Linker ranlib、ar和ld在创建库方面有什么区别
为了从*.o文件生成c++/unix中的库,我注意到在我的项目中有两种不同的方法(遗留代码): 及 这两种方法的区别是什么?使用哪种方法的目的是什么?ar 在Linux中,是GNU通用归档程序。 (在其他类似Unix的操作系统中,存在Linker ranlib、ar和ld在创建库方面有什么区别,linker,ld,unix-ar,Linker,Ld,Unix Ar,为了从*.o文件生成c++/unix中的库,我注意到在我的项目中有两种不同的方法(遗留代码): 及 这两种方法的区别是什么?使用哪种方法的目的是什么?ar 在Linux中,是GNU通用归档程序。 (在其他类似Unix的操作系统中,存在ar的非GNU变体)。使用选项c ar c... archive-name file... 它创建一个包含文件…副本的存档。存档名称按惯例 但不一定有扩展名.a(用于存档)。每个文件…可能是 任何类型的文件,不一定是对象文件 当归档文件都是目标文件时,通常打算使用
ar
的非GNU变体)。使用选项c
ar c... archive-name file...
它创建一个包含文件…
副本的存档。存档名称
按惯例
但不一定有扩展名.a
(用于存档)。每个文件…
可能是
任何类型的文件,不一定是对象文件
当归档文件都是目标文件时,通常打算使用
用于将选定的目标文件传递到程序链接中的存档
或DSO(动态共享对象)。在这种情况下,archive name
通常也会被赋予前缀lib
,例如。
libfoo.a
,以便可以通过链接器选项-lfoo
将其作为候选链接器输入文件进行查找
用作链接器输入文件,libfoo.a
通常称为静态库。这
对于不熟练的程序员来说,用法永远是一个困惑的根源,因为它会导致他们困惑
想一想归档文件libfoo.a
与DSO是同一种东西,libfoo.so
,
通常称为动态/共享库,并在此基础上建立错误的期望
基础。事实上,“静态库”和“动态库”根本不相似
并且以完全不同的方式在链接中使用
一个明显的区别是静态库不是由链接器生成的,
但是通过ar
。因此,不会发生链接,也不会发生符号解析。存档的
对象文件是不变的:它们只是放在一个袋子里
当一个归档文件被输入到由
链接器-如程序或DSO-链接器查看包中是否有
其中是否有为未解析符号引用提供定义的任何对象文件
这些都是在早期的联系中积累起来的。如果找到任何对象文件,它将从中提取这些对象文件
该包并将它们链接到输出文件中,就像它们被单独命名一样
在链接器命令行和存档中根本没有提到。那么整个
链接中的归档文件的角色是链接器可以从中访问的对象文件包
选择需要进行联动的部件
默认情况下,GNUar
使其输出档案准备好用作链接器输入。它添加了一个虚假的“文件”
到归档文件中,使用一个神奇的假文件名,并在这个假文件中写入
链接器能够从定义的全局符号中读取查找表
将存档中的任何对象文件复制到这些对象的名称和位置
档案中的文件。此查找表使链接器能够查找
存档并标识定义任何未解析符号引用的任何对象文件
它已经控制住了
您可以使用q
(=
快速)选项-事实上您已经在自己的ar
示例中使用了该选项,并且
使用(大写)S
(=无符号表)选项。如果您调用ar
来创建或更新
由于任何原因没有(最新)符号表的存档,那么您
可以使用s
选项为其设置一个
ranlib
没有
创建所有的库。在Linux中,ranlib
是一个传统程序,它添加了一个(最新的)
将符号表添加到ar
存档(如果没有)。它的效果正是
与ar s
相同,带有GNUar
。历史上,在配备ar生成
一个符号表本身,ranlib
就是注入这个神奇虚假文件的乱码
进入存档,以使链接器能够从中拾取对象文件。非GNU
与Unix类似的操作系统,ranlib
可能仍然需要用于此目的。你的例子是:
ar qc libgraphics.a *.o
ranlib libgraphics.a
ld -r -o libgraphics.a *.o
说:
- 创建
,方法是将当前数据库中的所有libgraphics.a
文件附加到存档文件中 目录,没有符号表*.o
- 然后将符号表添加到
libgraphics.a
ar cr libgraphics.a *.o
ar qc libgraphics.a*.o本身创建了一个链接器
无法使用,因为它没有符号表
ld
你的例子是:
ar qc libgraphics.a *.o
ranlib libgraphics.a
ld -r -o libgraphics.a *.o
这实际上是非常不正统的。这说明了链接器的使用非常罕见,
ld
,通过将多个输入文件链接到
单个输出对象文件,其中符号解析已尽可能完成,
给定输入文件。选择权
指示链接器通过以下方式生成对象文件目标(而不是程序或DSO)
尽可能地链接输入,如果未定义符号引用,则不要使linkaqe失败
保留在输出文件中。这种用法称为部分链接
ld-r…
的输出文件是一个对象文件,而不是ar
归档文件,并且
指定一个类似于ar
归档文件的输出文件名并不能使其成为归档文件。
所以你的例子说明了一个骗局。这:
ld -r -o graphics.o *.o
这是真实的。我不清楚这种欺骗的目的是什么,
因为即使ELF对象文件被称为libgraphics.a
,并通过该名称输入到链接,
或者通过-lgraphics
,链接器将正确地将其标识为ELF对象文件,而不是ar
存档,并将使用
它使用命令行中任何对象文件的方式:无条件链接它
输入到输出文件中,而输入真实存档的点是
gcc -o prog file.o ... -Ldir ... -lfoo ...
gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...