给出一个makefile:
BigInteger
然后跑步,我得到:
# We force Make to execute commands, both for 'x' and for 'all'.
$(shell rm -rf x all)
# The "global" variable 'foo'
foo = global
# The target-specific variable 'foo', defined for target 'x'.
x : foo = target
all: x
@echo '$@: "$(foo)"'
x :
$(eval foo += 1)
@echo '$@: "$(foo)"'
如果仔细观察,我们在这里有两个名称为$ make
x: "target"
all: "target 1"
的不同变量:
foo
定义的特定于目标的变量。如您所见,变量x
已展开两次,首先是在目标foo
的上下文中,当然是指目标特定的变量,然后在目标x
的上下文中,它必须是全局变量,因为all
没有目标特定的变量{{1 }}
但是,全球 all
的值为foo
,那么它如何扩展为foo
?
更重要的是,对于目标global
,我们将值target 1
附加到变量(变量是什么?全局?目标特定一个?)。看起来,这个追加对特定于目标的变量没有任何影响,这在' x'的下一个命令行中很明显,其中{ {1}}已扩展为普通x
。此处不附加1
。
但是,通过这种推理,我们假设foo
目标的配方中的target
,引用了全局变量,因此它应该附加到现有的全局值,即1
,而不是特定于目标的变量eval
。
但是,在查看x
目标的扩展时,在执行目标global
的配方时,我们发现全局变量的值为{{ 1}},看起来像追加是在目标特定的变量上完成的。
这与先前的假设相矛盾,该假设基于目标target
的配方输出。
答案 0 :(得分:1)
对于我来说,在使用eval
和目标特定访问目标中的变量时,您必须考虑读取和编写操作环境。因此,对于目标中的eval
语句,似乎:
您可以通过这种方式重新分析代码:
# The global variable 'foo'
foo = global
# The target-specific variable 'foo', defined for target 'x'
x : foo = target
all: x
@echo '$@: "$(foo)"'
# ^
# global as there is no target-specific for 'all'
x :
$(eval foo = foo + 1)
# ^ ^
# write: global read: target-specific
@echo '$@: "$(foo)"'
# ^
# read: target-specific
最后,我们可以说:
x
目标x
目标更改。新值为<target-specific value> + 1
x
是all
的先决条件,全局变量将始终在运行all
目标最后,试试这个Makefile
:
foo = global
x: foo = x
y: foo = y
all: x y
@echo '$@: "$(foo)"'
x y:
$(eval foo += 1)
@echo '$@: "$(foo)"'
.PHONY: all x y
你会得到:
$ make
x: "x"
y: "y"
all: "y 1"
$ make y all
y: "y"
x: "x"
all: "x 1"