2011-01-28 2 views
0

часть моего Makefile:Makefile: нужно сделать цель, прежде чем включать еще один Makefile

CPUDEPS=./mydeps.cpu 
(...) 
deps: $(CPUDEPS) 

$(CPUDEPS): $(CCFILES) 
@echo [DEPS] CPU 
$(CMDECHO)makedepend -Y -s'# CPU sources dependencies generated with "make deps"' \ 
    -w4096 -f- -- $(CFLAGS) -- $^ 2> /dev/null > $(CPUDEPS) 
(...) 
sinclude $(CPUDEPS) 

Проблема 1: включает сделаны во время первой фазы обработки, цели во время второй фазы; поэтому, если ./mydeps.cpu не существует, и я «сделать DEPS», я получаю первый ошибка

Makefile:335: ./mydeps.cpu: No such file or directory 

Я скрыть ошибку, используя sinclude вместо include, но проблема все еще существует: старый файл включен, а не только сгенерированный-один. Необходимо запустить его дважды, чтобы включить обновленный файл. Это потому, что make делает двухфазную обработку; есть ли способ сказать make завершить целевые отпечатки до синтаксический анализ включает?

Задача 2: даже если файл ./mydeps.cpu не существует и make deps фактически создает его, я всегда получаю «делать: ничего, чтобы сделать для DEPS». Это не происходит с другими целями. Я не понимаю, почему и как его избежать.

ответ

1

Проблема 1 не существует: перед созданием цели make автоматически перестраивает make-файлы (с неявными правилами, если не указано явное правило). Таким образом, наличие правила для make-файла гарантирует, что оно всегда будет актуальным, нет необходимости запускать deps дважды. Кроме того, поскольку CPUDEPS является make-файлом, он будет обновляться автоматически до запуска любого другого правила, поэтому зависимости будут всегда обновляться, если необходимо, и make deps не требуется. Вы, вероятно, заметите это сами, заметив, что линия [DEPS] эхом, если какой-либо из CCFILES становится более поздним, чем файл зависимостей.

Для проблемы 2 добавление чего-либо к рецепту гарантирует, что make не жалуется на то, что ему нечего делать. Если нет ничего другого, вы можете использовать что-то вроде @echo OK, чтобы дать обратную связь пользователю или просто @true, если вы предпочитаете полностью тихие произведения.

1

То, что вы пытаетесь достичь, бесполезно: вы можете использовать файл зависимостей, который был создан во время предыдущей сборки. Достаточно.

Основное обоснование этого правила является:

  • если вы не изменили какой-либо из файлов, то файл зависимостей вверх-к-дата, и нет ничего строить.
  • Если вы что-то изменили, даже очень глубоко в цепочку #include, на существующий файл, который использовался предыдущей сборкой, тогда файл зависимостей уже поймал его. Вы восстановите то, что нужно.
  • если вы что-то изменили в новом файле (вы добавите этот файл!), То он не был использован предыдущей сборкой и не указан в зависимостях. Но если вы действительно хотите его использовать, вам необходимо изменить хотя бы один из ваших других файлов, который использовался ранее, и вы вернулись к предыдущему случаю.

Решение состоит в том, чтобы создать файл зависимостей во время нормального процесса компиляции, а также необязательно включать его (с sinclude), если он присутствует.

+0

Эта проблема «решает» 1 в случае обновления зависимостей, но возможно ли реализовать такой механизм для общих целей? (Я имею в виду: включая файл, который только что был создан). – Narcolessico

+0

@EugenioR: прочитайте [Расширенное создание автозависимости] (http://mad-scientist.net/make/autodep.html) – bobbogo

Смежные вопросы