GNU makefile如何使用引号以及何时使用引号来引用字符串

49

如何在makefile中引用字符串?最佳实践是什么?

以下是否为正确的引用方式?

$(warning  $(shell ls -ld "$(CURDIR)" ) )

我熟悉Bash,在其中通常需要对变量进行引用以允许嵌入空格。在makefile中是否也需要这样做呢?

使用字符串如何进行赋值语句?

vara := "$(CURDIR)"

varb := $(CURDIR)

varc := /home/me/source

vard := "/home/me/source"

等号后面的空格怎么办?

1个回答

51

因为make不理解也不解析单引号或双引号字符,所以你绝不应该因为引号而引用任何内容。在makefile中编写的每个引号字符都将作为字面引号保留,并原样传递给make调用的命令。

因此,如果shell期望并能够解释带引号的字符串,则应使用引号。当shell不期望或无法正确解释带引号的字符串时,您不应使用引号。

在您的示例中,引号是否可接受取决于这些变量被如何使用。如上所述,make不会对引号执行任何特殊操作,这意味着vard(例如)包含了字面字符串"/home/me/source"(包括引号)。

如果您以一种shell可以为您处理引号的方式使用该值,那么就没问题:

all: ; echo $(vard)

会输出/home/me/source(不带引号),因为shell会解释它们。但是,如果你在make环境下使用该变量,例如作为目标或先决条件:
all: $(vard)
$(vard): ; echo $@

那么这是不正确的,因为目标和先决条件都是文字字符串"/home/me/source"(包括引号)。

通常最好不要在变量周围加上文件名的引号,而是在make变量的配方中添加引号。当然,如果变量包含整个shell脚本而不仅仅是文件名,则应向脚本添加适当的引号。


ifequ "$(varx)" "a" 这段代码让我有些困惑。 - historystamp
2
其中一个结果是_make_不能容忍文件名中的空格。空格是列表分隔符,正如MadScientist指出的那样,它是不可引用的。_make_通常会将这样的文件名分解成无用的片段。 - bobbogo
9
这段内容可能与提问者的意图无关,但其他用户可能会找到这里并不理解$(VARX)这样的“创建变量”和$${VARZ}这样的“shell变量”的区别 - 请注意双重美元符号$$是make用来区分它们的。因此,在需要将shell变量作为变量传递给命令而不进行扩展时,您可能需要使用单引号。例如:将$ORIGIN传递给链接器,则使用带有单引号的cc -Wl,-rpath='$${ORIGIN}' -shared -fPIC -Wall $(SRC) -o $(DIR)/$(LIB),以防止在shell中扩展它。 - Mark Mikofski
关于我的评论,请参见MadScientists在make文件中如何正确传递$ORIGIN的答案,其中使用了单引号和双美元符号,但-Wl,option的语法与我的示例略有不同。 - Mark Mikofski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接