0
votes

I have the following Makefile

SHELL=/bin/bash
.SHELLFLAGS=-O extglob -o errexit -o pipefail -o nounset -c

.PHONY: testing

define getFileContents
$(shell cat ./test.txt)
endef

TEST_STATIC=dummy

deploy:
    $(eval TEST=$(getFileContents))
    @echo "$(TEST)"
ifeq ($(TEST),dummy)
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif
ifneq (,$(findstring dummy,$(TEST)))
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif

ifeq ($(TEST_STATIC),dummy)
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif
ifneq (,$(findstring dummy,$(TEST_STATIC)))
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif

No matter what value I put in ./test.txt, I always go into PASS in both the ifeq & the findstring conditions but the variable's values show up properly in the echo statements. So the value is not available during the evaluation of ifeq

However, the if-else behaves properly for the TEST_STATIC variable.

Any help would be appreciated. Thanks.

1
Try moving your eval line between endef and deploy: lines, and modify to TEST := $(getFileContents); then reverse all your echo lines for PASS and FAIL; also instead of testing did you mean .PHONY: deploy ? - Milag

1 Answers

1
votes

ifeq is parsed while the makefile is read in. Even if it looks like it's part of a recipe, it isn't. You can tell that it isn't, because it isn't indented with a TAB character. Anything not indented by TAB, is part of the makefile not part of the recipe, and is parsed when the makefile is read in, not when the rule is run.

So by the time your rule is running and it gets to your eval, all the ifeq statements have long been expanded and dealt with.

In general, it's virtually never a good idea to use eval inside a recipe. It will almost never do what you're hoping for.

If you need to test some value inside a recipe then you have to write shell code to do it, not makefile code, and indent the shell code with a TAB so it's passed to the shell.