Performing greater-than less-than calculations in a Makefile

前端 未结 4 442
花落未央
花落未央 2021-01-11 09:40

I\'m trying to do this in a Makefile:

value = 2.0

if ${greaterthan ${value}, 1.50}
-> execute a rule
elseif ${lessthan ${value}, 0.50}
-> execute a ru         


        
4条回答
  •  孤独总比滥情好
    2021-01-11 09:57

    Using shell commands, as mentioned in the other answers, should suffice for most use cases:

    if [ 1 -gt 0 ]; then \
        #do something \
    fi
    

    However, if you, like me, want to use greater-than comparison in order to then set a make variable via make's $(eval) command, then you will find that attempting to do so using the other answer's model:

    if [ 1 -gt 0 ]; then \
        $(eval FOO := value) \
    fi
    

    raises an error:

    if [ 1 -gt 0 ]; then  fi;
    /bin/bash: -c: line 0: syntax error near unexpected token `fi'
    /bin/bash: -c: line 0: `if [ 1 -gt 0 ]; then  fi;'
    make: *** [clean] Error 2```
    

    The reason is that make's $(eval) expression returns the empty string. The resulting bash code is then malformed.**

    I came up with the following solution (after trying many different approaches!).

    $(if $(shell [ $(FOO) -ge 1 ] && echo "OK"), \
        $(eval BAR := true), \
        $(eval BAR := false))
    

    It is necessary to print out a string after performing the arithmetic comparison (the echo "OK" part) because make's $(if) operator its based on empty-string logic:

    $(if condition,then-part[,else-part])

    The if function provides support for conditional expansion in a functional context (as opposed to the GNU make makefile conditionals such as ifeq (see Syntax of Conditionals).

    The first argument, condition, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.

    Source: GNU Make Manual

    Hope this helps!

    ** Note: Initially, I thought that that issue could be easily fixed by adding a bash command that doesn't do anything to the expression, such as true:

    if [ $(VALUE) -ge 1 ]; then \
        true; $(eval BAR := GreaterOrEqualThan1) \
    else \
        true; $(eval BAR := LowerThan1) \
    fi
    

    That turned out to be a terrible idea. I still haven't figured out why, but the else branch is always executed, independently of the result of the comparison.

    I think I should open a question for this case.

提交回复
热议问题