uDu*_*ude 79

.o,.a,.lo和.so之间的区别.

执行摘要

  • .o通常是编译器发出的非PIC对象文件(在链接器阶段之前)当与exe链接时,代码将包含在可执行文件中 - 我们在链接时绑定.
  • .a通常是包含一个或多个.o文件[non-PIC] 的归档库.与exe链接时,存档中的特定"*.o"文件将插入到可执行文件中.
  • .lo通常是一个"库对象",包含PIC代码,无论是使用gcc -fPIC还是使用libtool手动编译.
  • .so文件是"共享对象"文件.它们包含PIC对象.

注意:

  • 如果您需要静态可执行文件,请使用".o"和".a"文件.
  • 如果您需要/希望动态可执行文件在运行时与库绑定,请使用.lo.so文件.

介绍

虽然我喜欢上面的答案,但它们不包括.a/archive库表单.所以在这里我将解决所有这三个问题,并加入.so库格式.另外,在stackexchange的静脉中,我将使用更多的文本以防链接被破坏(注意我不需要这个链接的引用链接).

文件类型.o

编译.o文件时,是包含目标平台的编译器发出的目标代码的目标文件.要创建.o文件:

gcc -c filename.c     <==== creates filename.o
Run Code Online (Sandbox Code Playgroud)

请注意,此示例未创建位置无关代码(PIC).我们认为这是一个可能包含在静态库或可执行文件中的对象.也就是说,当我们将可执行文件与.o文件链接时,.o文件中的代码将插入到可执行文件中 - 它在构建时绑定,而不是在运行时绑定.这意味着可以重新分发可执行文件而不包含.o文件.警告:通常认为.o文件是非PIC的.我们通常使用.lo扩展名来命名PIC对象文件.

文件类型.a

.A文件类型是" 存档 "库.它包含一个或多个.o文件,通常用于创建静态可执行文件.

我们使用ar命令来操作归档库.下面是一个例子,(1)从.o文件创建一个存档库,然后(2)列出一个文件的内容.

创建库

$ ls *.o
a.o  b.o  c.o                 <=== the files going in the archive

$ ar q libmyStuff.a *.o       <=== put *.o files in an archive (or new one)
ar: creating libmyStuff.a    

$ ls *.a                      <=== just show the library created
libmyStuff.a
Run Code Online (Sandbox Code Playgroud)

显示存档库的内容

$ ar t libmyStuff.a
a.o
b.o
c.o
Run Code Online (Sandbox Code Playgroud)

文件类型.lo

.lo的使用是一种常用于位置无关的目标文件的约定.在当前目录中, libtool compile命令创建.lo文件和.o文件,一个具有PIC代码,另一个没有PIC代码.见下面的输出:

$ libtool compile gcc -c a.c
libtool: compile:  gcc -c a.c  -fPIC -DPIC -o .libs/a.o  <== PIC code
libtool: compile:  gcc -c a.c -o a.o >/dev/null 2>&1     <== Not-PIC code

$ ls a.lo a.o
a.lo  a.o       <=== a.lo contains the PIC code.
Run Code Online (Sandbox Code Playgroud)

另请注意,.libs子目录是使用ao创建的.这个文件是PIC代码,尽管名称. Libtool将此文件移动到当前目录并将扩展名更改为.lo.

您可以在编译时使用PIC选项简单地手动创建.lo文件.将生成的.o文件移动到.lo扩展名.

文件类型.so

按照惯例.so意味着"共享对象"库文件.我们将PIC对象文件放入共享库中.在.o.a文件的合同中,当我们链接.so文件时,代码不包含在生成的编译文件中.那就是我们使用运行时绑定(如.lo情况).有多种形式的运行时绑定,但我们不会在此处讨论.

  • 是否有一本书涵盖了您在答案中解释的信息类型?我只能在论坛等中找到有用的实用信息,例如你的帖子.这些知识是碎片化的,从未作为对程序如何构建和运行的一致报道. (3认同)
  • @wandadars:查看 John R. Levine 的“链接器和加载器”https://linker.iecc.com/ (2认同)

Dum*_*der 37

'.lo'文件是一个库对象,可以内置到共享库中,'.o'文件是标准目标文件

.lo文件是libtool对象,Libtool使用它来确定可以在共享库中构建哪个对象文件

  • 你真的希望你的所有答案都以链接的形式出现吗? (4认同)
  • 这是否意味着.o文件不能构建到共享库中? (3认同)