将私有库静态链接到公共库以隐藏符号

spa*_*ija 10 c++ static symbols collision

考虑以下:

  • 我正在用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,让我们说zlib.在我的开发中,我将依赖于zlib v1.2.3.4.5.rc6,因为我广泛且成功地使用并测试了它,如果我更改版本,我无法承担SDK测试/修复所需.
SDK将提供的所有静态或dinamically链接库必须隐藏第三方静态库.

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

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

谢谢.

更新
似乎我是这个问题的VENDOR2: 链接到库的多个版本
bstpierre的答案似乎是一个可行的解决方案,但我不确定它是否有效或是否可以在*nix以外的操作系统上重现.

Sco*_*nes 1

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

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