How do you perform a logical OR using make\'s ifeq
operator?
e.g., I have (simplified):
ifeq ($(GCC_MINOR), 4)
CFLAGS += -fno-strict
Here more flexible variant: it uses external shell, but allows to check for arbitrary conditions:
ifeq ($(shell test ".$(GCC_MINOR)" = .4 -o \
".$(GCC_MINOR)" = .5 -o \
".$(TODAY)" = .Friday && printf "true"), true)
CFLAGS += -fno-strict-overflow
endif
You can introduce another variable. It doesnt consolidate both checks, but it at least avoids having to put the body in twice:
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
I don't think there's a concise, sensible way to do that, but there are verbose, sensible ways (such as Foo Bah's) and concise, pathological ways, such as
ifneq (,$(findstring $(GCC_MINOR),4-5))
CFLAGS += -fno-strict-overflow
endif
(which will execute the command provided that the string $(GCC_MINOR) appears inside the string 4-5).
As found on the mailing list archive,
one can use the filter
function.
For example
ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))
filter X, A B
will return those of A,B that are equal to X.
Note, while this is not relevant in the above example, this is a XOR operation. I.e. if you instead have something like:
ifeq (4, $(filter 4, $(VAR1) $(VAR2)))
And then do e.g. make VAR1=4 VAR2=4
, the filter will return 4 4
, which is not equal to 4
.
A variation that performs an OR operation instead is:
ifneq (,$(filter $(GCC_MINOR),4 5))
where a negative comparison against an empty string is used instead (filter
will return en empty string if GCC_MINOR
doesn't match the arguments). Using the VAR1
/VAR2
example it would look like this:
ifneq (, $(filter 4, $(VAR1) $(VAR2)))
The downside to those methods is that you have to be sure that these arguments will always be single words. For example, if VAR1
is 4 foo
, the filter result is still 4
, and the ifneq
expression is still true. If VAR1
is 4 5
, the filter result is 4 5
and the ifneq
expression is true.
One easy alternative is to just put the same operation in both the ifeq
and else ifeq
branch, e.g. like this:
ifeq ($(GCC_MINOR),4)
@echo Supported version
else ifeq ($(GCC_MINOR),5)
@echo Supported version
else
@echo Unsupported version
endif
ifeq ($(GCC_MINOR), 4) CFLAGS += -fno-strict-overflow endif ifeq ($(GCC_MINOR), 5) CFLAGS += -fno-strict-overflow endif
Another you can consider using in this case is:
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
I actually use the same in my code because I don't want to maintain a separate config
or Configure
.
But you have to use a portable, non-anemic make
, like GNU make (gmake
), and not Posix's make
.
And it does not address the issue of logical AND
and OR
.