Makefile ifeq logico o


92

Come si esegue un OR logico utilizzando l' ifeqoperatore make ?

ad esempio, ho (semplificato):

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

ma vorrei consolidare queste linee.

(sì, sì, autotools, configure, ecc ecc; troppo pesante per la situazione attuale, vorrei mantenere tutto all'interno del Makefile qui)

[l'opposto logico di questa domanda: come utilizzare la condizione multipla nell'istruzione "ifeq" ]



1
Non pensare che sia un imbroglio, la domanda collegata si riferisce al concatenamento di ifdefoperatori, questa domanda è relativa al concatenamento di ifeqoperatori, simile, ma le risposte sono decisamente diverse.
Pat

Risposte:


103

Come si trova nell'archivio della mailing list,

si può usare la funzione di filtro .

Per esempio

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

il filtro X, AB restituirà quelli di A, B che sono uguali a X.

Una variazione di questo è

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

dove viene invece utilizzato un confronto negativo con una stringa vuota (il filtro restituirà una stringa vuota se GCC_MINOR non corrisponde agli argomenti)

Lo svantaggio di questi metodi è che gli argomenti devono essere parole singole.


7
Una nota tarda: nelle due varianti che hai sopra, la prima si risolverà a vero se $ (GCC_MINOR) è vuoto, mentre la seconda no (quindi la seconda è la soluzione migliore in termini generici).
Giovanni

1
In realtà, dovrebbe essere ifneq (,$(filter 4 5,$(GCC_MINOR))):)
Tuxdude

2
Forse è meglio lasciare così com'è per semplicità?
Jason

Un'altra nota: questa non funziona come un'istruzione OR generale . Abbiamo qualcosa su cui vogliamo controllare if(flagA == TRUE || flagB == true), ma se lo fai $(filter true, $(flagA) $(flagB)ed entrambi sono veri, ottieniifeq(true, true true)
Charlie Su

27

Puoi introdurre un'altra variabile. Non consolida entrambi i controlli, ma evita almeno di dover inserire il corpo due volte:

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
La manutenibilità di questo su larga scala non mi sembra molto buona: / Poi di nuovo, una volta che iniziamo a parlare di scala, immagino che stiamo parlando di autotools
Pat

2
@Pat: Preferisco piuttosto questo approccio in cui posso separare l'assegnazione in un punto nel Makefile, possibilmente confrontandola con più valori usando ifeq / else ifeq / else, piuttosto che usare la funzione di filtro che potrebbe rendere terribilmente lunghe righe difficili da leggere .
jcarballo

15

Non penso che ci sia un modo conciso e sensato per farlo, ma ci sono modi verbosi e sensati (come quello di Foo Bah) e modi concisi e patologici, come

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

(che eseguirà il comando a condizione che la stringa $ (GCC_MINOR) compaia all'interno della stringa 4-5).


4
Nel bene o nel male (probabilmente peggio), proprio il tipo di sporco hack che stavo cercando; grazie
Pat

1
Non penso che questo sia affatto patologico, a parte il fatto che tutto in un Makefile è patologico. È davvero molto elegante. Ho letto quattro o cinque modi diversi per farlo, e il tuo è di gran lunga il più facile da capire.
Michael Geary

8

Qui variante più flessibile: utilizza shell esterna, ma consente di verificare condizioni arbitrarie:

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

Un altro che puoi considerare di utilizzare in questo caso è:

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

In realtà uso lo stesso nel mio codice perché non voglio mantenere un file configo Configure.

Ma devi usare un portatile, non anemico make, come GNU make ( gmake), e non quello di Posix make.

E non affronta la questione della logica ANDe OR.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.