如何链接(或绕过)定义相同符号的两个第三方静态库
How can I link with (or work around) two third-party static libraries that define the same symbols?
我不是唯一一个遇到这种情况的人。
我有一个C++应用程序,它需要与SDK中的一个第三方和另一个静态库集链接。出于一些令人沮丧的原因,SDK将同一个第三方库的一个子集重新编译到了自己的(重命名的)库中,尽管符号本身的名称相同,并且没有封装在命名空间中。我的应用程序本身依赖于同一个第三方库。
我已经考虑了一些选择,但也许我错过了一些东西,希望新的外观能帮助我。也许我已经接近了,有人会知道其中一个的下一步行动。我将列举我所尝试的以及迄今为止每种解决方案的缺点:
-
与两者链接。我收到了大约2500行符号重新定义/大小更改警告和错误。这是我第一次发现他们定义了相同的符号。我现在正试图用g++重新编译OpenSSL,并将其放入命名空间。。。请参阅下面的编辑。。。
-
仅与SDK链接。我得到了我自己的代码所依赖的未定义符号——这是我发现他们对第三方lib的重新编译是一个子集,或者至少配置了一个禁用的模块。
-
仅与第三方库链接。SDK报告了几个未定义的符号,其中一个实际上是第三方库中头文件中的#define,因此第三方中的所有引用都解析为该定义,但外部的引用则不解析。我把它移到了c文件中,它解决了这个问题,但我仍然有两个未解析的函数,我在任何地方都找不到。这是我迄今为止最接近的一次。
-
从一个库和两个库中的链接中删除冲突的符号。到目前为止,这还没有奏效。这可能是SDK中静态链接的lib和我尝试使用的第三方lib版本之间的版本问题,但看起来有些函数是在符号之间移动的,所以通过删除符号,我无意中删除了其他地方需要的函数。SDK中符号中的函数与第三方库中符号中函数之间似乎没有完美的映射。在不需要手动调整地址的情况下剥离功能是否可行?
我一直在用检查libs中的符号
nm -C --defined-only lib<name>.a
并使用提取整个对象
ar -x lib<name>.a <objname>.o
希望这也能帮助那些不得不与相互冲突的第三方libs链接的其他人。为了便于说明,第三方库是OpenSSL,SDK是Opsec-libcpopenssl.a是Opsec中有问题的库。
**EDIT-一个后期可能的解决方法可能是用g++重新编译OpenSSL,并将整个内容放在命名空间中,然后链接两个库。我现在正在尝试。。。还有更多。。。
谷歌搜索表明SSL_get_peer_dh和dh_dup实际上是从libcpopenssl.A添加的,它们也不存在于我的OpenSSL副本中。因此,你真的必须将该库链接到中。在二进制级别将两个库混合在一起(上面的方法4)不太可能奏效——OpenSSL对其ABI非常挑剔(他们通常有.So文件版本,直到次要编号),所以你必须非常幸运地拥有一个.So文件,它与他们的.a文件兼容。
我的建议是方法4的变体,但在源代码级别:您将在Opsec libcpopenssl.a中有链接,因为它是OpenSSL的修改版本,包含额外的符号(可能还有其他修改),并从OpenSSL源代码中获取所需的额外函数,并使用libcpopenssl.a重新编译这些对象,这样他们就可以使用Opsec版本中的函数。如果您只使用一些libcpopenssl.a没有导出的OpenSSL函数,那么这是非常可行的。
当然,这仍然是一种繁琐的方法,但这是获得符号兼容性的一种有保证的方法,当然前提是Opsec SDK没有对OpenSSL进行语义更改,这将破坏您在项目中引入的额外OpenSSL功能。
(我是StackOverflow的新手,所以我不知道这个建议是否是一个合适的答案,但无论如何,我没有信誉点可以发表评论。如果不合适,我会删除它。)
如果你非常好奇,在最新版本的OpenSSL中,有249个文件被修改以进行编译。到目前为止,最常见的问题是大量的C风格指针类型转换,尤其是void*。现在,我在梦中看到了"reinterpret_cast"。
不过,这并不能单独解决问题——它仍然需要被完整地放置到一个命名空间中,这意味着要再次修改所有文件以及我自己对它的内部引用。我想我现在要把它传下去。
谢谢大家的帮助。
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 两个有符号数字之间的距离
- 为什么 Clang 和 GCC 中两个无符号整数之和的结果类型不同
- 如何安全地比较两个无符号整数计数器?
- 获取两个无符号整数 C++ 乘积的高 32 位的有效方法
- 如何以精度换取速度来评估C++中两个向量的点积符号?(不特定于硬件)
- 当两个共享库定义相同的符号时,实际会发生什么?
- 与两个符号链接.一个在存档文件中定义
- SSE2 内部函数 - 找到两个无符号短向量的最大值
- 加载具有相同符号的两个共享库时是否存在符号冲突
- 如何链接(或绕过)定义相同符号的两个第三方静态库
- 将两个字符安全转换为无符号短字符
- C++模需要在两个*无*符号字节之间进行减法转换才能工作,为什么
- C++:从两个符号之间提取字符串
- 在两个单独的 cpp 文件中定义的内联函数是否可以在链接期间创建重复的符号
- 链接两个具有相同函数签名的强函数符号的结果使用 G++ 以及原因
- 链接来自包含相同符号的不同项目的两个对象文件时发生C++链接器错误
- 在OpenCV中保持两个矩阵中具有最小绝对值的有符号值
- 条件反射为四种情况下的两个数字的符号
- C++:有符号64位整数中两个无符号64位的整数之差