Пока что мой подход заключается в создании файла cc-options-dump
с содержимым раскрытия переменной COMPILE.c
каждый раз, когда создается lib.o
.
Хеш MD5, полученный в результатерасширение текущей переменной COMPILE.c
сравнивается с той, которая использовалась для предыдущей сборки, т. е. той, чье содержимое хранится в файле cc-options-dump
, если таковое имеется (то есть, если файл существует).
.PHONY: foo bar require-rebuild cc-options-dump
# include the xxx/config.mk files
# sort built-in function to make it independent of the order (i.e., "foo bar" or "bar foo")
$(foreach opt,$(sort $(MAKECMDGOALS)),$(eval include $(opt)/config.mk))
# obtain the MD5 hash of the previously used flags
ifneq (,$(wildcard cc-options-dump))
prev-cc-options-hash := $(shell md5sum cc-options-dump | cut -f1 -d' ')
endif
# obtain the MD5 hash of the current flags
curr-cc-options-hash := $(shell echo "$(COMPILE.c)" | md5sum | cut -f1 -d' ')
# Do these hashes differ?
ifneq ($(prev-cc-options-hash),$(curr-cc-options-hash))
# keep track of the fact that a rebuilt needs to be triggered
does-need-rebuild := require-rebuild
# just for displaying information
$(info Rebuild required)
else
$(info Rebuild not required)
endif
# make both targets foo and bar dependent on the file with the flags
# so that it has to be generated, since it is a phony target as well
foo bar: cc-options-dump
# lib.o has now an additional prerequisite for determining whether it need to be rebuilt
lib.o: $(does-need-rebuild)
# save the used compiler flags for comparing them with the future flags
cc-options-dump: lib.o
@echo '$(COMPILE.c)' >$@
Поведение этого make-файла при вызове make
для целей foo
и / или bar
соответствует, насколько я вижу, желаемому:
$ make foo
Rebuild required
cc -DFOO -c -o lib.o lib.c
$ make foo
Rebuild not required
$ make bar
Rebuild required
cc -DBAR -c -o lib.o lib.c
$ make bar
Rebuild not required
$ make foo bar
Rebuild required
cc -DBAR -DFOO -c -o lib.o lib.c
$ make bar foo
Rebuild not required
Использование встроенной функции sort
крайне важно для правильной работы последних двух приведенных выше случаев.
Было бы замечательно, если бы кто-то мог прийти с болееэлегантное решение.