views:

236

answers:

4

How to pass variables to gnu makefile from command line arguments? In other words I want to pass some arguments which will eventually become variables in makefile.

+1  A: 

The simplest way is:

make foo=bar target

Then in your makefile you can refer to $(foo). Note that this won't propagate to sub-makes automatically.

If you are using sub-makes, see this article: Communicating Variables to a Sub-make

Mark Byers
@Mark Byers: by sub-makes you mean to the makefiles `included` in the main makefile?
Michael
@Michael: It means calling make again from inside the makefile. I've updated my answer since you seem to be interested in this detail.
Mark Byers
+1  A: 

Say you have a makefile like this:

action:
    echo argument is $(argument)

You would then call it make action argument=something

nc3b
so the target and arguments can be interchanged in terms of position?
Michael
@Michael: Yes (see the answer of Mark Byers)
nc3b
A: 

From the manual:

Variables in make can come from the environment in which make is run. Every environment variable that make sees when it starts up is transformed into a make variable with the same name and value. However, an explicit assignment in the makefile, or with a command argument, overrides the environment.

So you can do (from bash):

FOOBAR=1 make

resulting in a variable FOOBAR in your Makefile.

Thomas
I don't like environment way, but thanks
Michael
The other way is indeed better in nearly all cases. I'll leave this here for completeness.
Thomas
+1  A: 

You have several options to set up variables from outside your makefile:

  • From environment - each environment variable is transformed into a makefile variable with the same name and value.

    You may also want to set -e option (aka --environments-override) on, and your environment variables will override assignments made into makefile (unless these assignments themselves use the override directive . However, it's not recommended, and it's much better and flexible to use ?= assignment:

    FOO?=default_value_if_not_set_in_environment
    

    Note that certain variables are not inherited from environment:

    • MAKE is gotten from name of the script
    • SHELL is either set within a makefile, or defaults to /bin/sh (rationale: commands are specified within the makefile, and they're shell-specific).
  • From command line - make can take variable assignments as part of his command line, mingled with targets:

    make target FOO=bar
    

    But then all assignments to FOO variable within the makefile will be ignored unless you use the override directive in assignment. (The effect is the same as with -e option for environment variables).

  • Exporting from the parent Make - if you call Make from a Makefile, you usually shouldn't explicitly write variable assignments like this:

    # Don't do this!
    target:
            $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
    

    Instead, better solution might be to export these variables. Exporting a variable makes it into the environment of every shell invocation, and Make calls from these commands pick these environment variable as specified above.

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
            $(MAKE) -C target
    

    You can also export all variables by using export without arguments.

Pavel Shved