2017-02-23 108 views
2

В моей программе у меня несколько сложный процесс сборки. В настоящее время в одном каталоге я использую include в Makefile.am с файлом, который не существует, но его нужно строить самостоятельно. Причина в том, что этот файл довольно длинный. Далее в реальной программе это не только один файл, но несколько, и процесс генерации этого файла может время от времени меняться.Сгенерировать включить файлы для Makefile тем же Makefile

Makefile.am выглядит как этот

noinst_LIBRARIES = libtest.a 
nodist_libtest_a_SOURCES = file.c 
CLEANFILES = file.c Make_file.mk 

$(builddir)/Make_test.mk: $(srcdir)/Perl/generate_mk_files.pl 
     perl $(srcdir)/Perl/generate_mk_files.pl file 

include $(builddir)/Make_file.mk 

После создания Make_file.mk он выглядит что-то вроде

$(builddir)/file.c: $(srcdir)/file.template $(srcdir)/Perl/generate_c.pl 
     perl $(srcdir)/Perl/generate_c.pl $(srcdir)/file.template 

Automake работает, а окончательный процесс сборки, а также. Выход на make что-то вроде (я замкнута это несколько):

Makefile:721: Make_file.mk: Datei oder Verzeichnis nicht gefunden (file not found) 
perl ../../../../src/components/test/Perl/generate_mk_files.pl test 
perl ../../../../src/components/test/Perl/generate_c.pl ../../../../src/components/test/file.template 

Поэтому make первый жалуется, что файл включает не найден, а затем создает его, а затем следует также правила включаемого файла.

Хотя я рад, что он работает, я задаюсь вопросом, почему. Во-первых, я думал, что make загружает Makefile. На этом этапе Make_file.mk не существует. Поэтому кажется, что Makefile загружен более одного раза.

Далее, manual из Automake для include состояний:

Обратите внимание, что эти фрагменты читаются и интерпретируются Automake, не сделать.

Это не то, что я вижу, так как включенный фрагмент не существует во время выполнения Automake.

Мои вопросы в основном являются:

  • Почему это работает?
  • Это правильный способ сделать это или использовать другой подход, например. начиная с новых экземпляров make в пределах Makefile.

ответ

2

Я не знаю Automake, но, с ГНУ сделать руководство:

Если включенный Makefile не может быть найден в любом из этих каталогов {стандарт включает в себя каталоги}, предупреждения генерируется сообщение, но это не является непосредственной фатальной ошибкой ; обработка make-файла, содержащего include, продолжается. После того, как он закончил читать make-файлы, make попытается переделать любые , которые устарели или не существуют. См. Раздел «Как make-файлы». Только после того, как он попытался найти способ переделать make-файл и не смог, сделает диагностику отсутствующего make-файла как фатальной ошибки.

Если вы хотите сделать, чтобы просто игнорировать Makefile, который не существует или не может быть переделано, без сообщений об ошибках, используйте -Include директиву вместо включать, например:

-include filenames…

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

В основном, make не может выполнить рецепт для перепродажи файла включения, прежде чем он закончит, чтобы проанализировать основной файл Makefile. Таким образом, он вызывает предупреждение, продолжает читать Makefile, находит правило для перепродажи включенного файла, переделывает его и перезапускает сам (что подробно объясняется в разделе «Как Makefiles Are Remade»).

+0

Благодарим вас за комментарий. Я думаю, что в основном объясняет, почему он работает. Я буду проверять руководство по эксплуатации для более подробной информации. Я не буду принимать ответ, но, возможно, у кого-то есть лучшее представление о том, как справиться с моим сценарием. – Nemesis

+2

FYI, проблема с посторонними ошибками была исправлена ​​в новых версиях GNU make (4.2 и выше); вам больше не нужно использовать '-include' для его подавления. – MadScientist

0

Возвращаясь к manual, он утверждает, что есть две формы automake с включают механизм:

include $(srcdir)/file 

и

include $(top_srcdir)/file 

ни один из которых соответствовал свой include. Поэтому я бы предположил, что include фактически управляется базовым make тем, что может быть (например, GNU Make, хотя, конечно, у других программ make есть эта функция).

Теперь вопросы:

Почему это работает?

Как объяснено в другом ответе, GNU Make попытается сделать отсутствующий файл include d перед сбоем.

Это правильный способ сделать это или использовать другой подход, например. запуск новых экземпляров марки в Генерирующие Makefiles Makefile

является одной из задач Autotools сделать, либо через autoconf или automake. Переход на несколько этапов «создания make-файлов» кажется склонным к ошибке (и трудно поддерживать). Recursive make имеет схожие проблемы.

Причина в том, что этот файл включает в себя довольно длинный.

automakeinclude заявление будет счастливо склеить большой Makefile из более мелких компонентов.

Далее в реальной программе это не только один файл, но и несколько, и процесс генерации этого файла может время от времени меняться.

Трудно рекомендовать, что предложить сделать в autotools, основываясь на том, как определяются «изменения».Поскольку кажется, что вы также используете libtool, добавляя/удаляя источники в libs (или целые библиотеки), могут быть сделаны conditionals, переменные и т. Д.