linux: ranlib 似乎没有向存档文件中添加任何新信息?

linux: ranlib doesn't seem to add any new information into an archive file?

ranlib 的手册页说:

说明 ranlib 生成存档内容的索引并将其存储在存档中。该索引列出了由作为可重定位目标文件的存档成员定义的每个符号。

好吧,我试着编译了一个存档文件,如下所示:

$ cat o.c
#include<stdio.h>
int f(){
  printf("hello\n");
  return 2;
}

gcc -o o.o -c o.c
ar rc libmyobject.a o.o
cp libmyobject.a libmyobject.a.keep
ranlib libmyobject.a

我尝试比较了 ranlib 前后的库文件大小,我得到:

-rw-rw-r-- 1 a a   1626 Oct  3 12:03 libmyobject.a.keep
-rw-rw-r-- 1 a a   1626 Oct  3 12:06 libmyobject.a

它们大小相同。这出乎我的意料。我希望 runlib 会将一些额外信息存储到 .a 文件中。但实际上,文件大小还是一样。

那么ranlib到底做了什么工作,如何查看ranlib做了什么工作呢? 谢谢

如果 binutils 是使用 --enable-deterministic-archives 编译的,那么默认情况下,在相同输入源上多次运行 ranlib 将产生相同的输出文件,因为它会取消时间戳、uid 和 gid 值。

你可以通过传递 -U 标志来强制它是非确定性的,这将导致时间戳、uid 和 gid 值的存储,并且由于时间戳已经改变,文件将不同:

$ ranlib -U libmyobject.a
$ diff libm*
Binary files libmyobject.a and libmyobject.a.keep differ

但是文件大小将保持不变。

$ ls -l libm*
-rw-r--r-- 1 xx xx 1618 Oct  3 13:58 libmyobject.a
-rw-r--r-- 1 xx xx 1618 Oct  3 13:58 libmyobject.a.keep

请记住,像这样的工具中的确定性实际上是非常可取的,因为它允许像 Reproducible Builds 这样的功能工作而无需在构建过程中添加卷积。

使用现代 GNU 工具,我不知道是否真的可以创建没有索引的存档。 ar 默认创建索引,我没有看到不创建索引的选项,也没有看到任何删除它的命令。

运行 ranlib 在您创建存档之后,您需要做的是让您的构建过程在更老的、更古怪的 UNIX 系统上运行。