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

时间:2012-10-12 16:02:05

标签: 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符号的情况下将X链接到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: Linking with multiple versions of a library
bstpierre的答案似乎是一个可行的解决方案,但我不确定它是否有效,或者它是否可以在* nix以外的操作系统上重现。

1 个答案:

答案 0 :(得分:1)

我使用静态库多次出现此问题,最近一次使用MSVCRT。正如一位评论者指出的那样,使用单个可执行文件,One Definition Rule就会受到阻碍。除了修补二进制文件之外,我无法解决这个问题。而且你必须“深入”地执行此操作 - 捕获静态库Y(zlib)对其自己的外部链接对象所做的所有内部引用。

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