开发者

Output multiline variable to a file with GNU Make

I'm having hard time writing a makefile rule that outputs a multiline variable in a file.

Here is th开发者_StackOverflowe code I have :

define VAR1
    /dev d 755 - - - - -
endef

define VAR2
    /test d 777 - - - - -
    /test2 d 777 - - - - -
endef

VARS += $(VAR1)
VARS += $(VAR2)

all:
    echo "$(VARS)" > test

However, the echo fails telling "Unterminated quoted string" for a reason unknown to me. How could i put in the file every lines declared on a separate line ?


If you export the variable to the shell and reference it as a shell variable, rather than a make variable, you will have better luck:

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

Note the following adjustments to your makefile:

  • I used define to create VARS, rather than a series of += assignments, which makes it easier to get a newline between the value of VAR1 and VAR2.
  • I added export VARS to your makefile, to get the variable pushed into the environment for the shell invocation.
  • I used $$VARS rather than $(VARS) to dereference it -- that leaves the expansion to the shell, rather than to make, which will avoid the "Unterminated quoted string" error.


GNU make 4.0 adds the ability to write files directly:

define VAR1
    /dev d 755 - - - - -
endef

define VAR2
    /test d 777 - - - - -
    /test2 d 777 - - - - -
endef

define VARS :=
$(VAR1)
$(VAR2)
endef

all:
        $(file > test,$(VARS))

Note that you still need to use define to define VARS, or the last line of VAR1 and the first line of VAR2 will be glommed onto one line. Also, don't put a space after the comma in the $(file ...) construct, or there will be a leading space in the output!


It looks as if you're getting "Unterminated quoted string" because Make executes each line of the recipe in a separate shell, and the first line is:

echo "    /dev d 755 - - - - -

Here's the best solution I could come up with (and I admit it's not very good, but you're going against the grain of Make) is to pass VARS to a sub-Make which invokes $(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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