什么是ranlib?


13

我使用MacOSX系统已有一段时间了,但是直到最近才开始涉足这一领域。我找到了一个指南,告诉我运行“ sudo ranlib /usr/local/lib/libjpeg.a”(安装libjpeg)。我已经阅读了ranlib手册,并尝试在线对其进行查找。我根本听不懂。我需要查找哪些资源以了解更多信息,或者有人可以对其使用进行简要说明?提前致谢!

Answers:


7

ranlib静态库中添加或更新目标文件。链接器在链接时可以使用静态库,以提供代码才能运行所需的符号(与加载程序在运行可执行文件时在动态库中寻找它们相反)。


您好Ignacio,感谢您的回复。这是否意味着如果我在库上执行ranlib,则链接器每次尝试“引用”它时都可以使用它吗?如何删除?
2012年

ranlib用于创建和修改库。通常通过在命令行中传递库的位置和/或名称来由链接器使用。有关详细信息,请参见gcc 的-L-l参数。
伊格纳西奥·巴斯克斯

5
但这不是ar吗?有什么不同?
greatwolf

18

该描述看起来很清楚:http : //sourceware.org/binutils/docs/binutils/ranlib.html

因此,如果您归档目标文件的集合,请说:

$ ar r fruits.a apple.o orange.o pineapple.o

然后跑步

$ ranlib fruits.a

创建一个fruits.a内容的索引,并将索引存储在fruits.a中。这对于链接以及对象之间相互调用很有用。


“ ranlib生成对档案内容的索引,并将其存储在档案中”。这听起来更像是要结合的东西tar,我想说的不是很清楚。
编码

9

ranlib生成指向档案内容的索引,并将其存储在档案中。索引列出了由可重定位目标文件的归档成员定义的每个符号。具有这种索引的存档可以加快链接到库的速度,并允许库中的例程相互调用,而无需考虑它们在存档中的位置。

资料来源:ranlib手册页


2

AR

在Linux中,ar是GNU通用归档程序。(ar在其他类似Unix的操作系统中有非GNU变体)。带有选项c

ar c... archive-name file...

它会创建一个包含的副本的存档file...。该archive-name传统,但不一定具有扩展.a(用于存档)。每个file...文件可以是任何类型的文件,而不必是目标文件。

当归档的文件都是目标文件时,通常打算使用归档将所选的目标文件传递到程序或DSO(动态共享对象)的链接中。在这种情况下,archive-name通常还会给定前缀lib,例如 libfoo.a,以便可以通过链接器选项将其发现为候选链接器输入文件-lfoo

用作链接器输入文件,libfoo.a通常称为静态库。这种用法对于不熟练的程序员来说是一个长期的困惑源,因为它使他们认为存档libfoo.a与DSO libfoo.so(通常称为动态/共享库)与DSO大致相同,并且在此基础上建立了错误的期望。实际上,“静态库”和“动态库”根本不相似,它们以完全不同的方式用于链接。

一个明显的区别是,静态库不是由链接程序生成的,而是由链接程序生成的ar。因此,不会发生链接,也不会发生符号解析。归档的目标文件保持不变:它们只是放在一个袋子里。

当存档是在东西联动输入通过链接器生成-如程序或DSO -链接程序会在袋子,看看是否有任何目标文件,对于已计提未解决的符号引用提供的定义在链接的早期。如果找到,就从包里取出这些目标文件和链接它们到输出文件,就好像他们是在命令行连接单独命名,并在所有的档案没有提及。因此,归档文件在链接中的全部作用是作为目标文件包,链接程序可以从中选择进行链接所需的文件。

默认情况下,GNU ar使输出档案准备好用作链接器输入。它将带有伪造假名文件名​​的伪造“文件”添加到存档中,并且在该伪造文件中,它写入链接程序能够从存档中任何对象文件定义的全局符号中作为查找表读取的内容这些对象文件在归档中的名称和位置。该查找表使链接器可以在存档中查找并标识任何对象文件,这些对象文件定义了已获取的任何未解析的符号引用。

