转义 makefile 变量(供内部 makefile 使用)
Escaping makefile variables (for internal makefile use)
是否可以"safely"扩展 makefile 中的变量,转义 makefile 认为特殊的所有字符?
举个例子,假设一个变量被用作目标:
${external_chaos}:
dd if=/dev/zero of=${external_chaos}
(例子中的戏剧故意)
如果 external_chaos
包含空格、;
、#
、:
、,
或其他 makefile 重要字符,则整个规则得到搞砸了。
我想象的解决方案是一些应该执行此操作的 Make 内置函数,例如 ${escape external_chaos}
(想象中的奢侈)。
${value external_chaos}
不做。
一般来说,使用带有空格的目标是不会成功的(如果有的话,没有巨大的痛苦)。放弃吧。如果您必须支持其中包含空格的目标,请选择其他构建工具,而不是 make。
简短的回答是否定的,没有内置功能。您可以使用 subst
自己编写一个;例如,在目标中,您至少需要转义 %
和 :
:
TESCAPE = $(subst :,\:,$(subst %,\%,))
另一方面,请注意 ;
和 ,
在目标中并不特殊,因此您根本不需要转义它们;事实上,如果你这样做,你会得到不正确的结果,因为 \
将留在目标名称中:只有在引用特殊字符时才会删除反斜杠。
#
在 define 变量时是特殊的,但在 expanded 变量时不是:解析器已经那时已经完成了对评论的查找。所以你必须写:
external_chaos = foo\#bar,biz;baz:boz%bin
首先将 #
放入变量中,但是一旦它在那里,您就不需要在使用变量时将其转义。
下一个有趣的事情是你需要针对目标和先决条件进行不同的转义。因此,例如,在目标中你必须不转义;
,但在先决条件中你必须转义;
。所以你需要不同的宏:
PESCAPE = $(subst :,\:,$(subst ;,\;,))
TESCAPE = $(subst :,\:,$(subst %,\%,))
all: $(call PESCAPE,${external_chaos})
$(call TESCAPE,${external_chaos}): ; echo '$@'
给出:
foo#bar,biz;baz:boz%bin
是否可以"safely"扩展 makefile 中的变量,转义 makefile 认为特殊的所有字符?
举个例子,假设一个变量被用作目标:
${external_chaos}:
dd if=/dev/zero of=${external_chaos}
(例子中的戏剧故意)
如果 external_chaos
包含空格、;
、#
、:
、,
或其他 makefile 重要字符,则整个规则得到搞砸了。
我想象的解决方案是一些应该执行此操作的 Make 内置函数,例如 ${escape external_chaos}
(想象中的奢侈)。
${value external_chaos}
不做。
一般来说,使用带有空格的目标是不会成功的(如果有的话,没有巨大的痛苦)。放弃吧。如果您必须支持其中包含空格的目标,请选择其他构建工具,而不是 make。
简短的回答是否定的,没有内置功能。您可以使用 subst
自己编写一个;例如,在目标中,您至少需要转义 %
和 :
:
TESCAPE = $(subst :,\:,$(subst %,\%,))
另一方面,请注意 ;
和 ,
在目标中并不特殊,因此您根本不需要转义它们;事实上,如果你这样做,你会得到不正确的结果,因为 \
将留在目标名称中:只有在引用特殊字符时才会删除反斜杠。
#
在 define 变量时是特殊的,但在 expanded 变量时不是:解析器已经那时已经完成了对评论的查找。所以你必须写:
external_chaos = foo\#bar,biz;baz:boz%bin
首先将 #
放入变量中,但是一旦它在那里,您就不需要在使用变量时将其转义。
下一个有趣的事情是你需要针对目标和先决条件进行不同的转义。因此,例如,在目标中你必须不转义;
,但在先决条件中你必须转义;
。所以你需要不同的宏:
PESCAPE = $(subst :,\:,$(subst ;,\;,))
TESCAPE = $(subst :,\:,$(subst %,\%,))
all: $(call PESCAPE,${external_chaos})
$(call TESCAPE,${external_chaos}): ; echo '$@'
给出:
foo#bar,biz;baz:boz%bin