Вывести многострочную переменную в файл с помощью 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