【发布时间】:2015-05-19 20:54:32
【问题描述】:
这是一个我正在研究的更复杂的构建系统的简单示例。
T := 1
$T/foo.o: $T/foo.c
touch $T/foo.o # yes, I know I can use $@, this is an example
T := 2
$T/foo.o: $T/foo.c
touch $T/foo.o # yes, I know I can use $@, this is an example
(两种模式都在包含文件中定义,因此它们必须是相同的文本。)
这不起作用。虽然模式本身是正确创建的,使用名为1/foo.o: 1/foo.c 和2/foo.o: 2/foo.c 的规则,但配方本身在实际执行之前不会扩展$T;当然,此时$T 的值为 2,即使在第一个配方中也是如此。
我知道在定义配方的地方强制扩展变量的唯一方法是将整个模式放在一个多行变量中,然后用 $(eval)... 扩展它,这很奇怪。
我意识到这里的答案可能会是否,但是还有其他方法可以强制$T 在上述配方中内联扩展吗?
【问题讨论】:
-
您可以使用特定于目标的变量在解析时“捕获”变量来执行此类操作。请参阅我链接的问题。
-
特定于目标的变量非常危险;它们通过依赖树向下传播,这意味着如果通过多个顶级规则可以看到相同的依赖,并且这些顶级规则使用不同的目标特定变量,那么依赖看到的定义取决于 makefile 的执行顺序。这是未定义的。
-
啊! cmets 中的多线程竞争条件!
-
是的,除了直接 eval 和特定于目标的变量之外,我不确定您还有其他选择。 (至少这不像你在解析时写出并在配方时读取的特定于目标的 env 文件那样可怕的黑客攻击。)
标签: gnu-make