【问题标题】:Statically link a private library into a public one to hide symbols [closed]将私有库静态链接到公共库以隐藏符号[关闭]
【发布时间】:2012-10-12 16:02:04
【问题描述】:

考虑以下几点:

  • 我正在用 C++ 开发一个静态库 X,它在内部使用著名的静态库 Y v2.0;
  • 我只想分发一个库 X',即 X 与 Y 静态链接/合并以供其内部使用;
  • 开发人员希望在其可执行文件中使用 X';
  • 另外,他需要 Y v1.0(不像我那样需要 v2.0);
  • Y v1.0 和 v2.0 有一些共同的符号,其中一些共同的符号也表现不同。

我开发 X 时严格要求将 Y v2.0 用于某些内部业务。这就是说我无论如何都不能恢复到 Y v1.0。
另一方面,开发者使用 Y v1.0 也有类似的限制。

正如您已经争论的那样,问题是:如何在不导出 Y 符号的情况下将 Y 链接到 X 中以避免冲突? Y 已经很成熟了,可能我不想修改它的源代码或构建设置(如果公开可用的话)。

为了把更多的东西放到地球上,我正在设计一个 SDK,它肯定需要一些 3rd 方库,比如说 zlib。 在我的开发中,我将依赖 zlib v1.2.3.4.5.rc6,因为我广泛且成功地使用和测试了它,如果我更改版本,我负担不起所需的 SDK 测试/修复。
SDK 将提供的所有静态或动态链接库都必须隐藏第 3 方静态库。

潜在客户可能会遇到类似的限制(他需要 zlib v7.8.9),那么如何避免符号冲突?同样,可能无需更改原始源代码(命名空间等)。

更复杂的是,SDK 是多平台的,这意味着我需要不同的方法来解决问题,具体取决于平台(Windows、Linux、Mac OS、iOS、Android...)和使用的编译器(例如 MSVC++和 g++)。

谢谢。

更新
看来我是这个问题的 VENDOR2: Linking with multiple versions of a library
bstpierre 的回答似乎是一个可行的解决方案,但我不确定它是否有效,或者它是否可以在 *nix 以外的操作系统上重现。

【问题讨论】:

  • (匿名)命名空间,也许?
  • 这是我想避免的,即修改第 3 方库的源代码(假设我可以访问它)。
  • windows, linux, os x, ios, android...代码几乎完全独立于平台,如果出现平台相关的东西,它将为所有支持的操作系统实现。跨度>
  • 尝试 "attribute ((visibility("default")))" 为您的库 X 的公共函数,并在使用 g++ 编译时使用 "g++ -fvisibility=hidden test .cpp -o 测试”。
  • 如果您与外部链接的名称发生冲突,并考虑到您的限制(不要以任何方式修改代码,不要做与平台相关的事情),那么它只是 One Definition Rule违规。

标签: c++ static symbols collision


【解决方案1】:

我在使用静态库时遇到过很多次这个问题,最近一次是使用 MSVCRT。正如一位评论者指出的那样,对于单个可执行文件,单一定义规则会成为障碍。除了修补二进制文件,我真的没有办法解决这个问题。而且您必须“深入”地执行此操作-捕获静态库 Y (zlib) 对其自己的外部链接对象所做的所有内部引用。

在这种情况下,我建议使用动态库(DLL 或 SO)。它将增加一些部署复杂性。但它提供了一个可执行的“防火墙”,允许同名的全局对象驻留在每个二进制文件中而不会发生冲突。即便如此,如果应用程序和 DLL 都具有冲突的第三方依赖项,它可能会造成问题。不过,这可能是最好的选择。

【讨论】:

    猜你喜欢
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2015-10-08
    • 1970-01-01
    • 2021-07-28
    相关资源
    最近更新 更多