.a .o 和 .lo 文件之间的区别
Posted
技术标签:
【中文标题】.a .o 和 .lo 文件之间的区别【英文标题】:Difference between .a .o and .lo file 【发布时间】:2011-08-19 05:36:58 【问题描述】:C语言中.a
.o
和.lo
文件有什么区别?
【问题讨论】:
【参考方案1】:.o、.a、.lo 和 .so 之间的区别。
执行摘要
.o 通常是编译器发出的非 PIC 目标文件(在链接器阶段之前)当与 exe 链接时,代码将包含在可执行文件中——我们在链接时绑定。李> .a 通常是一个存档库,包含一个或多个 .o 文件 [非 PIC]。当与 exe 链接时,存档中的特定“*.o”文件将被插入到可执行文件中。 .lo 通常是一个“库对象”,其中包含使用 gcc -fPIC 手动编译或使用 libtool 编译的 PIC 代码。 .so 文件是“共享对象”文件。它们包含 PIC 对象。注意:
如果您需要静态可执行文件,请使用“.o”和“.a”文件。 如果您需要/希望动态可执行文件在运行时与库绑定,请使用 .lo 和 .so 文件。简介
虽然我喜欢上面的答案,但它们不包括 .a/archive 库表单。因此,在这里我将通过添加 .so 库格式来解决所有这三个问题。此外,在 stackexchange 的脉络中,我将使用更多文本以防链接损坏(请注意,我不需要此链接的参考链接)。
文件类型 .o
当编译一个 .o 文件是一个包含编译器为目标平台发出的目标代码的目标文件。创建 .o 文件:
gcc -c filename.c <==== creates filename.o
请注意,此示例未创建位置无关代码 (PIC)。我们认为这是一个可能包含在静态库或可执行文件中的对象。也就是说,当我们将可执行文件与 .o 文件链接时,.o 文件中的代码会插入到可执行文件中——它是在构建时绑定的,而不是在运行时绑定的。这意味着可执行文件可以在不包含 .o 文件的情况下重新分发。警告:按照惯例,.o 文件被视为非 PIC。我们通常使用 .lo 扩展名来命名 PIC 对象文件。
文件类型 .a
.a 文件类型是一个“archive”库。它包含一个或多个 .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
显示档案库的内容
$ ar t libmyStuff.a
a.o
b.o
c.o
文件类型 .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.
另请注意,.libs 子目录是用 a.o 创建的。这个文件是 PIC 代码,尽管有名字。 Libtool 将此文件移动到当前目录并将扩展名更改为 .lo。
您可以随时手动创建 .lo 文件,只需在编译时使用 gcc 的 PIC 选项即可。将生成的 .o 文件移动到 .lo 扩展名。
文件类型.so
按照惯例,.so 意味着一个“共享对象”库文件。我们将 PIC 对象文件放入共享库中。在与 .o 和 .a 文件的合同中,当我们与 .so 文件链接时,代码不会包含在生成的编译文件中。那就是我们使用运行时绑定(如 .lo 的情况)。运行时绑定的形式不止一种,但我们不会在这里讨论。
【讨论】:
是否有一本书涵盖了您在回答中解释的信息类型?我只能找到有用的实用信息,例如您在论坛中的帖子等。这些知识是零散的,从未作为程序构建和运行方式的连贯报道来呈现。 不。 *.lo 文件是人类可读的纯文本文件,其中包含 pic 对象和 non_pic 对象的名称。 PIC 代码通常在.libs/a.o
中,而非PIC 代码在a.o
中。所以 libtool 创建了 3 个文件:2 个目标文件 (.o
),一个 PIC 和一个非 + .lo
描述文件位置的文件。
@wandadars:查看 John R. Levine 的“链接器和加载器”linker.iecc.com
这是一个质量更高的答案,应该被接受。【参考方案2】:
The '.lo' file is a library object,可以内置到共享库中,'.o'文件是标准目标文件
The .lo file is the libtool object,Libtool 使用它来确定可以将哪些目标文件构建到共享库中
【讨论】:
这是否意味着 .o 文件不能构建到共享库中? @Raj Kumar - ***.com/questions/2583770/… 您真的希望所有答案都以链接的形式出现吗? @Raj 不,它没有,命名是方便,而不是要求。【参考方案3】:.lo
文件是库对象,可以内置到共享库中,.o
文件是标准对象文件。更多信息:How to install and use libtool shared library (.lo files)?
【讨论】:
这是否意味着 .o 文件不能构建到共享库中? 最重要的技术区别是 .lo 文件应该包含可重定位代码(GCC 中的 -fPIC),而 .o 文件可能不包含。以上是关于.a .o 和 .lo 文件之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
C++学习(三八三).o .a .so .la .lo的区别
O(n) 和 O(log(n)) 之间的区别 - 哪个更好,O(log(n)) 到底是啥?
Object o = makeMeAnObjectPlease(); 之间的区别和对象 o = new Object();