【问题标题】:makefile use variable defined in target [duplicate]makefile使用目标中定义的变量[重复]
【发布时间】:2018-04-28 20:13:07
【问题描述】:

如何使用 make 目标中定义的变量

.PHONY: foo

VAR_GLOBAL=$(shell cat /tmp/global)

foo:
    echo "local" > /tmp/local
    VAR_LOCAL=$(shell cat /tmp/local)
    echo ${VAR_GLOBAL}
    echo ${VAR_LOCAL}

这里是执行输出:

$ echo global > /tmp/global
$ make foo
echo "local" > /tmp/local
VAR_LOCAL=local
echo global
global
echo

【问题讨论】:

  • 感谢@KelvinSherlock,你是对的,这是一个骗子。有趣的是,我之前发现它时忽略了它...感谢您的时间。
  • 查看该问题时,请使用第二个答案,它几乎在所有情况下都比公认的答案好。这是 SO 中的一种缺陷:有时一个不太好的答案被接受,然后一遍又一遍地提出来,对此无能为力,而且这种不太好的方法会传播到世界各地的 makefile :sad:.跨度>

标签: makefile


【解决方案1】:

正如@KelvinSherlock 指出的那样,这是another question 的副本

这是我的问题的具体解决方案:

.PHONY: foo

VAR_GLOBAL=$(shell cat /tmp/global)

foo:
    echo "local" > /tmp/local
    $(eval VAR_LOCAL := $(shell cat /tmp/local))
    echo ${VAR_GLOBAL}
    echo ${VAR_LOCAL}

【讨论】:

  • 这是不必要的复杂和奇怪的副作用。我建议使用带有反斜杠的单个命令行,如 Basile 的最后一个示例(尽管在该示例中不需要导出)或上面引用问题中的第二个答案。
  • 请原谅我的困惑,我知道这个例子非常愚蠢,但精神是将命令的结果放在一个变量中,然后再使用该变量。
  • “稍后”是指稍后在同一个食谱中,还是稍后在其他食谱中?这听起来仍然很危险。如果从不调用这个配方会发生什么?如果它总是被调用,那么为什么你首先需要在配方中设置变量?这听起来像是你在寻求一个你不需要的问题的解决方案。当然不能肯定。
  • @MadScientist 我明白是什么困扰着你,而且我知道在我给出的上下文中,我无法理解我为什么要做这样的事情以及为什么 eval 解决方案对我的问题有效,而不是其他解决方案.要添加一些上下文,我需要做的第一个操作是调用 cli 并在输出中收集一些信息。第二个命令使用后者并执行第二个 cli 命令。在执行第二个命令之前,我还对变量执行了test 以确保它已设置,否则它会失败。话虽如此,makefile 并不是我在这里做的事情的正确工具,但我必须遵守一些标准。
【解决方案2】:

您可能想在target-specific variable assignment 中使用override directive,所以试试:

foo: override LS_LOCAL=$(shell ls /var | tail -1)
    echo ${LS_GLOBAL}
    echo ${LS_LOCAL}

如果从未定义过LS_LOCAL(即使通过内置规则),您可能不需要override 关键字。

顺便说一句,您可以通过将wildcard function 与lastword function 结合使用(可能与notdir function 结合使用)来避免$(shell ls /var | tail -1),因此您可以使用$(lastword $(wildcard /var/*)) 或$(notdir $(lastword $(wildcard /var/*))) 来代替。但是,请注意扩展顺序以及带有空格的文件名。最后shell function 可能会使用你的$PATH variable(如果在/bin/ls 之前出现一些奇怪的ls 程序可能会发生奇怪的事情)。也许使用$(shell /bin/ls /var | /usr/bin/tail -1) 可能会更好。

还可以查看Guile-extended make;考虑使用其他build-automation 工具,例如ninja 和/或使用configure script 等通过autoconf 或cmake 生成的configure script 生成您的Makefile(或其他构建配置)。

还要注意,recipe 中的命令可以由多个物理反斜线组成(因此在 same shell 中执行)。也许你可以考虑类似

  export MY_VAR=$$(ls /var | tail); \
  dosomething; \
  use $$MY_VAR

在一些食谱里面。

【讨论】:

  • 您好,感谢您的好评。这让我意识到我的例子并没有反映我的现实。我修改了我的原始代码。重要的是 VAR_LOCAL 在目标中的某个点定义,而不是在开始时系统地定义,因为它的值会受到目标中其他操作的影响
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多