altendky
altendky

Reputation: 4344

Specify empty variable on make command line

I have some Makefiles that are flexible based on the existence of certain variables by using ifdef to check for them. It is a bit annoying that I have to actually set the variable equal to something on the command line. make all DEBUG does not trigger the ifdef but make all DEBUG=1 does. Perhaps I am just using the C pre-processor approach where it does not belong.

Q1) Is it possible to specify a variable on the command line to be empty? Without even more characters? Q2) What is the preferred approach for such boolean parameters to a make?

Upvotes: 1

Views: 4728

Answers (3)

Alex Cohn
Alex Cohn

Reputation: 57173

As @MadScientist explained few minutes ago,

make all DEBUG

adds a target DEBUG to your make. Luckily, there is a workaround:

ifneq (,$(filter DEBUG,$(MAKECMDGOALS)))
    DEBUG:=1 # or do whatever you want
    DEBUG: all; @echo -n
endif

It is essential to supply a dummy rule (e.g. echo nothing, as above) to the dummy target. And either put this statement at the bottom of your makefile, or specify the prerequisite target explicitly as in the example. Otherwise, make may wrongly choose DEBUG target instead of all.

Note that this is not a preferred approach; the convention is like using V=1 to turn echo on.

Another caveat is that make processes the command-line goals sequentially, e.g. make A B will first take care of A target, then of B target, whether these targets are independent, or depend one on the other. Therefore writing make DEBUG PERFECT and make PERFECT DEBUG could produce different results. But the order of parameters is irrelevant, therefore make PERFECT=1 DEBUG=1 and make DEBUG=1 PERFECT=1 are equivalent.

Upvotes: 1

pmod
pmod

Reputation: 10997

It is already clarified why you can't use just DEBUG. But I would like to add something.

You can use shell script before running make that setup all variables you need, so, for example in linux shell it will look like this:

$source debug_setup.sh
$make all
Make is starting...
Debug is enabled
...

where debug_setup.sh contains all environment variables you need to set up:

export DEBUG=1
export DEBUG_OPTION=some_option

This is nice since you can make comments there, you can comment out if you don't need something at the moment and would like to keep for the future, etc.

Then you can have several setup scripts that must/can be used as a part of standard routine. This all depends on how many variables you need to set up, how many sets of variables you would like to have, etc.

Note that it is a good idea to notify user somehow which set of variables is selected.

Upvotes: 0

MadScientist
MadScientist

Reputation: 100836

I assume you mean make all DEBUG= here, right? Without the = make will consider DEBUG to be a target to build, not a variable assignment.

The manual specifies that a variable that has a non-empty value causes ifdef to return true. A variable that does not exist or exists but contains the empty string, causes ifdef to return false. Note ifdef does not expand the variable, it just tests whether the variable has any value.

You can use the $(origin ...) function to test whether a variable is really not defined at all, or is defined but empty, like this:

ifeq ($(origin DEBUG),undefined)
  $(info Variable DEBUG is not defined)
else
  $(info Variable DEBUG is defined)
endif

Upvotes: 3

Related Questions