Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change default values of variables like CC in Makefile

Tags:

(GNU) make uses several variables like:

  • CC -- C compiler, by default cc
  • CFLAGS -- flags for the C compiler, by default empty

I 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?

like image 420
pabouk - Ukraine stay strong Avatar asked Aug 02 '13 01:08

pabouk - Ukraine stay strong


People also ask

What is CC in Makefile?

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.

How do you assign default values to variables?

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.

What is $$ in Makefile?

$$ means be interpreted as a $ by the shell. the $(UNZIP_PATH) gets expanded by make before being interpreted by the shell.


2 Answers

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 
like image 193
pabouk - Ukraine stay strong Avatar answered Sep 22 '22 21:09

pabouk - Ukraine stay strong


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.

like image 21
jmlemetayer Avatar answered Sep 21 '22 21:09

jmlemetayer