Как заставить make завершиться неудачей, если генерация требуемого включения проходит, но файл фактически не создан

#makefile

#makefile

Вопрос:

У меня есть makefile, который ошибочно генерирует требуемый файл включения makefile. Включаемый файл изначально не существует, но существует правило для его создания. Правило выполняется успешно, но из-за ошибки требуемый включаемый файл создается не там, где ожидалось (и, следовательно, make не может его включить). Однако вместо сбоя make (из-за того, что файл все еще не может быть включен), make завершается успешно.

Ниже приведен мой файл makefile1.mak.

 include myfile.mak

default:
    @echo hi

myfile.mak:
    @echo hello
  

Когда я выполняю ‘make -f makefile1.mak’, я получаю:

 makefile1.mak:1: myfile.mak: No such file or directory
hello
hi
  

Конечно, я, наконец, выяснил, что мой код для генерации myfile.mak генерировал его неправильно, но фактические make-файлы, которые я использую, имеют длину в 100 строк, поэтому мы не заметили, что включение не происходило довольно долгое время (это была очень тонкая проблема сборки, которая была введена).

Итак, мой вопрос — есть ли какой-либо способ заставить make завершиться неудачей в приведенном выше примере?

Комментарии:

1. Как выполняется ваше правило, несмотря на то, что не удается создать файл? Исправление правила, вероятно, является лучшей линией атаки, поскольку отсутствующее включение является ошибкой только в том случае, если правило для его генерации завершается неудачей: «Только после того, как оно попыталось найти способ переделать makefile и потерпело неудачу, будет диагностироваться отсутствующий makefile как фатальная ошибка».

2. Это относится ко всем целевым объектам (не только к включаемым файлам) по замыслу — если рецепт выполняется успешно, то make слепо «верит», что цель была создана успешно. Если это может быть проблемой, вам следует проверить наличие целевого объекта вручную, как предлагает @Beta.

3. @Matt, спасибо, что указал, что это было сделано специально, хотя это кажется плохим поведением для случая includes . Т.е. если я не использую ‘-include’, я говорю make, что файл ДОЛЖЕН быть включен, поэтому, если включаемый файл не может быть включен даже после того, как он предположительно перестроен, тогда make не сможет прогрессировать (потому что я сказал ему, что он ДОЛЖЕН включать файл, который он не может включать). При этом я понимаю, что это способ make, и мне придется с этим согласиться.

4. @JohnKugelman, спасибо за ответы. Однако я хотел сказать, что я не знал, что рецепт был неверным, и сборка продолжалась. Если бы я знал, что рецепт неверен, я бы исправил его :-).

Ответ №1:

Добавьте строку в правило:

 myfile.mak:
    do various things to build myfile.mak
    test -f $@
  

Комментарии:

1. Как я упоминал в своих комментариях выше, если бы я знал, что рецепт неверен, я бы написал рецепт правильно в первую очередь :-). На мой взгляд, добавление ‘test’ к каждому целевому объекту не должно быть необходимым.

2. @Brett: Каждая цель? Я не уверен, о чем вы просите.

3. Если в моем процессе сборки у меня есть 100 различных рецептов, используемых для создания 100 различных целей включения makefile, мне нужно было бы установить эту проверку в каждую из этих 100 различных целей для включения makefile. Тогда как, на мой взгляд, если я скажу make включить данный файл (и не игнорировать, существует ли файл, используя синтаксис ‘-‘), он должен завершиться неудачей, если он не может включить файл, который я сказал ему не включать автоматически. Я надеюсь, что это имеет больше смысла.

4. @Brett: Есть способ получить желаемый эффект без добавления команд к этим правилам, но, насколько я знаю, нет способа заставить Make вести себя так, как вы считаете нужным.