rut*_*ike 26 c c++ linker openssl static-libraries
我不可能是唯一遇到这种情况的人.
我有一个C++应用程序需要链接到SDK中的一个第三方和另一个静态库集.出于某些令人沮丧的原因,SDK将相同的第三方库的子集重新编译为它们自己的(重命名的)lib,尽管这些符号本身的名称相同,并且它们未封装在命名空间中.我的应用程序本身依赖于相同的第三方库.
我考虑了一些选择,但也许我错过了一些东西,希望新面貌能帮到我.也许我很亲密,有人会知道其中一个的下一步.到目前为止,我将列举我尝试过的内容以及每个解决方案的缺点:
与两者联系.我得到大约2500行符号重新定义/大小更改警告和错误.这是我第一次发现他们定义了相同的符号.我正在尝试用g ++重新编译OpenSSL并将其放入命名空间...请参阅下面的编辑...
仅与SDK链接.我得到了我自己的代码所依赖的未定义符号 - 这是我发现他们重新编译第三方库是一个子集,或者至少配置了一个模块被禁用.
仅与第三方lib链接.我在SDK上报告了一些未定义的符号 - 其中一个实际上是第三方库中头文件中的#define,因此第三方lib中的所有引用都解析为定义,但外部引用却没有.我把它移到c文件中,这解决了这个问题,但是我仍然有两个我在任何地方都找不到的未解决的函数.这是我到目前为止最接近的.
从两个lib和链接中删除冲突的符号.到目前为止,这还没有奏效.它可能是SDK中静态链接的lib与我尝试使用第三方库的版本之间的版本问题,但看起来某些函数在符号之间移动,因此通过删除符号,我无意中删除了我在其他地方需要的功能.SDK中的符号中的函数与第三方lib中的符号中的函数之间似乎没有完美的映射.剥离功能而不必手动调整地址是否合理?
我一直在用libs检查符号:
nm -C --defined-only lib<name>.a
Run Code Online (Sandbox Code Playgroud)
并提取整个对象:
ar -x lib<name>.a <objname>.o
Run Code Online (Sandbox Code Playgroud)
希望这也将帮助那些不得不与彼此冲突的第三方库链接的其他人.为了具体细节,第三方lib是OpenSSL,SDK是Opsec - libcpopenssl.a是Opsec中令人讨厌的lib.
**编辑 - 可能的后期入口解决方法可能是使用g ++重新编译OpenSSL并将整个内容放在命名空间中,然后链接两个库.我现在正在尝试......更多来......
Google 搜索表明 SSL_get_peer_dh 和 DH_dup 实际上是 libcpopenssl.a 中的附加内容,并且它们也不存在于我的 OpenSSL 副本中。因此,您确实必须链接该库。在二进制级别将两个库混合在一起(上面的方法 4)不太可能起作用——OpenSSL 对它的 ABI 非常挑剔(它们通常将 .so 文件版本控制到次要版本号) )所以你必须非常幸运才能拥有一个与他们的 .a 文件 ABI 兼容的 .so 。
我的建议是方法 4 的变体,但在源代码级别:您将在 Opsec libcpopenssl.a 中有链接,因为它是 OpenSSL 的修改版本,其中包含额外的符号(以及可能的其他修改),并获取您需要的额外功能需要从 OpenSSL 源中获取并使用 libcpopenssl.a 重新编译这些对象,以便它们可以使用 Opsec 版本中的功能。如果您只使用一些未由 libcpopenssl.a 导出的 OpenSSL 函数,那么这是完全可行的。
诚然,这仍然是一种麻烦的方法,但它是获得符号兼容性的有保证的方法,当然前提是 Opsec SDK 没有对 OpenSSL 进行语义更改,从而破坏您拉入项目中的其他 OpenSSL 功能。
(我是 StackOverflow 的新人,所以我不知道这个建议是否符合正确答案,但无论如何,我没有声誉点来发表评论。如果不合适,我会删除它。)