Variables 转义makefile变量(用于内部makefile使用)
是否可以“安全”展开makefile中的变量,转义makefile认为特殊的所有字符 例如,假设变量用作目标:Variables 转义makefile变量(用于内部makefile使用),variables,makefile,gnu-make,Variables,Makefile,Gnu Make,是否可以“安全”展开makefile中的变量,转义makefile认为特殊的所有字符 例如,假设变量用作目标: ${external_chaos}: dd if=/dev/zero of=${external_chaos} (示例中的戏剧) 如果external_chaos包含空格,、#、:、、或其他makefile有效字符,则整个规则都会混乱 我设想的解决方案是一些应该实现这一点的Make内置函数,例如${escape external\u chaos}(想象的奢华) ${value
${external_chaos}:
dd if=/dev/zero of=${external_chaos}
(示例中的戏剧)
如果external_chaos
包含空格,
、#
、:
、、
或其他makefile有效字符,则整个规则都会混乱
我设想的解决方案是一些应该实现这一点的Make内置函数,例如${escape external\u chaos}
(想象的奢华)
${value external\u chaos}
不能做到这一点。一般来说,使用带有空格的目标是不会成功的(如果没有痛苦的话)。放弃吧。如果必须支持包含空格的目标,请选择其他生成工具,而不是make
简单的回答是不,没有内置的功能。您可以使用subst
自己编写一个;例如,在目标中,您需要至少转义%
和:
:
TESCAPE = $(subst :,\:,$(subst %,\%,$1))
另一方面,请注意
和,
在目标中不是特别的,所以你根本不需要逃避它们;事实上,如果您这样做,您将得到不正确的结果,因为\
将保留在目标名称中:反斜杠只有在引用特殊字符时才会被删除
#
在定义变量时是特殊的,但在展开变量时则不特殊:此时解析器已经完成了对注释的查找。所以你必须写:
external_chaos = foo\#bar,biz;baz:boz%bin
首先要将#
放入变量中,但一旦它存在,就不需要在使用变量时转义它
下一个有趣的事情是,您需要针对目标和先决条件进行不同的转义。例如,在一个目标中,你不能逃避代码>,但在先决条件中必须转义代码>。因此,您需要不同的宏:
PESCAPE = $(subst :,\:,$(subst ;,\;,$1))
TESCAPE = $(subst :,\:,$(subst %,\%,$1))
all: $(call PESCAPE,${external_chaos})
$(call TESCAPE,${external_chaos}): ; echo '$@'
给出:
foo#bar,biz;baz:boz%bin
那%
呢?或者这属于空间疼痛的范畴吗?是的,你也必须逃离%
。我没有试图想出所有可能的特殊字符,只是使用了问题中的字符。处理%
和冒号一样,没什么大不了的。恼人的是,不同的字符需要在不同的上下文中转义:例如,在目标上下文中,您不想转义代码>,但在先决条件上下文中必须转义代码>。我将更新答案。是否有任何原因说明转义不适用于空格字符?我刚刚编写的一个快速测试似乎很好:ESCAPE=$(subst${onespace},\${onespace},${1})
,其中onespace:=${nullstr}空格在这里
和nullstr:=
,v123:=一两个三个
,${call ESCAPE,${v123}}:
被调用为使“一两个三个”
(非常抱歉评论中包含这么多代码)。请尝试使用$(@D)
或$(@F)
)或任何其他make函数。尝试编写一个配方,打印规则的先决条件(使用$^
),在名称中保留空格(例如,每行打印一个先决条件,或使用“ls”)列出文件等等——将它们传递给链接器是一样的)。我应该说,如果(a)你愿意在所有目标和先决条件中转义空格,(b)你愿意在食谱中永远不使用任何可能扩展到多个单词的make自动变量,你就可以做到这一点(因此没有$^
,$?
,$+
等)和(c)您不愿意对任何可能包含空格分隔词的变量使用任何make函数,包括$(@F)
(这只是$(notdir$@)的缩写)
)等等。哦,你必须用适当的引用来写你自己的规则,不要使用make的任何内置规则。这至少是你必须要做的。