Reputation: 1545
(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
?
Upvotes: 29
Views: 21770
Reputation: 4952
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.
Upvotes: 15
Reputation: 1545
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
Upvotes: 11