Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile ifeq: when are they evaluated?

The following is a very simple makefile that does not seem to work properly.

TEST=ON

buildbegin:
ifeq ($(TEST),ON)        
    @echo TEST PASSED
else
    @echo TEST FAILED
endif

No matter what I set the TEST variable to, my ifeq statement passes. I always see TEST PASSED. Anyone see what I am doing wrong here?

EDIT:

ok. my example was not exactly accurate. What I actually have is this:

SHELL = /bin/sh

DEFAULT_TARGS:= all  all_debug  
DEBUG_TARGS:= all_debug
ALL_TARGS:= $(DEFAULT_TARGS) $(DEBUG_TARGS)

.PHONY: $(ALL_TARGS)
.PHONY: buildbegin

$(ALL_TARGS): buildbegin

TEST=ON

$(DEBUG_TARGS): TEST=OFF

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif

Running either make all or make all_debug will result in "PASSED" being printed. If I echo $(TEST) before the condition, it looks as if my rules are changing the variable, but the ifeq only ever sees whatever the default value is.

like image 731
kalden Avatar asked Aug 16 '12 19:08

kalden


People also ask

What is IFEQ in makefile?

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.

What is := in makefile?

Expanded assignment = defines a recursively-expanded variable. := defines a simply-expanded variable.


2 Answers

make evaluates conditionals when it reads a makefile (as you know it uses 2 passes), see: Conditional Parts of Makefiles. You can simply check this by using warning (which is good thing to debug makefiles):

buildbegin:
    @echo $(TEST)
$(warning now we reached ifeq TEST=$(TEST))
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif

You should use shell commands instead and include them in rule:

buildbegin:
      @if [ "$(TEST)" = "ON" ]; then echo "PASSED"; else echo "FAILED"; fi
like image 173
pmod Avatar answered Jan 18 '23 15:01

pmod


Here's a cleaner (I think, anyway) way to do what you want:

all:
    $(MAKE) TEST=ON buildbegin

all_debug:
    $(MAKE) TEST=OFF buildbegin

buildbegin:
    @echo $(TEST)
ifeq ($(TEST),ON)
    @echo PASSED
else
    @echo FAILED
endif
like image 33
twalberg Avatar answered Jan 18 '23 15:01

twalberg