I've written a fairly simple test Makefile
where I define two targets, all & clean. I've got two different conditional statements. One checks for the existence of the $(MAKECMDGOALS)
special variable and the other detects whether any of the command line targets matched those listed in a variable (NODEPS
). The problem I'm having is that none of the branches within my conditionals get executed. Ultimately I want to use a conditional to decide whether the target I'm supplying should include some autogenerated dependency files but at the moment I'm struggling to get either expression to even evaluate. I'm running GNU make version 3.81 and I've tried it under Ubuntu and Mac OS X to no avail.
NODEPS := clean
INCLUDE = $(filter $(NODEPS),$(MAKECMDGOALS))
.PHONY : all clean
ifndef $(MAKECMDGOALS)
@echo "$$(MAKECMDGOALS) is not defined"
else
@echo "$(MAKECMDGOALS) is defined"
endif
ifneq (0, $(words $(INCLUDE)))
@echo "INCLUDE = $(INCLUDE) != 0"
else
@echo "INCLUDE = $(INCLUDE) == 0"
endif
all :
@echo "all : $(MAKECMDGOALS)"
clean :
@echo "clean : $(MAKECMDGOALS)"
The ifeq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared.
The lines of the makefile following the ifneq are obeyed if the two arguments do not match; otherwise they are ignored. The ifdef directive begins the conditional, and specifies the condition. It contains single argument. If the given argument is true then condition becomes true.
If the condition is true, make reads the lines of the text-if-true as part of the makefile; if the condition is false, make ignores those lines completely. It follows that syntactic units of the makefile, such as rules, may safely be split across the beginning or the end of the conditional.
= defines a recursively-expanded variable. := defines a simply-expanded variable.
A makefile is not a shell script. You can not "randomly" place executable statements anywhere you like and expect them to be executed.
There are various ways of communicating with the outside world from within a makefile: $(info ...)
, $(warning ...)
, $(error ...)
and $(shell @echo ...)
(some or all of these may be GNU make extensions).
Ps: you misspelled PHONY
.
I eventually managed to work out what was wrong. @eriktous was right, pointing out that I should be using $(info)
rather than @echo
. More subtly though, part of the problem was that I'd indented the @echo
s with a tab. It seems that tabs are mandatory for rules but not allowed in conditionals. The other mistake was I'd expanded the $(MAKECMDGOALS)
variable in the test condition when it should have been written as just ifndef MAKECMDGOALS
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With