Makefile test if variable is not empty
Makefile test if variable is not empty
In a makefile I'm trying to
I've created this simplified makefile to demonstrate my problem. Neither make a
or make b
executes the body of the if, I don't understand why not.
make a
make b
.PHONY: a b
a:
$(eval MY_VAR = $(shell echo whatever))
@echo MY_VAR is $(MY_VAR)
$(info $(MY_VAR))
ifneq ($(strip $(MY_VAR)),)
@echo "should be executed"
endif
@echo done
b:
$(eval MY_VAR = $(shell echo ''))
@echo MY_VAR is $(MY_VAR)
$(info $(MY_VAR))
ifneq ($(strip $(MY_VAR)),)
@echo "should not be executed"
endif
@echo done
I'm using
$ make --version
GNU Make 3.81
MY_VAR
make
<tab>
$(eval ...)
MY_VAR:=$(shell echo whatever)
<tab>
$(info ...)
make
If you want to do something if not empty, you need to use
$(if $(strip $(MY_VAR)),do if,do else)
in the recipe line– Zelnes
2 hours ago
$(if $(strip $(MY_VAR)),do if,do else)
@Zelnes I only want to set
MY_VAR
when target a
or b
is run (the real commands are expensive and there are other targets that don't need it), if I remove the tabs I get syntax errors.– cerberos
2 hours ago
MY_VAR
a
b
Ahh, a different form of if, works! Please make an answer so I can accept.
– cerberos
1 hour ago
2 Answers
2
If you want to dynamically test the content of MY_VAR
, you may have to :
MY_VAR
a:
$(eval MY_VAR = $(shell echo ''))
$(if $(strip $(MY_VAR)),echo ok,echo no)
if
evaluation will become echo ok
if MY_VAR
is not empty, otherwise it will become echo no
if
echo ok
MY_VAR
echo no
Specifically, the
ifneq
conditionals happen at a different point to the inline $(if )
conditionals: in parsing the Makefile, not when executing the rule.– Toby Speight
49 mins ago
ifneq
$(if )
Note that, due to the time of evaluation, make conditionals (ifeq
, ifneq
...) cannot be used in recipes the way you tried. Use shell conditionals, instead, as shown below.
ifeq
ifneq
As your MY_VAR
variable is used only in recipes, is target-dependent and you want it to be computed only when needed, why don't you use shell variables, instead of make variables?
MY_VAR
$ cat Makefile
.PHONY: a b
a:
MY_VAR=$$(echo whatever) &&
echo $@: MY_VAR is $$MY_VAR &&
if [ -n "$$MY_VAR" ]; then
echo "$@: should be executed";
fi &&
echo $@: done
b:
MY_VAR=$$(echo '') &&
echo $@: MY_VAR is $$MY_VAR &&
if [ -n "$$MY_VAR" ]; then
echo "$@: should no be executed";
fi &&
echo $@: done
$ make a
a: MY_VAR is whatever
a: should be executed
a: done
$ make b
b: MY_VAR is
b: done
In case you absolutely need MY_VAR
to be a target-specific make variable, MadScientist has a wonderful trick that you should probably look at. Applied to your case, it should look like:
MY_VAR
$ make --version
GNU Make 4.1
...
$ cat Makefile
a: MY_VAR = $(eval a: MY_VAR := $$(shell echo whatever))$(MY_VAR)
b: MY_VAR = $(eval b: MY_VAR := $$(shell echo ''))$(MY_VAR)
a:
@echo $@: MY_VAR is $(MY_VAR) &&
if [ -n "$(MY_VAR)" ]; then
echo "$@: should be executed";
fi &&
echo $@: done
b:
@echo $@: MY_VAR is $(MY_VAR) &&
if [ -n "$(MY_VAR)" ]; then
echo "$@: should no be executed";
fi &&
echo $@: done
$ make a
a: MY_VAR is whatever
a: should be executed
a: done
$ make b
b: MY_VAR is
b: done
$ make b a
b: MY_VAR is
b: done
a: MY_VAR is whatever
a: should be executed
a: done
It may look extremely strange but it guarantees that MY_VAR
is computed if and only if targets a
or b
are invoked, and only at most once for each. Have a look at MadScientist's post for detailed explanations. Go, it's brilliant.
MY_VAR
a
b
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
There are several problems, and misunderstandings. Your
MY_VAR
is amake
variable, set it without a<tab>
to its value, and no need to$(eval ...)
.MY_VAR:=$(shell echo whatever)
is enough. No<tab>
before$(info ...)
neither, this ismake
– Zelnes
2 hours ago