Makefile создает цель, даже если предварительные условия не изменились - PullRequest
0 голосов
/ 18 декабря 2018

Большинство 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 не запускается.Понятно, что я что-то неправильно понимаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...