在" eval"中定义变量功能

时间:2015-08-21 07:16:05

标签: makefile gnu-make

给出一个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" 的不同变量:

  1. 全球一个。
  2. 为目标foo定义的特定于目标的变量。
  3. 如您所见,变量x已展开两次,首先是在目标foo的上下文中,当然是指目标特定的变量,然后在目标x的上下文中,它必须是全局变量,因为all没有目标特定的变量{{1 }}

    但是,全球 all的值为foo,那么它如何扩展为foo

    更重要的是,对于目标global,我们将值target 1附加到变量(变量是什么?全局目标特定一个?)。看起来,这个追加特定于目标的变量没有任何影响,这在' x'的下一个命令行中很明显,其中{ {1}}已扩展为普通x。此处不附加1

    但是,通过这种推理,我们假设foo目标的配方中的target,引用了全局变量,因此它应该附加到现有的全局值,即1,而不是特定于目标的变量eval

    但是,在查看x目标的扩展时,在执行目标global的配方时,我们发现全局变量的值为{{ 1}},看起来像追加是在目标特定的变量上完成的。

    这与先前的假设相矛盾,该假设基于目标target的配方输出。

1 个答案:

答案 0 :(得分:1)

对于我来说,在使用eval目标特定访问目标中的变量时,您必须考虑读取编写操作环境。因此,对于目标中的eval语句,似乎:

  • 读取对变量的访问权限请参阅目标特定的
  • 对变量的访问权,请参阅 global

您可以通过这种方式重新分析代码:

# 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
  • 由于xall的先决条件,全局变量将始终在运行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"