In GNU Makefiles, there are often interactions between environment variables and parameters/variables/macros. There are also several different assignment operators, there are "override" variables that can be provided on the command line, and there is an override
directive.
What are the precedence rules for these interactions?
Consider this Makefile:
# Use := to avoid infinite recursion of macro expansion
CFLAGS := -g -O2 $(CFLAGS)
hello: src/hello.c
cc $(CFLAGS) -o $@ $<
If you invoke CFLAGS=-pipe make hello
, you get cc -g -O2 -pipe -o hello src/hello.c
. If you invoke make CFLAGS=-pipe hello
, you get cc -pipe -o hello src/hello.c
. What's the difference?
And if you change the Makefile to:
CFLAGS ?= -g -O2 $(CFLAGS)
hello: src/hello.c
cc $(CFLAGS) -o $@ $<
You get cc -pipe -o hello src/hello.c
in both cases.