Подтвердить что ты не робот

Как сделать $(eval $(shell...)) работать в GNU make

make синтаксис является разделителем строки, но $(shell...) заменяет символы новой строки пробелом. Итак, какой наименее уродливый способ сделать

$(eval $(shell program-that-emits-makefile-фрагмент))

который не работает так, как вам хотелось бы.

4b9b3361

Ответ 1

Это, вероятно, будет делать то, что вы имеете в виду:

makefile_fragment:
  program-that-emits-makefile-fragment > [email protected]

include makefile_fragment

Это достаточно? Существуют дополнительные трюки, которые вы можете использовать, если они вам нужны, например, когда правило добавляет контекст вокруг того, что создает программа, или передает вывод через sed, чтобы разглядеть его в одну строку, а затем разобрать его с помощью обратных косых черт.

Ответ 2

Проблема уже сообщалась разработчикам GNU make make:

http://savannah.gnu.org/bugs/?28230

Он был закрыт следующим комментарием:

Как упоминает Филипп, это намеренное/задокументированное поведение.
Я рекомендую использовать "include", а не eval; попросите script записать файл, затем включите этот файл.

ДОБАВЛЕНО: Там обходной путь! Здесь образец 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' '#')))

Вам нужно выбрать символ, который не появится на выходе script; # кажется хорошим кандидатом.

Ответ 3

Вот способ сделать это, захватив символ замены #, поэтому нам не нужно полагаться на char, который не отображается в выводе myscript.

define nl


enddef
$(foreach line, $(shell myscript | sed -e 's/%/\\%/' -e 's/$$/%/'), \
  $(eval $(patsubst %, $(line), $(nl))))