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.
Set default value for the undefined variables
For 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
Set default value for the default variables
The 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
Conclusion
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)
Optional
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.
CChas valueccby default (at least in GNU make I was testing). It is described with the default value in the documentation: Variables Used by Implicit Rules. The implicit rules which useCCand other variables are there. For example if you have fileprog.cand just an empty (!)Makefileinvokingmake progwill executecc prog.c -o prog. - paboukCFLAGS-- flags for the C compiler, by default empty". Well, for me is set by default to-g -O2- Kyrol