Append to GNU make variables via command line

Check out the override directive. You will probably need to modify the makefile once, but it should do what you want.

Example makefile:

override CFLAGS += -Wall

app: main.c
    gcc $(CFLAGS) -o app main.c 

Example command lines:

$ make
gcc -Wall -o app main.c 
$ make CFLAGS=-g
gcc -g -Wall -o app main.c 

For the record, @Carl Norum's answer prepends the variable, from the command line perspective.

I needed a way to actually append and came up with:

override CFLAGS := -Wall $(CFLAGS)

There are two ways to pass variables to make:

  • Using command line arguments:

    make VAR=value
    
  • Using environment:

    export VAR=var; make
    

    or (better because it change environment only for current command)

    VAR=var make
    

They are slightly different. The first one is stronger. It mean you know what you want. The second may be considered like a hint. Difference between them is about operators = and += (without override). These operators are ignored when a variable is defined on command line, but are not ignored when variable is defined in environment. Thus, I suggest you to have a Makefile with:

CC ?= gcc
CFLAGS += -Wall
INTERNAL_VARS = value

and call it with:

CFLAGS=-g make

Notice, if you want to withdraw -Wall, you can use:

make CFLAGS=

Please don't use override keyword, else you won't have any way to change a variable affected with override.


Just a note, as I got confused - let this be file testmake:

$(eval $(info A: CFLAGS here is $(CFLAGS)))

override CFLAGS += -B

$(eval $(info B: CFLAGS here is $(CFLAGS)))

CFLAGS += -C

$(eval $(info C: CFLAGS here is $(CFLAGS)))

override CFLAGS += -D

$(eval $(info D: CFLAGS here is $(CFLAGS)))

CFLAGS += -E

$(eval $(info E: CFLAGS here is $(CFLAGS)))

Then:

$ make -f testmake
A: CFLAGS here is 
B: CFLAGS here is -B
C: CFLAGS here is -B
D: CFLAGS here is -B -D
E: CFLAGS here is -B -D
make: *** No targets.  Stop.
$ make -f testmake CFLAGS+=-g
A: CFLAGS here is -g
B: CFLAGS here is -g -B
C: CFLAGS here is -g -B
D: CFLAGS here is -g -B -D
E: CFLAGS here is -g -B -D
make: *** No targets.  Stop.

With the override directives deleted from the testmake file:

$ make -f testmake
A: CFLAGS here is 
B: CFLAGS here is -B
C: CFLAGS here is -B -C
D: CFLAGS here is -B -C -D
E: CFLAGS here is -B -C -D -E
make: *** No targets.  Stop.
$ make -f testmake CFLAGS+=-g
A: CFLAGS here is -g
B: CFLAGS here is -g
C: CFLAGS here is -g
D: CFLAGS here is -g
E: CFLAGS here is -g
make: *** No targets.  Stop.

So,

  • if a variable used override once, it can only be appended with another statement with override (the normal assignments will be ignored);
  • when there's been no override at all; trying to append (as in +=) from the command line overwrites every instance of that variable.