4

Following advice at Abort makefile if variable not set I am attempting to use ifndef but it's not working.

Makefile:

foo:
        ifndef BAR
        $(error "Must set BAR")
        endif

But make foo BAR=quux does not work:

Makfile:2: *** "Must set BAR". Stop.

What gives? Is it whitespace issue? Or am I misunderstanding completely?

(I'm using GNU Make)

I tried also:

foo:
ifndef BAR
$(error "Must set BAR")
endif
        echo $(BAR)

Which seems to sort of work but still causes the ifndef to be invoked if a target further down in the Makefile (which does not require the variable to be set) is invoked.

Community
  • 1
  • 1
nathanleclaire
  • 1,040
  • 8
  • 11

2 Answers2

9

Technically, yes, it's a whitespace problem, but more fundamentally it's a scope problem.

The ifndef... endif is a Make conditional. So Make will evaluate it before executing any rule. And since the ifndef is not part of a recipe, it should not be preceded by a TAB. This works:

ifndef BAR
$(error "Must set BAR") # this is a Make error
endif

foo:
ifndef BAR
    echo "Must set BAR" # this is a shell command
    exit 1              # this is another shell command
endif

But what you did was this:

foo:
    ifndef BAR
    $(error "Must set BAR")
    endif

You put a TAB in front of the three lines (ifndef..., $(error... and endif), so Make assumed that those were commands, to be passed to the shell if and when the foo recipe was executed. And when Make executed the rule, it expanded the Make-syntax statement $(error...) -- and terminated with an error -- before passing anything to the shell.

Beta
  • 96,650
  • 16
  • 149
  • 150
2

You can use "if" function this purpose. foo : $(if $(BAR),,$(error Must set BAR))

Elpis
  • 297
  • 2
  • 8