gnu 将存档成员作为目标

gnu make Archive Members as Targets

我在使用 Archive Members as Targets 时遇到 GNU make 问题。问题是在某些机器上(例如 运行 MacOS、Solaris)它工作正常,即构建库,下一个 make 给出 Nothing to be done for 'all'.

但不在 Linux 框上 make 总是重建所有内容。在我使用 GNU Make 的所有机器上。

这里是一个源文件 foo.cMakefile

的示例

foo.c

void foo() {}

生成文件

all: libfoo.a

libfoo.a(%.o) : %.o
        $(AR) cr $@ $^

libfoo.a: libfoo.a(foo.o)
        ranlib libfoo.a

谁能证实一下? (或者告诉我我犯了什么明显的愚蠢错误......?)

运行 在 Solaris 上

theon$ make
gcc    -c -o foo.o foo.c
ar cr libfoo foo.o
ranlib libfoo
rm foo.o
theon$ make
make: Nothing to be done for 'all'.

运行 在 Linux

acker$ make
gcc    -c -o foo.o foo.c
ar cr libfoo foo.o
ranlib libfoo
rm foo.o
acker$ make
gcc    -c -o foo.o foo.c
ar cr libfoo foo.o
ranlib libfoo
rm foo.o

很可能不是你,而是你的 GNU/Linux 发行版很愚蠢,并且将“确定性模式”设置为 ar 的默认行为。这是 ar 程序的 configure-time 选项,用于确定它默认为“确定性”还是“non-deterministic”(ar 的历史和正确默认行为)。一些发行版做出了在他们的 ar 版本中设置此配置选项并更改默认行为的荒谬决定。

这会破坏 make(以及任何其他需要知道对象时间戳的工具)。

如果这是问题所在,您可以更改对 ar 的调用以添加 U 选项以再次关闭确定性模式:

ARFLAGS = crU

不幸的是,non-GNU 系统上的 ar 命令可能无法理解此选项,因此您需要找到一种方法来仅为使用 GNU binutils 的系统添加它。

您也可以随时就此事向您的 GNU/Linux 发行版投诉。