Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile: ifeq directive compares special variable to constant does not work

I have a little issue with my Makefile. I want make to change commands regarding the working directory. I added a conditional directive to the rule testing the current target's directory ($(*D)).

The thing is that make always goes to the second branch of my test, even when my file is in mySpecialDirectory and echo indeed prints "mySpecialDirectory".

.c.o .cpp.o .cc.o:
ifeq ($(*D),mySpecialDirectory)  
   @echo "I'm in mySpecialDirectory! \o/"
   $(CC) $(DEBUG_FLAGS) $(MYSPECIALFLAGS) -c $< -o $@
else  
   @echo "Failed! I'm in $(*D)"
   $(CC) $(DEBUG_FLAGS) $(NOTTHATSPECIALFLAGS) -c $< -o $@
endif
like image 213
Kyone Avatar asked Feb 27 '23 23:02

Kyone


1 Answers

This is the expected behavior.

Conditional Statements

All instances of conditional syntax are parsed immediately, in their entirety; this includes the ifdef, ifeq, ifndef, and ifneq forms. Of course this means that automatic variables cannot be used in conditional statements, as automatic variables are not set until the command script for that rule is invoked. If you need to use automatic variables in a conditional you must use shell conditional syntax, in your command script proper, for these tests, not make conditionals.

$(*D) is an automatic variable.

Instead, consider doing:

.c.o .cpp.o .cc.o:
   $(CC) $(DEBUG_FLAGS) $(if $(subst mySpecialDirectory,,$(*D)),$(NOTTHATSPECIALFLAGS),$(MYSPECIALFLAGS)) -c $< -o $@

The idea is to abuse $(subst) into some equality testing by replacing mySpecialDirectory with the empty string. Then, if $(*D) expansion equals to mySpecialDirectory, it is fully replaced by the empty string and the else-part of $(if) gets evaluated as per:

$(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.

Notice the flip in this hack between the then-part and the else-part.

Hope this helps!

like image 172
Gregory Pakosz Avatar answered May 02 '23 01:05

Gregory Pakosz