2017-01-18 14 views
0

Если перебрать .VARIABLES и печать каждого, любая истинная переменная может быть напечатана правильно со следующим правилом:переменные печати, включая функции из Makefile и/или переменной интроспекции

print_variables: $(foreach V,$(.VARIABLES),print-$(V)) .phony_explicit 
print-%: .phony_explicit; @echo "$* = \"$($*)\"" 
.PHONY: .phony_explicit ... 

0- или 1-линии функция будет по-прежнему работать, но больше не приведет к Syntax error: Unterminated quote string. Только одна многострочная функция разрушит все правило print_variables. В качестве обходного пути я добавил ;\ в каждую строку в определениях моих функций, но это не будет исправлять существующие многострочные функции (либо через include из этого makefile, либо через другие make-файлы, включая этот.) Что я могу сделать? Есть ли контейнер только функциональных переменных или способ проверить, является ли переменная определением функции?

ответ

1

Простым минимальным примером было бы легче понять; это не имеет ничего общего с .VARIABLES, шаблонные правила и т.д. (и я не уверен, что точка .phony_explicit Prereq есть ..)

define F 
foo 
bar 
endef 

print: ; echo "F = $(F)" 

покажет проблему:

echo "F = foo 
/bin/sh: 1: Syntax error: Unterminated quoted string 

Это происходит потому, что когда make видит переменную, которая содержит новые строки в рецепте, она предполагает, что новые строки означают, что вы хотите, чтобы строки переменной стали линиями в рецепте.

Прежде всего, вы должны использовать одиночные кавычки вокруг строк, которые вы отправляете в оболочку, если только вам не нужна оболочка для их расширения; это не поможет в этой ситуации, но в целом это намного безопаснее.

Невозможно отменить это на самом деле. У вас есть несколько вариантов.

Первый не использовать эхо, но вместо того, чтобы использовать функцию грим info:

print-F: ; $(info F = "$(F)") 

урожайности:

F = "foo 
bar" 

Другой вариант заключается в использовании subst заменить символ новой строки с каким-либо другим значением. Новое значение, не может содержать явные символы новой строки, но вы можете попросить оболочки напечатать строку для вас:

# Create a variable containing a single newline 
# Note this must contain TWO newlines! 
define NL 


endef 

print-F: printf 'F = "$(subst %,%%,$(subst $(NL),\n,$(F))"\n' 

Урожайность:

printf 'F = "foo\nbar"\n' 
F = "foo 
bar" 

Один окончательный вариант заключается в преобразовании Makefile использовать функция .ONESHELL, но я предполагаю, что это шаг слишком далеко, чтобы получить доступ к этому отладочному выводу :).

+0

Добавление 'phony_explicit' в' .PHONY' означает, что добавление 'phony_explicit' к любой другой цели делает этот целевой фальшивый. (Другими словами, это позволяет вам сделать phoniness предпосылкой для вашей цели, а не сделать вашу цель предпосылкой для '.PHONY'.) В результате голословность цели объявляется в том же самом месте, что и сама цель. В противном случае вам придется либо прыгать взад-вперед к вашей цели .PHONY, читая/записывая фальшивые цели в другом месте, либо перенаправляйте «.PHONY» рядом с каждой применимой целью. Я не знаю более элегантного решения. Спасибо за вашу помощь! –

+0

Кстати, 'print-F: echo 'F =" $ (subst $ (NL) ,;, $ (F)) "'', вы имели в виду добавить точку с запятой или новую строку после 'print-F: '? Кроме того, вот где я верю, что узнал этот фальшивый трюк. http://stackoverflow.com/a/38803814/1043529 –

+0

Я просто добавляю '.PHONY' рядом с каждой целью; дополнительная линия меня не беспокоит. Но YMMV. Я не хотел добавлять новую строку; вы не можете сделать это с эхом, но это дает мне представление: вы можете использовать printf. Я уточню свой ответ. – MadScientist

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

  • Нет связанных вопросов^_^