Makefile ifeq logisch oder


91

Wie führen Sie ein logisches ODER mit dem ifeqOperator make durch ?

zB habe ich (vereinfacht):

ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

möchte aber diese Zeilen konsolidieren.

(ja, ja, Autotools, konfigurieren usw. usw .; zu hartnäckig für die aktuelle Situation, möchte hier alles im Makefile behalten)

[logisches Gegenteil dieser Frage: Verwendung der Mehrfachbedingung in der 'ifeq'-Anweisung ]



1
Denken Sie nicht, dass es ein Betrug ist, die verknüpfte Frage bezieht sich auf Verkettungsoperatoren ifdef, diese Frage bezieht sich auf Verkettungsoperatoren ifeq, ähnlich, aber die Antworten sind definitiv unterschiedlich.
Pat

Antworten:


102

Wie im Mailinglisten-Archiv zu finden,

man kann die Filterfunktion verwenden.

Beispielsweise

 ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))

Filter X, AB gibt diejenigen von A, B zurück, die gleich X sind.

Eine Variation davon ist

 ifneq (,$(filter $(GCC_MINOR),4 5))

Dabei wird stattdessen ein negativer Vergleich mit einer leeren Zeichenfolge verwendet (der Filter gibt eine leere Zeichenfolge zurück, wenn GCC_MINOR nicht mit den Argumenten übereinstimmt.)

Der Nachteil dieser Methoden ist, dass die Argumente einzelne Wörter sein müssen.


7
Ein später Hinweis: In den beiden oben genannten Varianten wird die erste in true aufgelöst, wenn $ (GCC_MINOR) leer ist, während die zweite nicht (daher ist die zweite generisch die bessere Lösung).
John

1
Eigentlich sollte es sein ifneq (,$(filter 4 5,$(GCC_MINOR))):)
Tuxdude

2
Vielleicht ist es der Einfachheit halber besser, so zu lassen, wie es ist?
Jason

Noch ein Hinweis: Dies funktioniert nicht als allgemeine ODER-Anweisung. Wir haben etwas, wo wir überprüfen wollen if(flagA == TRUE || flagB == true), aber wenn Sie dies tun $(filter true, $(flagA) $(flagB)und beide wahr sind, erhalten Sieifeq(true, true true)
Charlie Su

27

Sie können eine andere Variable einführen. Es konsolidiert nicht beide Prüfungen, aber es vermeidet zumindest, dass der Körper zweimal eingesetzt werden muss:

do_it = 
ifeq ($(GCC_MINOR), 4)
    do_it = yes
endif
ifeq ($(GCC_MINOR), 5)
    do_it = yes
endif
ifdef do_it
    CFLAGS += -fno-strict-overflow
endif

7
Die Wartbarkeit im Maßstab scheint mir nicht sehr gut zu sein: / Wenn wir wieder anfangen, über den Maßstab zu sprechen, sprechen wir wohl über Autotools
Pat

2
@Pat: Ich bevorzuge diesen Ansatz, bei dem ich die Zuweisung an einer Stelle im Makefile trennen und möglicherweise mit ifeq / else ifeq / else mit mehr Werten vergleichen kann, anstatt die Filterfunktion zu verwenden, die das Lesen von Zeilen nur schrecklich lang machen könnte .
Jcarballo

15

Ich glaube nicht, dass es einen prägnanten, vernünftigen Weg gibt, dies zu tun, aber es gibt ausführliche, vernünftige Wege (wie Foo Bahs) und prägnante, pathologische Wege wie

ifneq (,$(findstring $(GCC_MINOR),4-5))
    CFLAGS += -fno-strict-overflow
endif

(der den Befehl ausführt, vorausgesetzt, die Zeichenfolge $ (GCC_MINOR) erscheint in der Zeichenfolge 4-5).


4
Zum Guten oder Schlechten (wahrscheinlich Schlechteren), genau die Art von schmutzigem Hack, nach der ich gesucht habe; danke
Pat

1
Ich denke nicht, dass dies überhaupt pathologisch ist, außer der Tatsache, dass alles in einem Makefile pathologisch ist. Es ist wirklich sehr elegant. Ich habe vier oder fünf verschiedene Wege gelesen, um dies zu erreichen, und Ihre ist bei weitem am einfachsten zu verstehen.
Michael Geary

8

Hier flexiblere Variante: Es verwendet eine externe Shell, ermöglicht jedoch die Überprüfung auf beliebige Bedingungen:

ifeq ($(shell test ".$(GCC_MINOR)" = .4  -o  \
                   ".$(GCC_MINOR)" = .5  -o  \
                   ".$(TODAY)"     = .Friday  &&  printf "true"), true)
    CFLAGS += -fno-strict-overflow
endif

1
ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

Eine andere Möglichkeit, die Sie in diesem Fall in Betracht ziehen können, ist:

GCC42_OR_LATER = $(shell $(CXX) -v 2>&1 | $(EGREP) -c "^gcc version (4.[2-9]|[5-9])")

# -Wstrict-overflow: http://www.airs.com/blog/archives/120
ifeq ($(GCC42_OR_LATER),1)
  CFLAGS += -Wstrict-overflow
endif

Ich verwende dasselbe in meinem Code, weil ich kein separates configoder pflegen möchte Configure.

Sie müssen jedoch ein tragbares, nicht anämisches Gerät makewie GNU make ( gmake) und nicht das von Posix verwenden make.

Und es geht nicht um das Problem der logischen ANDund OR.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.