首页 > 解决方案 > GNU 制作特定于目标的变量,想要单个赋值,得到很多

问题描述

给定以下 GNU Makefile:

OBJS = a.o b.o

LIB = libX.a

$(LIB): $(OBJS)
    $(AR) cr $@ $^

$(LIB): CPPFLAGS = $(shell P)

当我构建时$(LIB),我可以看到外部程序 P 被调用了两次,每次构建一次a.ob.o我只是打印getpid()stderr)。

就我而言, P 将始终产生相同的结果,因此 P 要求创建每个.o. LIB当然可以由许多 .o 组成,而且问题更糟。

有没有办法让特定于目标的变量只被评估一次,即为目标评估,$(LIB)并且将 VALUE 逐字传递给先决条件配方(.ofrom .c)?还是我误解了他们的用法(我怀疑我是!)

通过反复试验,尝试了各种变量赋值语法,例如=and :=、 even 。::=一遍又一遍地阅读手册。

标签: makefilegnu

解决方案


有没有办法让特定于目标的变量只被评估一次,即为目标评估,$(LIB)并且将 VALUE 逐字传递给先决条件配方(.ofrom .c)?还是我误解了他们的用法(我怀疑我是!)

文档似乎没有指定何时以及如何设置目标特定变量以构建受影响目标的先决条件的确切语义。对于您想要的行为,您最好的选择是使用简单的变量赋值(:=::=),但您说这不起作用。 make似乎表现得好像变量赋值分别包含在每个先决条件的规则中,这是有道理的,因为一般来说,不能保证所有先决条件都会一个接一个地构建或紧邻主要目标之前构建,在它们不是一个接一个地构建的地方,变量必须在两者之间恢复其全局值。

真的,我想鼓励您尽量减少对 GNU 特定功能的使用make。它们中的每一个都是一种便利,而不是必需品,尽管偶尔,其中一些确实非常方便。您可以考虑改为部署 Autoconf +/- Automake 以(半)动态地将标志插入到您的 makefile 中。

但是,如果您必须$(shell)在您的 makefile 中使用,并且您想确定该命令每次make运行只执行一次,那么您最好的选择可能是在任何规则之外运行它。如果您不想修改全局 CPPFLAGS 则将结果存储在其他变量中:

OBJS = a.o b.o

LIB = libX.a
X_CPPFLAGS := $(shell P)

$(LIB): $(OBJS)
    $(AR) cr $@ $^

$(LIB): CPPFLAGS = $(X_CPPFLAGS)

推荐阅读