Makefile:执行作为参数传递的内置函数以调用
Makefile: Executing builtin function passed as a parameter to call
我正在编写以下 Makefile:
CHECK = $( )
$(info $(call CHECK,dir,a/b/c))
stop:
并在 GNU Make 4.3 中作为 make
不带参数执行它。我在输出中期望的是 a/b/
但我得到的是空行。
我的实际问题是如何 pass/get/use 其他宏中的内置函数来使那些传递的函数起作用?这可能吗?
注意:实际的 Makefile 稍微复杂一些,但这个简短的示例演示了这个想法。我知道我可能只写 $(dir a/b/c)
但这不是我想要的。
UPD: 我的实际用例如下。我有一个在模板管道(具有 %
)规则中处理的文件列表。其中一些文件的名称中有空格,为了正确解释它们的名称,我使用了以下技巧:
ESCAPE_IN_SHELL = sed -E 's,_,_1,g;s, ,_2,g'
ESCAPE = $(subst $() ,_2,$(subst _,_1,))
UNESCAPE = $(subst _1,_,$(subst _2, ,))
MAP = $(foreach A,,$(call ,$A))
# Names acquisition
NAMES != ls in_dir | ${ESCAPE_IN_SHELL}
trans_dir/% : in_dir/%
mkdir -p $(dir $@)
...
out_dir/% : trans_dir/%
...
main_rule : $(call MAP,UNESCAPE,${NAMES})
问题在于 mkdir -p $(dir $@)
恰恰在于 $@
在包含空格时如何被 $(dir ...)
解释。我要做的是将 $(dir $@)
替换为
$(call UNESCAPE,$(dir $(call ESCAPE,$@)))
但我发现可以通过创建像这样的附加函数来概括和缩短解决方案:
SAFE = $(call UNESCAPE,$( $(call ESCAPE,)))
应该像$(call SAFE,dir,$@)
一样使用。在这里,我遇到了 dir
没有按预期扩展的问题。
我没有阅读问题的所有细节,但如果 call
函数的文档对此非常清楚:
If variable is the name of a built-in function, the built-in function is always invoked (even if a make variable by that name also exists).
所以如果你想调用一个函数,包括内置函数,你不能使用:
CHECK = $( )
你必须使用:
CHECK = $(call ,)
我正在编写以下 Makefile:
CHECK = $( )
$(info $(call CHECK,dir,a/b/c))
stop:
并在 GNU Make 4.3 中作为 make
不带参数执行它。我在输出中期望的是 a/b/
但我得到的是空行。
我的实际问题是如何 pass/get/use 其他宏中的内置函数来使那些传递的函数起作用?这可能吗?
注意:实际的 Makefile 稍微复杂一些,但这个简短的示例演示了这个想法。我知道我可能只写 $(dir a/b/c)
但这不是我想要的。
UPD: 我的实际用例如下。我有一个在模板管道(具有 %
)规则中处理的文件列表。其中一些文件的名称中有空格,为了正确解释它们的名称,我使用了以下技巧:
ESCAPE_IN_SHELL = sed -E 's,_,_1,g;s, ,_2,g'
ESCAPE = $(subst $() ,_2,$(subst _,_1,))
UNESCAPE = $(subst _1,_,$(subst _2, ,))
MAP = $(foreach A,,$(call ,$A))
# Names acquisition
NAMES != ls in_dir | ${ESCAPE_IN_SHELL}
trans_dir/% : in_dir/%
mkdir -p $(dir $@)
...
out_dir/% : trans_dir/%
...
main_rule : $(call MAP,UNESCAPE,${NAMES})
问题在于 mkdir -p $(dir $@)
恰恰在于 $@
在包含空格时如何被 $(dir ...)
解释。我要做的是将 $(dir $@)
替换为
$(call UNESCAPE,$(dir $(call ESCAPE,$@)))
但我发现可以通过创建像这样的附加函数来概括和缩短解决方案:
SAFE = $(call UNESCAPE,$( $(call ESCAPE,)))
应该像$(call SAFE,dir,$@)
一样使用。在这里,我遇到了 dir
没有按预期扩展的问题。
我没有阅读问题的所有细节,但如果 call
函数的文档对此非常清楚:
If variable is the name of a built-in function, the built-in function is always invoked (even if a make variable by that name also exists).
所以如果你想调用一个函数,包括内置函数,你不能使用:
CHECK = $( )
你必须使用:
CHECK = $(call ,)