GNU Make Gotcha: ifndef and ?=

[article]
Summary:

This month's article is about a little GNU Make Gotcha: an easy way to get tripped up by two pieces of GNU Make syntax that do similar things, yet one has a deceptive name. ifndef isn't really ifndef at all, it would better if it were called ifempty, while ?= does make its decision based on whether the variable is defined or not.

Compare these two ways of conditionally setting the variable FOO in a Makefile:

ifndef FOO
FOO = New Value
endif

and

FOO ?= New Value

They look like they should do the same thing, and they do... almost.
What ?= doesThe ?= operator in GNU Make sets the variable mentioned on its left-hand side to the value on the right-hand side if the left-hand side is not defined. So, for example the following Makefile sets FOO to New Value:

FOO ?= New Value

But this one does not:

FOO = Old Value
FOO ?= New Value

And neither does this one (even though FOO was initially empty):

FOO =
FOO ?= New Value

In fact ?= is exactly the same as the following which uses the GNU Make $(origin) function to determine if a variable is undefined. $(origin FOO) will return a string that shows whether and how FOO is defined (see the GNU Make manual for more information). If FOO is undefined then $(origin FOO) is undefined.

ifeq ($(origin FOO),undefined)
FOO = New Value
endif

Note that variables defined with ?= are expanded just like variables defined with =. They are expanded when used and not when defined just like a normal GNU Make variable.
What ifndef doesifndef, on the other hand, tests whether a variable is empty or not. ifndef does not check to see if the variable is defined. ifndef actually means "if the variable is undefined or is defined but is empty". Thus

ifndef FOO
FOO = New Value
endif

will set FOO to the New Value if FOO is undefined or FOO is empty. So ifndef can be rewritten

ifeq ($(FOO),)
FOO = New Value
endif

Since an undefined variable is always treated as having an empty value when read.

 

About the author

CMCrossroads is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.