【问题标题】:How to do variadic macros with $(call ...) in GNU Make如何在 GNU Make 中使用 $(call ...) 做可变参数宏
【发布时间】:2012-08-28 23:22:10
【问题描述】:

我创建了一个宏以在 makefile 中使用,如下所示:

TODO_MSG = $(warning TODO: $(1))
$(call TODO_MSG, This part of the msg displays fine, but this part does not)

我可以通过以下方式解决它:

BLAH := $(shell perl -e 'print join( " ", 2..200 )'
COMMA := ,
TODO_MSG = $(warning TODO:$(1)$(strip $(foreach x,${BLAH},$(if $(${x}),${COMMA}$(${x}))))

...但我很好奇是否有任何东西为可变参数宏提供更明确的支持。

【问题讨论】:

    标签: macros gnu-make variadic-macros


    【解决方案1】:

    这是 Beta 解决方案的混音:

    TODO_MSG = $(warning TODO: $(1))
    
    test:
            $(call TODO_MSG, $(strip This part displays fine, and this does too))
    

    如果 Make 有一个 $(identity ...) 函数,我会使用它; $(strip ...) 是我能找到的最接近的。

    【讨论】:

    • 很好的解决方案。也可以使用$(if ,,A message, possibly with commas)
    【解决方案2】:

    这样可以吗?

    comma := ,
    
    #define TODO_MSG = $(warning TODO: $(1))
    TODO_MSG = $(warning TODO: $(1))
    $(call TODO_MSG, This part displays fine$(comma) and so does this)
    

    【讨论】:

    • 嗯,有点,但有点乏味。我希望有一个“神奇”变量,类似于您使用宏获得的 $(1), $(2) ... 变量,它可以自动让您访问整个参数列表,但我认为它不存在。
    • @BrianVandenberg:给它几天时间。这里有一些非常聪明的人。
    • A 认为这是最直接的解决方案。重要的一点是,其他不太熟悉您的代码的人在理解它时应该没有任何问题。
    【解决方案3】:

    正如我在 cmets 中提到的,@Beta's@claytontstanley's 的答案已经足够好了,我个人会使用他们的解决方案之一。

    如果您更喜欢获取可变参数的通用方式,那么以下内容可以帮助您。

    警告:下面有很多魔法和肮脏的黑客攻击。

    # 扩展为出现在 # 当前调用上下文。 参数 = \ $(评估 __arg_tmp := \ $(call __args_strip_tail,$(foreach __a,.1,$(__args_list))))$(__arg_tmp) # 非空参数引用的列表,例如$(1),,$(3),,, # Context: __a - 当前正在处理的参数的编码编号。 __args_list = \ $(if $(__arg_value),$(__arg_ref))$(foreach __a,$(call inc,$(__a)) \ ,$(if $(__arg_simple),$(comma)$(eval __arg_tmp := \ $(值 __args_list))$(__arg_tmp))) __arg_value = $(value $(call to_dec,$(__a))) __arg_ref = $${$(call to_dec,$(__a))} __arg_simple = $(findstring simple,$(flavor $(call to_dec,$(__a)))) # 用作 GNU Make 'call' 中的错误的解决方法。 # ${1},,${3},,, -> ${1},,${3} __args_strip_tail = $(subst } ,},$(call nolastword,$(subst },} ,$1,))) # 一些有用的东西... 逗号 := , nolastword = $(wordlist 2,$(words $1),x $1) # 将 .4.2 解码为 42 to_dec = $(subst .,,$1) # 增加给定的数字。 # 1. 数字之间有句点的小数:42 是 .4.2 公司=\ $(call __inc$(suffix .0$1),$(basename $1)) __inc.0 = $1.1 __inc.1 = $1.2 __inc.2 = $1.3 __inc.3 = $1.4 __inc.4 = $1.5 __inc.5 = $1.6 __inc.6 = $1.7 __inc.7 = $1.8 __inc.8 = 1.9 美元 __inc.9 = $(call inc,$1).0

    测试它:

    func = 使用 args 调用的 Func $0 [$(args)] foo = $(func) bar = $(调用函数,ar,baz,boo) $(警告 $(调用 foo,a1,a2,a3,a4)) $(警告 $(call bar,a1,a2,a3,a4))

    输出是:

    Makefile:49: Func foo called with args [a1,a2,a3,a4]
    Makefile:50: Func func called with args [ar,baz,boo]
    

    【讨论】:

    • 这太棒了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2016-10-23
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    相关资源
    最近更新 更多