Here's a basic way to do this (although I'm convinced it's a terrible idea, see below):
-include CFLAGS.save
CFLAGS := -O2 -g
all: foo
CFLAGS.save:
echo 'CFLAGS_SAVE := $(CFLAGS)' > $@
ifeq ($(CFLAGS),$(CFLAGS_SAVE))
%.o: %.c CFLAGS.save
gcc $(CFLAGS_SAVE) -c -o $@ $<
else
.PHONY: CFLAGS.save
%.o: %.c CFLAGS.save
$(MAKE) $@
endif
foo: foo.o
gcc -o $@ $^
Here's what happens: Before any compilation is done, the current CFLAGS
are written out to CFLAGS.save
. If CFLAGS
isn't equal to CFLAGS_SAVE
, then the user must've changed them. If so, we declare CFLAGS.save
to be phony so make
will rebuild it. Note also that if CFLAGS
has changed, we'll update it but we'll still have the old value in memory. Therefore, we have to recursively invoke make
for every source file. Not cool on a big project.
The other problem is that if you neglect to specify CFLAGS
on the command line, it will go back and rebuild everything with the default. You could work around this by testing the $(origin)
of CFLAGS
, but seriously, no. My professional ethics won't allow me to stand for this.
make
is meant to be simple. Distributors already have enough trouble understanding packagers' abuses of build tools (sadly, most of the blame levelled at automake
is due to this). Please, just say no to Cthulhoid build systems.
Besides, make clean all CFLAGS='-Whatever -foo'
will work just as well.