【问题标题】:Difference between .a .o and .lo file.a .o 和 .lo 文件之间的区别
【发布时间】:2011-08-19 05:36:58
【问题描述】:

C语言中.a.o.lo文件有什么区别?

【问题讨论】:

    标签: c++ c shared-libraries libraries


    【解决方案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 不,它没有,命名是方便,而不是要求。
    【解决方案3】:

    .lo文件是库对象,可以内置到共享库中,.o文件是标准对象文件。更多信息:How to install and use libtool shared library (.lo files)?

    【讨论】:

    • 这是否意味着 .o 文件不能构建到共享库中?
    • 最重要的技术区别是 .lo 文件应该包含可重定位代码(GCC 中的 -fPIC),而 .o 文件可能不包含。
    猜你喜欢
    • 2012-05-15
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2014-07-16
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多