Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile ifeq logical or

Tags:

makefile

How do you perform a logical OR using make's ifeq operator?

e.g., I have (simplified):

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

but would like to consolidate these lines.

(yes, yes, autotools, configure, etc etc; too heavy-handed for the current situation, would like to keep everything within the Makefile here)

[logical opposite of this question: How to Use of Multiple condition in 'ifeq' statement ]

like image 929
Pat Avatar asked Oct 05 '11 03:10

Pat


3 Answers

As found on the mailing list archive,

  • http://osdir.com/ml/gnu.make.windows/2004-03/msg00063.html
  • http://osdir.com/ml/gnu.make.general/2005-10/msg00064.html

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
like image 163
3 revs, 2 users 67% Avatar answered Nov 16 '22 13:11

3 revs, 2 users 67%


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
like image 26
Foo Bah Avatar answered Nov 16 '22 13:11

Foo Bah


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).

like image 19
ruakh Avatar answered Nov 16 '22 13:11

ruakh