我有一个类似于以下内容的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
有谁知道为什么会这样?
答案 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