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.
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 scriptSHELL
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.
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)
and pass it along as make -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). –
Stewardess override
statement? Because I just get: make: override: Command not found
–
Harkey ifdef($(DEBUG),1) debug_flags else normal_flags endif
which is located at the top and the variable is passed from command line like make all DEBUG=1
or make DEBUG=1 all
but it ignores that value and uses the value set by DEBUG ?= 0
at all times. Why is that? –
Insider make target FOO=bar
make FOO=bar target
? –
Ineffable Makefile
I have a line ifdef MY_FLAG
, if I execute a command make MY_FLAG=any_string_I_want
, the ifdef MY_FLAG
evaluates to true, however, if I execute a command make MY_FLAG
(i.e. without setting any value), make command returns an error. So my question: how can I make Makefile
support two options such that make MY_FLAG
would evaluate ifdef
to true and single make
without anything would evaluate ifdef
to false? –
Boles CFLAGS
and sometimes I want to pass -D DEBUG
in addition to those default arguments. I tried make CFLAGS="\$CFLAGS -D DEBUG" all
but that does not escape the dollar sign but yields FLAGS -D DEBUG
. –
Mantis 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
included
in the main makefile? –
Lovering Say you have a makefile like this:
action:
echo argument is $(argument)
You would then call it make action argument=something
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
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.
There's another option not cited here which is included in the GNU Make book by Stallman and McGrath (see http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html). It provides the example:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
It involves verifying if a given parameter appears in MAKEFLAGS
. For example .. suppose that you're studying about threads in c++11 and you've divided your study across multiple files (class01
, ... , classNM
) and you want to: compile then all and run individually or compile one at a time and run it if a flag is specified (-r
, for instance). So, you could come up with the following Makefile
:
CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread
SOURCES = class01 class02 class03
%: %.cxx
$(CXX) $(CXXFLAGS) -o [email protected] $^ $(LDLIBS)
ifneq (,$(findstring r, $(MAKEFLAGS)))
./[email protected]
endif
all: $(SOURCES)
.PHONY: clean
clean:
find . -name "*.out" -delete
Having that, you'd:
- build and run a file w/
make -r class02
; - build all w/
make
ormake all
; - build and run all w/
make -r
(suppose that all of them contain some certain kind of assert stuff and you just want to test them all)
If you make a file called Makefile and add a variable like this $(unittest) then you will be able to use this variable inside the Makefile even with wildcards
example :
make unittest=*
I use BOOST_TEST and by giving a wildcard to parameter --run_test=$(unittest) then I will be able to use regular expression to filter out the test I want my Makefile to run
export ROOT_DIR=<path/value>
Then use the variable, $(ROOT_DIR)
in the Makefile.
© 2022 - 2024 — McMap. All rights reserved.
make A='"as df"'
– Philender