Passing additional variables from command line to make
Solution 1
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 theoverride
directive . However, it's not recommended, and it's much better and flexible to use?=
assignment (the conditional variable assignment operator, it only has an effect if the variable is not yet defined):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 theoverride
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.
Solution 2
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
Solution 3
Say you have a makefile like this:
action:
echo argument is $(argument)
You would then call it make action argument=something
Solution 4
It seems command args overwrite environment variable.
Makefile:
send:
echo $(MESSAGE1) $(MESSAGE2)
Example run:
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OK
echo YES OK
YES OK
Solution 5
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.
Pablo
Updated on July 15, 2022Comments
-
Pablo almost 2 years
Can I pass variables to a GNU Makefile as command line arguments? In other words, I want to pass some arguments which will eventually become variables in the Makefile.
-
Pablo about 14 yearsso the target and arguments can be interchanged in terms of position?
-
nc3b about 14 years@Michael: Yes (see the answer of Mark Byers)
-
Pablo about 14 yearsby sub-makes you mean to the makefiles
included
in the main makefile? -
Mark Byers about 14 years@Michael: It means calling make again from inside the makefile. I've updated my answer since you seem to be interested in this detail.
-
Keyur Padalia about 14 yearsThe other way is indeed better in nearly all cases. I'll leave this here for completeness.
-
Ciro Santilli OurBigBook.com over 11 yearsto pass from command line somthing with spaces do
make A='"as df"'
-
James Moore over 11 yearsSeems like you're asking for trouble if you care about environment variables. For one thing, it's a debugging nightmare if it works in place A and not in place B, just because they have different environments.
-
user7610 over 10 yearsIt is actually spelled --environment-overrides
-
R.D. over 10 yearsJust based on experience, exporting stuff like CFLAGS is a recipe for nightmare for large projects. Large projects often have 3rd party libraries that only compile with a given set of flags (that no one bothers fixing). If you export CFLAGS, your project's CFLAGS ends up overriding the 3rd party library's and triggers compile errors. An alternate way might be to define
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)
and pass it along asmake -C folder $(PROJECT_MAKE_FLAGS)
. If there's a way to tell the library's makefile to ignore the environment, that'd be ideal (opposite of -e). -
pattivacek almost 10 yearsFor passing variables to a submake, consider appending to MAKEFLAGS in the parent make. See here.
-
Jonathan Ben-Avraham almost 9 yearsWARNING: In the section "Exporting from the parent Make" above, "Don't do this!" is critically misleading. Passing variables on the command line overrides assignments in the sub-makefile but exported variables do not override assignments in the sub-makefile. These two methods for passing variables to a sub-makefile are not equivalent and should not be confused.
-
Tomáš Zato almost 9 yearsGuys did anyone have any success using make
override
statement? Because I just get:make: override: Command not found
-
jtimz about 8 yearsI'd like to know why this is not working; I have a makefile that has
ifdef($(DEBUG),1) debug_flags else normal_flags endif
which is located at the top and the variable is passed from command line likemake all DEBUG=1
ormake DEBUG=1 all
but it ignores that value and uses the value set byDEBUG ?= 0
at all times. Why is that? -
wlnirvana almost 8 yearsJust to complement, this is the link to the documentation of the From command line approach.
-
basickarl over 6 yearsMultiple arguments?
-
ThomasMcLeod almost 6 years"Note that this won't propagate to sub-makes automatically." Untrue! "By default, only variables that came from the environment or the command line are passed to recursive invocations. You can use the export directive to pass other variables." gnu.org/software/make/manual/html_node/…
-
gfan over 5 yearsAny difference ?
make target FOO=bar
make FOO=bar target
? -
M_M over 4 yearsThis is the only answer which shows the assignment of variables before the make command on the same line - it's worth knowing this isn't a syntax error.
-
mercury0114 over 3 yearsIn
Makefile
I have a lineifdef MY_FLAG
, if I execute a commandmake MY_FLAG=any_string_I_want
, theifdef MY_FLAG
evaluates to true, however, if I execute a commandmake MY_FLAG
(i.e. without setting any value), make command returns an error. So my question: how can I makeMakefile
support two options such thatmake MY_FLAG
would evaluateifdef
to true and singlemake
without anything would evaluateifdef
to false? -
Jonny Brooks almost 3 yearsI love this answer. It's concise and very informative. Precisely what I was looking for. Thank you
-
Arun George almost 3 yearsPart of the anwer is wrong. The CFLAGS if its inherited from another make target via $(MAKE) target you don't need nothing. It's simply propogated from the parent.
-
MadScientist over 2 yearsIf you look at the page you referenced you'll see it says explicitly make automatically passes down variable values that were defined on the command line, by putting them in the MAKEFLAGS variable. See Options/Recursion. So contrary to this answer, make will propagate to sub-makes automatically.
-
SimonH over 2 yearsIs it possible to expand an existing environment variable? I use autotools which has some default values in
CFLAGS
and sometimes I want to pass-D DEBUG
in addition to those default arguments. I triedmake CFLAGS="\$CFLAGS -D DEBUG" all
but that does not escape the dollar sign but yieldsFLAGS -D DEBUG
. -
itirazimvar over 2 yearsmake target foo=bar also works!!
-
user615501 over 2 yearsThe nuance to understand is that with the assignment in front you're setting an environment variable for the make subprocess. With the assignment after the target you're passing an argument to make and it is parsing it and it will override what's set in your environment.