【问题标题】:Variable assignment issue in multiline macro in GNU MakefileGNU Makefile 中多行宏中的变量赋值问题
【发布时间】:2014-04-27 23:53:26
【问题描述】:

我知道这是一个简单的问题,但我找不到原因/解决方案。我在 Makefile 中定义了一个简单的 shell 函数,如下所示,

define my_function
    my_var="Hello";
    echo $(my_var);
    echo Recvd arg = $(1);
endef

请注意,这是在 makefile 中定义的,我在我的规则之一中使用,

 $(obj_dir)/%.o: $(src_base)/%.cpp 
 $(q)$(CXX) $(CXXFLAGS) -o $@ 
 $(call my_function, $@) 

但是局部变量 my_var 永远不会被赋值。我使用 eval、set 和 export 尝试了很多东西,但似乎没有为函数中的变量赋值。并且 echo $(my_var) 不会打印任何内容。这在 shell 脚本中工作正常,但在 Makefile 中使用时,会导致此问题。

请帮我解决这个问题。帮助将不胜感激。

【问题讨论】:

  • 您没有提供足够的信息。您究竟是如何使用$(call my_function...) 的?它在食谱里面吗?或不?请提供您使用调用函数的完整上下文。
  • 调用在我的构建规则之一内。这样, $(obj_dir)/%.o: $(src_base)/%.cpp $(q)$(CXX) $(CXXFLAGS) -o $@ $(call my_function, $@) 我已经验证了这个函数是被正确调用,但里面的操作,即变量赋值不起作用。
  • 问题描述已更新。请看一看。

标签: makefile gnu-make


【解决方案1】:

Make 将在单独的 shell 中调用配方的每个逻辑行。所以对于类似的东西:

foo:
        echo line1
        echo line2

这会启动两个不同的 shell,一个运行第一个 echo,另一个运行第二个(实际上 make 有一些性能增强,因此如果命令“足够简单”,它可以避免启动 shell,但行为是两种方式都一样)。

所以如果你在一行写一个变量然后在另一行使用它,当shell退出时该值将丢失:

foo:
        foo=bar
        echo $$foo

什么都不打印。为了使用多条物理行但使用单个逻辑行,您必须以反斜杠/换行符组合结束每条物理行:make 将收集它们并将它们发送到单个 shell:

foo:
        foo=bar; \
        echo $$foo

将打印“bar”。

即使在多行变量赋值中也是如此。此外,当您想要引用 shell 变量时,您必须使用 $$(就像我在上面所做的那样)。使用单个 $ 将通过该名称引用 make 变量。并且 shell 变量引用不支持括号(但如果需要,您可以使用花括号)。所以你必须写:

define my_function
    my_var="Hello"; \
    echo $$my_var; \
    echo Recvd arg = $(1);
endef

【讨论】:

  • 提示:如果您的宏只使用 shell 变量(而不使用 make 变量),您可以使用$(value …) 宏来节省每个$ 加倍。 [同样地,如果你将一堆东西传递给$(eval …)。]
【解决方案2】:

我对 MadScientist 的回答没有什么要补充的,但这是:如果您不介意稍长的行,您还可以将多个 shell 命令放在一行中,用分号分隔:

define my_function
    my_var="Hello"; echo $$my_var; echo Recvd arg = $(1)
endef

【讨论】:

    猜你喜欢
    • 2017-06-12
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多