Мысли по поводу того, как убрать мистическое знание программиста "а теперь необходимо сделать clean + full rebuild" и записать его в makefile (не важно, какого конкретно из make).
Устанавливать makefile целиком как зависимость для перекомпиляции проекта целиком - нехорошо, так как он автогенерится, и от убранного import/include его содержимое изменится. Но с другой стороны, изменение команды компиляции - это уже повод пересобрать все ноды где эта команда используется.
Значит, зависимости надо хранить отдельно, и их изменение - не вызывает full rebuild. А вот команды компиляции - надо добавить в зависимости всех нод которые их вызывают.
Например, вместо:
foobar.obj: foobar.cpp
compiler -c foobar.cpp -o foobar.obj -some-compiler-flag1 -some-compiler-flag2
писать makefile как-то так:
foobar.obj: foobar.cpp compile.sh # compile.sh тоже в зависимостях этой ноды
compile.sh foobar.cpp -o foobar.obj
compile.sh: env.COMPILER_PATH.txt # compile.sh зависит от переменной окружения COMPILER_PATH
env.INCLUDE.txt:
echo $COMPILER_PATH> env.COMPILER_PATH.txt
По хорошему, compile.sh так же должен зависеть от всех файлов в системе которые влияют на его работу. Например, изменение системной версии gcc после apt-get dist-updgrade - это повод пересобрать проект.
Могут быть ещё дополнительные зависимости, например от переменных окружения. Такие переменные окружения можно распечатать в файл и тоже поставить как зависимости в makefile
( так же отдельно надо думать о том, что бы убивать файлы без родителей, и о том как детектить "файл изменился", см. тег "
build" ).