【问题标题】:standalone static library (.a) with cmake带有 cmake 的独立静态库 (.a)
【发布时间】:2011-05-02 09:52:15
【问题描述】:

我需要为 SDK 提供一个静态库。我们称之为“libsdk.a”。 这个库应该是独立的,这意味着一个简单的示例“example.cpp”可以在没有任何其他库的情况下链接它,除了系统库。

这是我的配置:

  • cmake 用于我所有的 10 个依赖库。为我的每个模块生成了一个静态库 (.a)。这些库仅包含给定模块的目标文件 .o。依赖树不是扁平的,其中一些依赖于其他。
  • 一个简单的例子“example.cpp”,带有一个可以编译和工作的cmake。在这个级别,cmakes 会生成一个非常复杂的链接命令来处理 deps 树。
  • boost 等外部依赖项(还有一些静态库)

目前,我尝试了这个:

  • 对生成的不同 .a 进行存档,但它不起作用,因为链接到这个库告诉我存档没有索引(即使在 ranlib 之后)。然而,我记得我可以毫无问题地在 .a 文件中添加 .a 库。
  • 从所有 *.a 文件中提取所有 .o 对象(使用 ar -x)文件,并用所有这些对象文件重新创建一个“libsdk.a”。它也不起作用(未解决的引用)。此外,它包括所有对象,甚至那些不需要的对象……我的工作示例需要 3.7M。这个库大约 35M。
  • 制作一个.so 共享库。它似乎有效,但我更喜欢拥有一个静态库。
  • 静态编译,但链接器抱怨它没有找到-lgcc_s。好的,我想在静态中编译,但不是那么远,只是我自己的库一起编译!

所以我的最后一个问题是:有什么方法可以生成包含所有其他库而不是系统库的静态库?

顺便说一句,另一个有趣的话题: Combining static libraries

感谢您为我打开思路的任何建议!

【问题讨论】:

  • 你可以随意在 .a 文件中添加 .a 库,因为ar 只是一个“归档器”。喜欢tar 或 zip 或 arj。它对库一无所知,因此无法告诉您创建的东西不是有效的库。
  • “提取所有 .o 并将它们打包在一起”应该是正确的方法(并且链接器应该只能从库中选择那些需要的对象)。我不知道为什么它不为你链接。至于二进制的大小,不就是把所有代码都拉进去,因为库里的文件太依赖了,反正大部分都拉进去了?

标签: c++ linux cmake static-linking


【解决方案1】:

您尝试手动执行的是链接器的工作。虽然可行,但您不应该为此烦恼。

当您编译@​​987654321@ 时,请确保它的所有依赖项都是静态链接的。如果你这样做,libsdk.a 应该是独立的。静态链接意味着将代码复制到最终可执行文件中的正确位置,因此静态链接的任何内容都不需要在外部文件中提供。

【讨论】:

  • 您好 Tamás,谢谢。是的,我知道,但我不能肯定地承认链接器可以编译我的示例,并且我不能生成具有相同符号的静态库。恐怕如果我静态编译所有中间对象,那么最好的情况是符号冗余,最坏的情况是符号的多个定义,这将阻止我进行示例链接。无论如何,我会继续调查
  • 链接器应该处理冗余(并且只选择需要的对象)。您应该发布更具体的信息(例如您的 cmake 脚本或 cmake 生成的 makefile),以便我们为您提供帮助。
【解决方案2】:

this post on CMake mailing list。附加到消息的 libutils.cmake 具有完成这项工作的 MERGE_STATIC_LIBS() 宏。在 Linux(以及除 OSX 之外的所有其他 Unix)上,它使用 ar 来打包和解压缩对象文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-14
    • 2022-07-14
    • 1970-01-01
    • 2014-01-06
    • 2020-05-24
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    相关资源
    最近更新 更多