Вывести многострочную переменную в файл с помощью GNU Make
Мне сложно писать правило makefile, которое выводит многострочную переменную в файле.
Вот код, который у меня есть:
define VAR1
/dev d 755 - - - - -
endef
define VAR2
/test d 777 - - - - -
/test2 d 777 - - - - -
endef
VARS += $(VAR1)
VARS += $(VAR2)
all:
echo "$(VARS)" > test
Тем не менее, эхо не дает указания "Unterminated quoteed string" по неизвестной мне причине.
Как я могу поместить в файл каждую строку, объявленную в отдельной строке?
Ответы
Ответ 1
Если вы экспортируете переменную в оболочку и ссылаетесь на нее как на переменную оболочки, а не на переменную make, вам повезет больше:
define VAR1
/dev d 755 - - - - -
endef
define VAR2
/test d 777 - - - - -
/test2 d 777 - - - - -
endef
define VARS
$(VAR1)
$(VAR2)
endef
export VARS
all:
echo "$$VARS" > test
Обратите внимание на следующие настройки вашего файла makefile:
- Я использовал
define
для создания VARS
, а не для серии +=
назначений, что упрощает получение новой строки между значением VAR1
и VAR2
.
- Я добавил
export VARS
в ваш make файл, чтобы получить переменную, введенную в среду для вызова оболочки.
- Я использовал
$$VARS
, а не $(VARS)
, чтобы разыменовать его - это оставляет расширение для оболочки, а не для создания, что позволит избежать ошибки "Unterminated quoteed string".
Ответ 2
GNU make 4.0 добавляет возможность напрямую записывать файлы:
define VAR1
/dev d 755 - - - - -
endef
define VAR2
/test d 777 - - - - -
/test2 d 777 - - - - -
endef
define VARS :=
$(VAR1)
$(VAR2)
endef
all:
$(file > test,$(VARS))
Обратите внимание, что вам все равно нужно использовать define
для определения VARS
, или последняя строка VAR1
, а первая строка VAR2
будет зависеть от одной строки. Кроме того, не помещайте пробел после запятой в конструкцию $(file ...)
, или на выходе будет ведущее место!
Ответ 3
Похоже, что вы получаете "Unterminated quoteed string", потому что Make выполняет каждую строку рецепта в отдельной оболочке, а первая строка:
echo " /dev d 755 - - - - -
Здесь лучшее решение, которое я мог бы придумать (и я признаю, что это не очень хорошо, но вы идете против зерна Make) заключается в передаче VARS
в суб-Make, который вызывает $(info ...)
:
Makefile:
define VAR1
/dev d 755 - - - - -
endef
define VAR2
/test d 777 - - - - -
/test2 d 777 - - - - -
endef
define VARS
$(VAR1)
$(VAR2)
endef
export VARS
all:
$(MAKE) -f Makefile.print > test
Makefile.print:
$(info $(VARS))
.PHONY:all
all:
@# do nothing