Macros 在宏中定义变量

Macros 在宏中定义变量,macros,makefile,Macros,Makefile,如何在GNU make宏中定义变量?我使用的是GNU Make 4.0,每当我赋值时,变量为空: define TEST_MACRO $(info $(1)) test_var := $(1) $(info $(test_var)) endef $(call TEST_MACRO,test) 产出: test (blank line) 我尝试过使用递归扩展进行赋值,但得到了相同的结果。您没有提到使用哪个版本的Make,而且在宏的处理方面,不同版本之间存在细微的差异。

如何在GNU make宏中定义变量?我使用的是GNU Make 4.0,每当我赋值时,变量为空:

define TEST_MACRO
    $(info $(1))
    test_var := $(1)
    $(info $(test_var))
endef

$(call TEST_MACRO,test)
产出:

test
(blank line)

我尝试过使用递归扩展进行赋值,但得到了相同的结果。

您没有提到使用哪个版本的Make,而且在宏的处理方面,不同版本之间存在细微的差异。但这对我来说是可行的(使用GNUMake 3.81):


您没有提到正在使用哪个版本的Make,而且在处理宏方面,不同版本之间存在细微的差异。但这对我来说是可行的(使用GNUMake 3.81):


我最终选择了这样的方式,因为我觉得双
$
太乱了

define TEST_MACRO
   $(info B $(test_var))
endef

# Note test_var was defined after TEST_MACRO
test_var := test

$(eval $(value TEST_MACRO))
这样做的缺点是您无法设置
$1..$n
变量,但更易于阅读


编辑-在宏内部定义变量的更好示例。上面的示例演示了如何将值传递到宏中,就像使用
call

define TEST_MACRO
    test_var := test

    $(info B $(test_var))
endef

我最终选择了这样的方式,因为我觉得双
$
太乱了

define TEST_MACRO
   $(info B $(test_var))
endef

# Note test_var was defined after TEST_MACRO
test_var := test

$(eval $(value TEST_MACRO))
这样做的缺点是您无法设置
$1..$n
变量,但更易于阅读


编辑-在宏内部定义变量的更好示例。上面的示例演示了如何将值传递到宏中,就像使用
call

define TEST_MACRO
    test_var := test

    $(info B $(test_var))
endef

我正在使用GNU Make 4.0,我已经用这些信息更新了这个问题。我试过了,它很有效,你能解释一下为什么我必须逃避和评估任何不直接使用参数的东西吗?@Lerp:我不愿意承认,但我不确定为什么这些东西是必要的;它们只是起作用。必须这样做的原因是make会将值扩展两倍。首先,
$(call…
函数将展开
TEST\u宏
。然后,
$(eval…
函数将展开
$(call…)
函数的结果。您可以通过将
eval
函数替换为
info
来了解这一点。这将向您显示
调用
函数的结果,
eval
将对其进行计算。两种方法都试一下,看看有什么不同。没有额外的转义,
info
函数通过
call
进行扩展,在变量由
eval
设置之前@madscient:这非常有意义,以至于我无法理解我是如何理解的。我正在使用GNU Make 4.0,我已经用这些信息更新了问题。我试过了,它成功了,你能解释一下为什么我必须逃避和评估任何不直接使用论点的东西吗?@Lerp:我不愿意承认,但我不确定为什么这些东西是必要的;它们只是起作用。必须这样做的原因是make会将值扩展两倍。首先,
$(call…
函数将展开
TEST\u宏
。然后,
$(eval…
函数将展开
$(call…)
函数的结果。您可以通过将
eval
函数替换为
info
来了解这一点。这将向您显示
调用
函数的结果,
eval
将对其进行计算。两种方法都试一下,看看有什么不同。在没有额外转义的情况下,
info
函数通过
call
进行扩展,然后由
eval
设置变量@madcascient:这非常有意义,以至于我无法理解为什么我无法理解它。我不明白。您最初的请求是在宏中定义一个变量:这根本不可能做到这一点?!我假设您在
(值…
)之前漏掉了
$
,但即使如此,这也是一种令人困惑的编写
$(信息B$(测试变量))的方法
…为什么要费心于
eval
value
?我也希望能够在宏内部定义变量,上面确实允许我这样做,而不必加倍
$
,因为这会让人非常困惑,特别是对于更大的宏,这正是我要做的。我将添加一个更好的示例。我不明白。Y我们最初的要求是在宏中定义一个变量:这根本不可能做到?!我假设您在
(value…
)之前遗漏了
$
,但即使如此,这也是一种令人困惑的编写
$(info B$(test\u var))的方法
…为什么要费心于
eval
value
?我也希望能够在宏内部定义变量,上面确实允许我这样做,而不必加倍
$
,因为这会让人非常困惑,特别是对于更大的宏,这正是我要做的。我将添加一个更好的示例。