Синтаксис make является разделителем новой строки, но $ (shell .. .) заменяет символы новой строки пробелами. Итак, какой наименее уродливый способ сделать
$ (eval $ (shell-program-that-emits-makefile-фрагмент))
, который работает не так, как хотелось бы.
Это, вероятно, подойдет для того, что вы задумали:
makefile_fragment:
program-that-emits-makefile-fragment > $@
include makefile_fragment
Достаточно? Есть дополнительные приемы, которые вы можете использовать, если они вам нужны, например, добавление правилом контекста к тому, что производит программа, или передача вывода через sed, чтобы объединить его в одну строку, а затем разобрать его с помощью обратной косой черты.
Вот способ сделать это путем перехвата символа подстановки%, поэтому нам не нужно полагаться на символ, который не появляется в выводе myscript.
define nl
enddef
$(foreach line, $(shell myscript | sed -e 's/%/\\%/' -e 's/$$/%/'), \
$(eval $(patsubst %, $(line), $(nl))))
О проблеме уже было сообщено в GNU make сопровождающие:
http://savannah.gnu.org/bugs/?28230
Он был закрыт следующим комментарием:
Как упоминает Филип, это предполагаемое / задокументированное поведение.
Я рекомендую использовать "include" вместо eval; пусть ваш сценарий выпишет файл, а затем включит этот файл.
ДОБАВЛЕНО : Есть обходной путь! Вот пример файла GNUmakefile (замените 8 пробелов табуляцией; да, после define newline
есть две пустые строки):
define newline
endef
$(eval $(subst #,$(newline),$(shell { echo 'war:'; echo ' echo "not love?"'; echo ' echo "Give peace a chance!"'; } | tr '\n' '#')))
В общем, это $ (eval $ (subst #, $ (newline ), $ (shell myscript | tr '\ n' '#')))
Вы должны выбрать символ, который не появится в выводе скрипта; #
кажется хорошим кандидатом.