Makefile ifeq logical or

前端 未结 5 786
有刺的猬
有刺的猬 2020-12-02 06:51

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

e.g., I have (simplified):

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


        
相关标签:
5条回答
  • 2020-12-02 07:07

    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
    
    0 讨论(0)
  • 2020-12-02 07:14

    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
    
    0 讨论(0)
  • 2020-12-02 07:14

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

    0 讨论(0)
  • 2020-12-02 07:28

    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
    
    0 讨论(0)
  • 2020-12-02 07:29
    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.

    0 讨论(0)
提交回复
热议问题