在makefile中,使用
\
转义换行符可以将单行长字符串内容拆分为多个源行。然而,换行符会被替换为空格。是否存在一个透明的源代码换行符不影响字符串内容?VAR=w\
o\
r\
d
all:
echo $(VAR)
期望输出为'word',但实际输出为'w o r d'。
最简单的解决方案是使用$\<newline>
来拆分行(至少在使用GNU Make时是这样):
VAR = w$\
o$\
r$\
d
all:
echo $(VAR)
输出将会是"word",没有空格。这是因为GNU Make会用一个空格替换反斜杠-换行符-空格,使得对VAR
的赋值与以下等价:VAR = w$ o$ r$ d
从https://www.gnu.org/software/make/manual/html_node/Reference.html#Reference得知:
“在美元符号后跟着除美元符号、左圆括号或左花括号之外的字符会将该单个字符视为变量名称。”因此,$<space>
对是对名为单个空格字符的变量进行扩展。由于默认情况下未定义此变量,因此它将扩展为空字符串。
请注意,变量VAR
仍将包含$<space>
对,直到扩展为止。大多数情况下,这并不重要,但如果您的makefile依赖于使用$(value VAR)
来处理基础(未扩展)值,则上述技术可能会提供意想不到的结果。
另外,最近发布的GNU Make 4.3现在明确记录了这种分割行的技巧(https://www.gnu.org/software/make/manual/make.html#Splitting-Lines):
在不添加空格的情况下拆分
如果您需要拆分一行但不想添加任何空格,则可以利用一个微妙的技巧:将反斜杠/换行对替换为三个字符“美元符号/反斜杠/换行”:
var := one$\ word
在make命令去除反斜杠/换行并将下一行压缩成单个空格后,这相当于:
var := one$ word
然后make将执行变量扩展。变量引用'$'代表一个名字为“”(空格)的一字符变量,但是该变量不存在,因此扩展为一个空字符串,最终赋值相当于:
对于其他想法,请参见我在类似问题上的答案: 如何在没有空格的情况下在Makefile中将变量定义跨越多行? 关于行延续选项的更长讨论可在我的文章“GNU Make行延续”中找到: http://drmikehenry.com/gnu-make-line-continuations/var := oneword
$ \
对中被解释为$
之前。我知道Michael已经在Savannah上提交了一个错误报告,要求定义和支持这种行为。 - MadScientistfoo bar = biz
将会出错。但是你仍然可以通过间接方式来实现:如果 $s
扩展为一个空格,那么 foo$sbar = biz
将设置名为 foo bar
的变量。之所以禁止使用空格,是因为我们希望有自由地编写像 $(foo bar)
这样的内容,并且它们与引用名为 foo bar
的变量的含义不同。单个空格可以被特殊处理。它确实很好,可以在所有版本的 GNU make 中工作。但你必须承认,它感觉有点像一个 hack :). - MadScientist\
插入一个空格,$\
则不会。我见过将$(foo bar)
解释为$(call foo,bar)
的想法。消除call
只是一个小小的好处,比起拥有一种执行可读函数缩进的方法来说,这个好处要小得多,在我看来。此外,向后兼容性对我来说是必须具备的功能;我们几乎不能要求使用Make 3.81(现在已经12年了)。在我能够使用像$(foo bar)
这样的假设新功能之前,还需要十年时间 :-) - Michael Henry