转义 makefile 变量(供内部 makefile 使用)

Pri*_*NAI 5 variables makefile gnu-make

是否可以“安全地”扩展 makefile 中的变量,转义 makefile 认为特殊的所有字符?

例如,假设一个变量被用作目标:

${external_chaos}:
    dd if=/dev/zero of=${external_chaos}
Run Code Online (Sandbox Code Playgroud)

(例如故意的戏剧)

如果external_chaos包含空格、;#:,或其他 makefile 重要字符,那么整个规则就会混乱。

我想象的解决方案是一些应该执行此操作的 Make 内置函数,例如${escape external_chaos}(想象中的奢侈品)。

${value external_chaos} 不这样做。

Mad*_*ist 4

一般来说,使用带有空格的目标是不会成功的(没有巨大的痛苦,如果有的话)。放弃吧。如果您必须支持其中包含空格的目标,那么请选择不同的构建工具,而不是 make。

简短的回答是否定的,没有内置功能。您可以使用subst;自己编写一个 例如,在目标中,您至少需要逃脱%并且:

TESCAPE = $(subst :,\:,$(subst %,\%,$1))
Run Code Online (Sandbox Code Playgroud)

另一方面,请注意;,在目标中并不特殊,因此您根本不需要转义它们;事实上,如果你这样做,你会得到不正确的结果,因为\将留在目标名称中:反斜杠仅在引用特殊字符时才会被删除。

#当您定义变量时很特殊,但在扩展变量时则不然:此时解析器已经完成了对注释的查找。所以你必须写:

external_chaos = foo\#bar,biz;baz:boz%bin
Run Code Online (Sandbox Code Playgroud)

首先将 放入#变量中,但是一旦它存在,在使用变量时就不需要转义它。

下一个有趣的事情是,您需要针对目标和先决条件进行不同的转义。例如,在目标中你不能逃避;但在先决条件中你必须逃避;。所以你需要不同的宏:

PESCAPE = $(subst :,\:,$(subst ;,\;,$1))

TESCAPE = $(subst :,\:,$(subst %,\%,$1))

all: $(call PESCAPE,${external_chaos})

$(call TESCAPE,${external_chaos}): ; echo '$@'
Run Code Online (Sandbox Code Playgroud)

给出:

foo#bar,biz;baz:boz%bin
Run Code Online (Sandbox Code Playgroud)