(GNU) make uses several variables like:
CC
-- C compiler, by default cc
CFLAGS
-- flags for the C compiler, by default emptyI would like to specify my own default values of some of them in my Makefile
. In the example below I used the conditional assignment operator ?=
to be able to override my defaults when running make
:
CFLAGS ?= CFLAGS_my_default CC ?= CC_my_default print: echo CC=$(CC) CFLAGS=$(CFLAGS)
Unfortunately this does not change the value of the CC
variable as the original default value stays there. CFLAGS
are set by my assignment as the variable was originally empty:
$ make print echo CC=cc CFLAGS=CFLAGS_my_default CC=cc CFLAGS=CFLAGS_my_default
Overriding from environment variables works as expected:
$ CC=CC_from_env CFLAGS=CFLAGS_from_env make print echo CC=CC_from_env CFLAGS=CFLAGS_from_env CC=CC_from_env CFLAGS=CFLAGS_from_env
How can I change the default values of variables and still be able to override them when invoking make
?
Here's a quick and dirty intro : Files. All you need is a file called "makefile" or "Makefile". Comments Pound signs ("#") are comments to end of line. Variables CC = gcc.
The OR Assignment (||=) Operator The logical OR assignment ( ||= ) operator assigns the new values only if the left operand is falsy. Below is an example of using ||= on a variable holding undefined . Next is an example of assigning a new value on a variable containing an empty string.
$$ means be interpreted as a $ by the shell. the $(UNZIP_PATH) gets expanded by make before being interpreted by the shell.
It is possible to use non-conditional assignment:
CFLAGS ?= CFLAGS_my_default CC = CC_my_default print: echo CC=$(CC) CFLAGS=$(CFLAGS)
but unconditionally set variables cannot be overridden from environment variables:
$ CC=CC_from_env CFLAGS=CFLAGS_from_env make print echo CC=CC_my_default CFLAGS=CFLAGS_from_env CC=CC_my_default CFLAGS=CFLAGS_from_env
Wait, there is another way of setting the variable when invoking make
! - from command-line arguments:
$ make print CC=CC_from_cmdline CFLAGS=CFLAGS_from_cmdline echo CC=CC_from_cmdline CFLAGS=CFLAGS_from_cmdline CC=CC_from_cmdline CFLAGS=CFLAGS_from_cmdline
This way the non-conditionally set variables get overridden too. This method even works with recursive use of make
where the variables specified on command-line are automatically passed to the new make
process.
Another method is to enable overriding of unconditionally set variables by environment variables using command switch -e
:
$ CC=CC_from_env CFLAGS=CFLAGS_from_env make -e print echo CC=CC_from_env CFLAGS=CFLAGS_from_env CC=CC_from_env CFLAGS=CFLAGS_from_env
I have used this Makefile
to run some tests with GNU Make and check the origin and default value of some variables:
define whatisit $(info $(1) origin is ($(origin $(1))) and value is ($($(1)))) endef $(call whatisit,CC) $(call whatisit,CFLAGS)
Here are the results:
$ make CC origin is (default) and value is (cc) CFLAGS origin is (undefined) and value is () $ # Environment $ CC=clang CFLAGS=-Wall make CC origin is (environment) and value is (clang) CFLAGS origin is (environment) and value is (-Wall) $ # Command line $ make CC=clang CFLAGS=-Wall CC origin is (command line) and value is (clang) CFLAGS origin is (command line) and value is (-Wall)
As you can see there is two types of variables. These types are defined in the manual.
The first set of variables (AR
, AS
, CC
, ...) have default
values. The second set of variables (ARFLAGS
, ASFLAGS
, CFLAGS
, ...) are default to an empty string (i.e. undefined
).
By default, they can be override by environment or command line.
undefined
variablesFor the undefined
variables (and also other user variables) you just have to use the ?=
operator to set a default value which can be override by environment or command line.
CFLAGS ?= -Wall -Wextra -Werror
default
variablesThe best way to change default value for the default
variables is to check for their origin and change the value only when it is needed.
ifeq ($(origin CC),default) CC = gcc endif
The Makefile
:
ifeq ($(origin CC),default) CC = gcc endif CFLAGS ?= -Wall -Wextra -Werror define whatisit $(info $(1) origin is ($(origin $(1))) and value is ($($(1)))) endef $(call whatisit,CC) $(call whatisit,CFLAGS)
The final result:
$ make CC origin is (file) and value is (gcc) CFLAGS origin is (file) and value is (-Wall -Wextra -Werror) $ # Environment $ CC=clang CFLAGS=-Wall make CC origin is (environment) and value is (clang) CFLAGS origin is (environment) and value is (-Wall) $ # Command line $ make CC=clang CFLAGS=-Wall CC origin is (command line) and value is (clang) CFLAGS origin is (command line) and value is (-Wall)
You can use the MAKEFLAGS
variable to disable the built-in implicit rules and the built-in variable settings. This way:
MAKEFLAGS += -rR
This will clean a lot of default settings (you can check it by using make -p
). But the default
variables (like CC
) will still have a default value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With