Вот основной способ сделать это (хотя я убежден, что это ужасная идея, см. Ниже):
-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 $@ $^
Вот что происходит: перед выполнением любой компиляции текущие CFLAGS
записываются в CFLAGS.save
. Если CFLAGS
не равно CFLAGS_SAVE
, то пользователь, должно быть, изменил их. Если это так, мы объявляем CFLAGS.save
фальшивым, поэтому make
перестроит его. Также обратите внимание, что если CFLAGS
изменилось, мы обновим его, но в памяти останется старое значение. Поэтому мы должны рекурсивно вызывать make
для каждого исходного файла. Не круто на большом проекте.
Другая проблема заключается в том, что если вы не укажете указать CFLAGS
в командной строке, он вернется назад и перестроит все по умолчанию. Вы можете обойти это, протестировав $(origin)
из CFLAGS
, но серьезно, нет. Моя профессиональная этика не позволит мне отстаивать это.
make
должно быть простым . У дистрибьюторов уже достаточно проблем с пониманием злоупотреблений упаковщиков инструментами сборки (к сожалению, большая часть вины, нивелируемая на automake
, связана с этим). Пожалуйста, просто скажите нет системам сборки Ктулхоида.
Кроме того, make clean all CFLAGS='-Whatever -foo'
будет работать так же хорошо.