Большинство make-файлов имеют такую структуру:
.PHONY: prebuild
all: $(TARGET)
prebuild: Makefile
$(shell DEPDIR=$(DEPDIR) mkdir -p $(DEPDIR)/../common >/dev/null)
# do other work related to preparing for the object files to be built such as run a script to modify a header file included by $(TARGET).c
$(TARGET): $(TARGET).c prebuild
$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c
Неявные правила знают, как собрать $(TARGET).o
из $(TARGET).c
, и не выполняют никакой работы, если $(TARGET).o
уже новеечем $(TARGET).c
.Это происходит, когда make запускается несколько раз без изменения исходного файла.
Однако построение цели all
, приведенной выше, по-видимому, всегда перезапускает ссылку $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c
, чтобы связать приложение и создать двоичный файл приложения.Это происходит, даже если этот двоичный файл уже существует и не нуждается в воссоздании.В некоторых крупных проектах этот процесс может занять много времени (десятки секунд), что иногда нежелательно.
Редактирование # 1: Проблема связана с дополнительной фальшивой целью, которую я хочу запустить ОДИН РАЗ перед созданием объектных файлов.В моем случае я запускаю скрипт, который принимает переменные Makefile и, возможно, обновляет заголовочный файл, который включен в C-файл.Но, если Makefile не изменяется, цель предварительной сборки не запускается.Однако цель $(TARGET)
все еще выполняется, даже если prebuild
ничего не делает (например, потому что Makefile
не был изменен).К вашему сведению: из-за структуры моей системы сборки, я всегда запускаю prebuild
, потому что моя система сборки используется для различных приложений, которые могут динамически переопределять prebuild
.
- Как этот Makefile можетбыть реструктурирован, чтобы не выполнять связывание снова, когда в этом нет необходимости?
Edit # 2: Вот упрощенный пример, который, кажется, иллюстрирует мою проблему:
Перед запускомсоздайте новый каталог и touch a b
.PHONY: prebuild main all
all: main
prebuild: a Makefile
@echo prebuild ran
main: prebuild
@echo main ran
Когда я запускаю, я получаю следующий вывод:
prebuild ran
main ran
Это то, что происходит независимо от того, сколько раз я запускаю make, дажехотя обязательное условие a, ни Makefile не меняется.Я ожидаю, что prebuild не запускается (потому что a и Makefile не меняются) и main также не запускается, потому что prebuild не запускается.Понятно, что я что-то неправильно понимаю.