【问题标题】:Why create a .a file from .o for static linking?为什么要从 .o 创建一个 .a 文件用于静态链接?
【发布时间】:2010-12-23 14:26:47
【问题描述】:

考虑这段代码:

one.c:

#include <stdio.h>

int one() {
   printf("one!\n");
   return 1;
}

两个.c:

#include <stdio.h>

int two() {
   printf("two!\n");
   return 2;
}

prog.c

#include <stdio.h>

int one();
int two();

int main(int argc, char *argv[]) 
{
   one();
   two();

   return 0;
}

我想将这些程序链接在一起。所以我这样做:

gcc -c -o one.o one.c
gcc -c -o two.o two.c
gcc -o a.out prog.c one.o two.o

这很好用。

或者我可以创建一个静态库:

ar rcs libone.a one.o
ar rcs libtwo.a two.o
gcc prog.c libone.a libtwo.a
gcc -L. prog.c -lone -ltwo

所以我的问题是:我为什么要使用第二个版本——我创建“.a”文件的那个版本——而不是链接我的“.o”文件?它们似乎都是静态链接的,那么它们之间是否存在优势或架构差异?

【问题讨论】:

    标签: c linux gcc static-linking


    【解决方案1】:

    每当我被问到这个问题时(我的团队中的新人),“为什么(或者有时甚至是'什么是')a .a?”,我使用以下使用 .zip 作为类比的答案。

    “dotAy 就像您在构建 exe/lib 时要链接的所有 dotOhs 的 zip 文件。节省磁盘空间,而且无需键入所有相关 dotOhs 的名称。”

    到目前为止,这似乎让他们明白了。 ;)

    【讨论】:

      【解决方案2】:

      不同之处在于可执行文件的大小,尽管可能不适用于您的示例。

      链接到库时,仅包含可执行文件使用的位。链接目标文件时,您将获取全部内容。

      例如,如果您的可执行文件必须包含数学库中的每个数学函数,而您只使用一个,那么它会比它需要的大得多,并且包含大量未使用的代码。

      将这与 Windows 的动态链接模型进行对比很有趣。在那里,操作系统必须完全加载可执行文件使用的所有 Dll(动态链接库),这可能导致 RAM 膨胀。这种模型的优点是您的可执行文件本身较小,并且链接的 Dll 可能已经在其他可执行文件使用的内存中,因此不需要再次加载它们。

      在静态链接中,库函数为每个可执行文件单独加载。

      【讨论】:

        【解决方案3】:

        通常,库是可以在多个程序中使用的目标文件的集合。

        在您的示例中没有优势,但您可能已经这样做了:

        ar rcs liboneandtwo.a one.o two.o
        

        那么链接你的程序就变得更简单了:

        gcc -L. prog.c -loneandtwo
        

        这真的是一个包装问题。您是否有一组目标文件,这些目标文件自然形成了一组可以在多个程序中重用的相关功能?如果是这样,那么它们可以明智地归档到静态库中,否则可能没有任何优势。

        最后的链接步骤有一个重要区别。您链接的任何目标文件都将包含在最终程序中。仅当库中的目标文件有助于解析其他目标文件中的任何未定义符号时,它们才会包含在内。如果不这样做,它们将不会链接到最终的可执行文件中。

        【讨论】:

          【解决方案4】:

          您可以将一组文件放入存档 (.a) 文件中以供以后重复使用。标准库就是一个很好的例子。

          有时将大型项目组织到库中是有意义的。

          【讨论】:

            【解决方案5】:

            主要优点是当您必须链接时,您可以只指定一个库而不是所有单独的目标文件。管理文件还有一个小优势,可以处理一个库而不是一堆目标文件。有时,这也显着节省了磁盘空间,但目前的硬盘价格使这一点变得不那么重要了。

            【讨论】:

              【解决方案6】:

              从技术上讲,结果是完全一样的。通常,您会为实用程序函数创建库,因此您不必向链接器提供数十个目标文件,而只需链接该库即可。

              顺便说一句,创建一个仅包含一个 .o 文件的 .a 文件绝对没有意义。

              【讨论】:

              • 结果通常非常不同。在这个人为的例子中,它恰好是相同的。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-06-07
              • 2012-12-23
              • 1970-01-01
              • 2023-03-21
              • 1970-01-01
              • 2013-07-07
              相关资源
              最近更新 更多