makefilegnu-make

ifdef with target-specific variables


This Makefile specifies a target-specific variable and a global one

 VAR=value
target: VAR2=value2

ifdef VAR
    VAR3+=$(VAR)
endif
ifdef VAR2
    VAR3+=$(VAR2)
endif

target:
    @echo $(VAR) $(VAR2) $(VAR3)

The output of make target is value value2 value (using GNU make 4.1.1).

However, since, for that target, both VAR and VAR2 have a value, I would expect both the ifdef conditions to be true, so the output should be value value2 value value2. Why that? And what needs to be done to have a target-specific variable have an effect in ifdef?


Solution

  • Because ifdef is evaluated while make is reading the makefile (parse time), and target-specific variables like target: VAR2=value2 only take effect when make is running the recipe for that target (execution time).

    So at parse time:

    Later, when target runs, VAR2 exists for that target, but it’s too late: the ifdef already happened.

    That’s why you get:

    value value2 value
    

    In your case to have a working code the best way is to compute VAR3 as a target-specific variable too

    just likee:

    VAR = value
    target: VAR2 = value2
    
    target: VAR3 := $(if $(VAR),$(VAR))$(if $(VAR2), $(VAR2))
    
    target:
        @echo $(VAR) $(VAR2) $(VAR3)