为什么我的Makefile的目标特定变量被设置为所有目标?

时间:2013-12-19 06:12:16

标签: variables makefile

我有一个类似于以下内容的Makefile:

target1: DEFAULT_VALUE ?= $(shell bash -c 'read -p "Enter DEFAULT_VALUE to set: " value && echo $$value')

target2:
    echo "Hello"

target1:
    echo "World"

我希望设置DEFAULT_VALUE的代码只会在我运行make target1时执行,但我发现即使我运行make target2

也会运行

有谁知道为什么会这样?

2 个答案:

答案 0 :(得分:0)

你的“类似”makefile不够相似。上面的示例对我来说很好:如果我运行make target2,则不会执行shell命令。如果我运行make target1,那就是。

请在发布之前检查您的示例,并提供一个确实失败的示例。

我怀疑在你的真实环境中,target2表示的任何内容都是target1代表的任何先决条件,这意味着target2将继承所有target1特定于目标的变量赋值。

答案 1 :(得分:0)

使用上面的Makefile,对于任何目标,shell命令将从不运行。这是因为该变量样式是一个递归扩展变量,所以每次变量使用时它都会被展开(并运行shell命令)。

如果您将Makefile中的最后一个操作更改为

target1:
        echo $(DEFAULT_VALUE)
        echo $(DEFAULT_VALUE)

然后当你make target1时它会运行TWICE,可能会回应两个不同的东西

如果您希望shell命令只运行一次,则需要使用:=进行设置。但是如果你这样做,它将在读取Makefile时运行(在它甚至考虑构建哪些目标之前),因此无论你最终指定哪个目标,它都会运行。

如果您想要只在构建给定目标时运行的东西,则需要将其放在该目标的操作中。最简单的方法是使用递归调用

target1:
        read -p "Enter DEFAULT_VALUE to set: " value && \
        $(MAKE) real_target1 DEFAULT_VALUE=$$value