您可以使用q(= quick)选项(实际上是您在自己的ar示例中使用的)以及(capital)S(= no symbol table)选项禁止创建或更新此查找表。而且,如果ar出于任何原因调用创建或更新没有符号表(最新的)的归档文件,则可以给该文件一个s选项。

兰利布

ranlib根本不创建库。在Linux中,ranlib是一个遗留程序,ar如果没有,它将向归档文件中添加(最新)符号表。它的效果ar s与GNU 完全相同ar。从历史上看,在ar能够自动生成符号表之前,ranlib是将魔术幻象文件注入到存档文件中以使链接程序从其中选择目标文件的库尔德人。在非GNU类Unix操作系统中,ranlib可能仍需要为此目的。你的例子:

ar qc libgraphics.a *.o
ranlib libgraphics.a

说:

  • libgraphics.a通过将*.o当前目录中的所有文件(没有符号表)附加到存档中来创建。
  • 然后将符号表添加到 libgraphics.a

在linux中,其净效果与:

ar cr libgraphics.a *.o

本身ar qc libgraphics.a *.o创建了一个链接器无法使用的档案,因为它没有符号表。

ld

你的例子:

ld -r -o libgraphics.a *.o

实际上是非常非传统的。这说明相当罕见使用的连接器ld以产生合并通过连接多个输入文件到一个输出目标文件,其中符号解析已经完成目标文件,只要是可能给定的输入文件。所述-r(= 重定位选项指示所述接头通过链接输入尽可能而不是如果未定义的符号引用保持在输出文件中失败的linkaqe以产生一个对象文件目标(而不是节目,或DSO)。这种用法称为部分链接

的输出文件ld -r ... 是目标文件,而不是 ar 归档文件,并且指定看起来ar归档文件的输出文件名不会使它成为文件名。因此,您的示例说明了一种欺骗。这个:

ld -r -o graphics.o *.o

会是真实的。我不清楚这种欺骗的目的是什么,因为即使ELF对象文件被调用libgraphics.a,并通过该名称或通过-lgraphics链接输入到链接,链接器也会正确地将其标识为ELF对象文件。而不是ar档案,它将像在命令行中使用任何目标文件一样使用它:它无条件地将其链接到输出文件,而输入真正档案的目的是仅在引用档案成员的情况下链接档案成员。也许您在这里仅是一个信息不灵通的示例。

包起来...

实际上,我们只看到了一种生成某些东西的方法,通常将其称为,这就是所谓的静态库的生成,方法是将一些目标文件存档并将符号表放入存档中。

而且,我们还没有看到如何产生通常称为的另一种最重要的东西,即动态共享对象/共享库/动态库。

像程序一样,链接器会生成DSO 。程序和DSO是ELF二进制程序的变体,OS加载程序可以理解这些变体,并且可以使用它们来组装正在运行的进程。通常我们通过一个GCC前端的一个(调用链接gccg++gfortran,等):

链接程序:

gcc -o prog file.o ... -Ldir ... -lfoo ...

链接DSO:

gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...

-lfoo当您链接某些其他程序或DSO时,可以通过统一协议将共享库和静态库都提供给链接器。该选项指示链接程序扫描其指定的或默认的搜索目录以查找 libfoo.solibfoo.a。默认情况下,一旦找到其中一个,它将把该文件输入到链接中;如果在同一个搜索目录中找到两个文件,它将首选libfoo.so。如果libfoo.so选择,则链接器会将DSO添加到您正在制作的任何程序或DSO的运行时依赖项列表中。如果libfoo.a选择,则链接器使用归档文件作为目标文件的选择,以便在需要时直接链接到输出文件。不依赖于运行时 libfoo.a本身是可能的;无法将其映射到流程中;这对OS加载程序没有任何意义。

https://stackoverflow.com/a/47924864/195787复制。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.