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 rule
endif
It seems like quite开发者_如何学运维 a common thing to want to do. What's the best way of doing this?
Try this
In this example VER is checked for greater than 4
ifeq ($(shell test $(VER) -gt 4; echo $$?),0)
IFLAGS += -I$(TOPDIR)/include
LIBS += -L$(TOPDIR)/libs -lpcap
endif
Similar to this question, but basically you can use shell commands inside a Makefile. So the following is perfectly legal:
foo:
if [ ${value} -gt 2 ] ; then \
#Do stuff;\
fi
Edit for a small disclaimer: IIRC, bash
doesn't understand floating point arithmetic. It can interpret them as strings, but it might make things a little weird. Make sure you take this into consideration.
My preferred way to do this is:
value = 2.0
ifeq ($(shell expr $(value) \>= 1.5), 1)
# execute a rule
else ifeq ($(shell expr $(value) \<= 0.5), 1)
# execute a rule
endif
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.
精彩评论