Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I undefine variable in a Makefile via command line

I want to undefine a variable from a Makefile via passing a command to make. Is this possible? Man make didn't help that much.

What I want to do the following:

I want to compile a port with FreeBSD. This port is marked as broken. Though I don't have the permissions to change the Makefile I am looking for possibility to undefine the broken? variable.

Edit: In the Makefile is:

BROKEN=                 does not link

And I want to unset/undefine broken. Because the Makefile is not executed further. This is not related to compiler flags so far.

like image 331
mistapink Avatar asked Aug 31 '12 13:08

mistapink


3 Answers

I don't think you can actually undefine a variable.

However, if 'empty' is good enough for you:

make -e variable=''
like image 124
sehe Avatar answered Oct 03 '22 13:10

sehe


You can do so. Here's how, assuming that undef is the name of the target which you want to use to undefine the variable.

FOO:=foo

ifeq (undef,$(filter undef,$(MAKECMDGOALS)))
override undefine FOO
endif

.PHONY: all
all:
        echo $(FOO) '($(origin FOO))'

.PHONY: undef
undef: $(if $(filter-out undef,$(MAKECMDGOALS)),,$(.DEFAULT_GOAL)))

Explanation of make elements used:

  • MAKECMDGOALS is the predefined read-only variable containing the goals with which make was called. We use this to check whether make was called with undef.
  • .DEFAULT_GOAL is the predefined variable containing the default goal. If it is not set explicitly, it is set to the first goal, which in this case is all.
  • ifeq ... endif allows conditional parts in a Makefile.
  • The $(filter pattern,list) function returns all elements from list which are matched by pattern. So, if make was called with undef as one of its goals, $(filter undef,$(MAKECMDGOALS)) will be undef, otherwise it will be the empty String.
  • The $(filter-out pattern,list) function is the opposite of $(filter key,list). It returns all elements from list which are not matched by pattern. So, if make was called with undef only, $(filter-out undef,$(MAKECMDGOALS)) will be the empty String, otherwise it will be the list of all goals given on the command line, excluding undef.
  • undefine undefines a variable.
  • override changes a variable even if it was passed on the command line. You need to decide depending on your use case whether or not using override makes sense.
  • The $(if cond,then[,else]) function returns then if cond is true, otherwise else (or the empty String if there was no else). A non-empty String is true, an empty String is false.

So, the Makefile undefines FOO in case undef was given on the command line.

The "magic" dependency of undef makes sure that if undef was the only goal given on the command line, it will depend on and therefore execute the default goal, which in this example would be all. This is to make sure that make undef behaves like make except that it undefines the variable.

WARNING: The behavior of such Makefiles can be confusing. Imagine a Makefile that uses this mechanism to exclude CPPFLAGS+=-DNDEBUG in case debug was given. It is unexpected that make debug all and make all create a different output for make all. The expectation is that make debug all creates additional output compared to make all. The primary expectation is that make all always behaves the same, no matter what other goals might additionally be present on the command line. It is better to implement such mechanisms using a configure-style mechanism.

(Source: From my unpublished book on GNU make.)

like image 38
Christian Hujer Avatar answered Oct 03 '22 12:10

Christian Hujer


http://www.gnu.org/software/make/manual/make.html#Undefine-Directive

Supposedly you can

override undefine VARIABLE
like image 42
emrainey Avatar answered Oct 03 '22 11:10

emrainey