【问题标题】:How to create a static library which includes another static library如何创建包含另一个静态库的静态库
【发布时间】:2021-02-26 21:59:39
【问题描述】:

我有一个名为 testlib.pro(使用 Qtcreator)的 C++ 项目,它将创建一个静态库 libtest.a。

该项目还包括staticlib.a(示例)和staticlib1.a。即使用其他静态库即时创建一个静态库。创建静态库后,我创建 C 包装器 (testApi.c) 以使用使用静态库的 C++ 代码。我正在使用以下选项编译 testApi.c

gcc -o demo testApi.c -L ./testlib -ltest

但它给出了链接器错误,表明它需要我用来链接 libtest.a 的静态库。所以我用下面的注释重新编译程序,它工作正常

gcc -o demo testApi.c -L ./testlib -ltest -lstatuclib -lstaticlib1

我的理解是,如果我将 libtest.a 发送到另一台机器并尝试编译 testApi.c 文件,它可能需要该机器中的 staticlib.a 和 staticlib1.a。但我只想使用新创建的静态库 libtest.a。我错过了什么吗?

注意:我在 testlib.pro 中使用 -l 选项包含了 staticlib.a、staticlib1.a

【问题讨论】:

  • 请记住,静态库只不过是目标文件的存档。因此,可以从“其他”静态库中提取目标文件,并将它们添加到您自己的库中。并不是说我真的推荐它。

标签: c++ c gcc makefile qt-creator


【解决方案1】:

静态库的概念本质上是过时的。当一个程序有很多模块时,有时不可能将它们全部放在命令行中以便链接器将它们添加到程序中。此外,对于库,作为所有包含在最终可执行文件中的.o 模块,必须有某种机制允许链接器仅选择所需的模块,而不是将它们全部包含在最终可执行文件或可执行文件中会增长很多,包括程序不会使用的模块。这两件事都通过引入动态共享对象解决了,因此使用 .a 文件在今天有些过时,它仅用于静态链接程序。

无论如何,在链接器中选择目标模块的算法不是递归的,因此当它打开.a 库以搜索要包含在最终可执行文件中的依赖文件时,它只搜索.o(和可能是.so,但我还没有测试过),它会忽略它在那里找到的任何.a 文件。许多系统在存档中包含一个索引文件,该文件在提供的标识符和提供它们的模块的名称之间具有映射,因此编译器只需一次就知道需要提取哪些存档对象。如果文件中包含库(具有自己的索引),则应附加(并重建)该索引文件,因此这证明在库搜索中根本不使用递归。

解决这个问题的方法是链接所有你需要制作最终可执行文件的库,或者正如你已经被告知的,提取库中的.o 文件并将它们放入另一个库中。还有第三种解决方案,即:链接器允许您指定一个具有选项的文件(并且您可以指定库名称,以及您希望它扫描的 .o 文件),它将读取该文件以检查集合您希望它扫描的库。

另一点是链接器从不包含这样的库。库只是一个存档(如.tar.zip 文件),链接器在其中探索和提取它需要的文件,因此根本不需要递归搜索算法。库中的存档文件和存档中的相同文件之间没有区别。

【讨论】:

    【解决方案2】:

    如果您的库使用其他静态库,那么它们也需要在链接时提供。

    有一个丑陋的方法(在 Linux 上)。您可以解压缩现有的静态库(或其中的几个)并将它们重新打包到一个新库中。因此,如果您觉得特别活泼,您可以解压缩您所依赖的那些库,然后将它们的内容与您自己的东西一起打包到一个新库中。丑陋,令人困惑,可能会导致各种其他问题,但如果这是你想要的方式......

    【讨论】:

    • 这种丑陋的方式恰好是 libtool 所做的,所以如果你学会了如何使用 libtool 并使用 libtool 构建静态库,libtool 将为你做所有这些讨厌的事情。
    • @SamVarshavchik 你确定 libtool 能做到吗?那么 libtool *.la 文件的 dependency_libs 条目是干什么用的?
    • 它们是 libtool(脚本)用来完成所有这些工作的工具。
    • @SamVarshavchik 我不认为这是真的,从我可以看到 libtool 在链接器阶段读取这些 *.la 文件,并将这些依赖项添加到链接器命令。静态库本身没有被修改。
    • @ssbssa - 随意引导以下 Makefile.am:pastebin.com/1ti5eUEz - 重复此实验,然后解释 world.o 如何在没有 libtool 执行我所说的操作的情况下进入 libhello.a .
    猜你喜欢
    • 2022-01-04
    • 2011-12-24
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2021-07-29
    • 2017-01-03
    • 1970-01-01
    相关资源
    最近更新 更多