发布我的 *.so文件时,应使用哪个版本的glibc
Which version of glibc should be used when release my *.so file?
我正在研究一个支持SSL连接和传输的共享库。我想将其发布为 *.so文件。在使用G 4.8.2的Ubuntu14.04(64位桌面)中对其进行了编译后,它无法在Centos5.8中使用。
第一轮
我将共享库与以下命令进行编译:
g++ -v -shared -Wl,-soname,libmyssl.so.1,-o libmyssl.so.1.0 myssl.o -lz -lssl -lcrypto
i使用命令 objdump -p libmyssl.so.1.0 |需要知道它取决于以下库:
NEEDED libz.so.1
NEEDED libssl.so.1.0.0
NEEDED libcrypto.so.1.0.0
NEEDED libstdc++.so.6
NEEDED libc.so.6
然后我写一个演示以使用libmyssl.so.1.0。
g++ -D UNIX64 -o ssldemo ssldemo.cpp ./libmyssl.so.1.0 -lz -lssl -lcrypto
- 我在ubuntu14.04(同一版本)中编译了演示,它可以正常工作。
- 我在CentOS(OpenSSL 0.9.8e)中编译了演示,它链接到失败的,因为无效的OpenSSL版本
第二轮
我删除了" -lz lssl -lcrypto",因此命令如下
g++ -v -shared -Wl,-soname,libmyssl.so.1,-o libmyssl.so.1.0 myssl.o
i使用命令 objdump -p libmyssl.so.1.0 |需要知道它取决于以下库:
NEEDED libstdc++.so.6
NEEDED libc.so.6
我使用 libmyssl.so.1.0 在上述演示代码中以相同的方式:
g++ -D UNIX64 -o ssldemo ssldemo.cpp ./libmyssl.so.1.0 -lz -lssl -lcrypto
- 我在ubuntu14.04(同一版本)中编译了演示,效果很好。
我在CentOS(OpenSSL 0.9.8e)中编译了演示,没有报告SSL链接错误,但它报告了GliBC链接错误的错误:
未定义的引用至`memcpy@glibc_2.14'
更新Certos的GLIBC后,演示正常工作。
第三轮
我尝试将其删除到" libc.so.6"answers" libstdc 。so.6",所以我在编译命令:
中添加了选项" -nodefaultlibs"g++ -nodefaultlibs -v -shared -Wl,-soname,libmyssl.so.1,-o libmyssl.so.1.0 myssl.o
- 我使用命令 objdump -p libmyssl.so.1.0 |需要仅获取空字符串。
- i使用命令 ldd libmyssl.so.1.0 获取结果"静态链接",不确定为什么它说"静态链接"。
我使用 libmyssl.so.1.0 在上述演示代码中以相同的方式:
g++ -D UNIX64 -o ssldemo ssldemo.cpp ./libmyssl.so.1.0 -lz -lssl -lcrypto
它总是在Ubuntu14.04和Centos5.8中报告以下错误。8:
Ubuntu:
hidden symbol `atexit' in /usr/lib/x86_64-linux-gun/libc_nonshared.a(atexit.oS) is referenced by DSO
/usr/bin/ln: final link failed: Bad value
centos:
hidden symbol `atexit' in /usr/lib64/libc_nonshared.a(atexit.oS) is referenced by DSO
/usr/bin/ln: final link failed: Nonrepresentable section on output
问题:
- 当我编译我的 *.SO文件时,应链接哪个版本的GLIBC,以便在尽可能多的Linux中工作正常?
- 确实有办法避免对GLIBC的依赖?我在第三轮尝试中尝试了一下,但失败了。
- 还有其他建议吗?
当我编译 *.so文件时,应链接哪个版本的GLIBC 这样它可以在尽可能多的linux中运行良好?
您应该选择要定位的最古老的发行版并在此基础上构建。这将确保您的库需要最低可能的GLIBC版本。因此,只需使用最古老的glibc选择发行版并在此处构建。
您的glibc的版本通常在libc.so名称(例如/lib64/libc-2.12.so)中编码,但是您也可以做
$ strings //lib64/libc-2.12.so | grep GLIBC
GLIBC_2.2.5
GLIBC_2.2.6
...
GLIBC_2.12
GLIBC_PRIVATE
确实有办法避免对GLIBC的依赖?我在第三轮尝试,但失败了。
完全独立于GLIBC的库听起来像是过度杀伤(与GLIBC相比,质量/性能较低)。您确定要走这条路吗?
还有其他建议吗?
对于完整的应用,两种常见的解决方案是
- 静态链接
- 将它们与stdlibs捆绑在一起,它们与他们相关联(当然需要使用特殊的ld_library_path或-wl,-rpath运行)
但是,在您的情况下(孤立的共享库),针对最低的GLIBC似乎是唯一的选择。
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 导入库可以跨dll版本工作吗
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 不同的Visual Studio版本中缺少.dll
- 用符号版本替换对函数的所有调用
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- glibc 版本比 gcc 版本和 -wl,-rpath 不工作
- libstdc++.so 在使用 Patchelf 和备用 glibc 版本时找不到
- 发布我的 *.so文件时,应使用哪个版本的glibc
- glibc(或libc6)库版本
- 检测旧GLIBC版本的堆栈溢出
- Glibc 版本不匹配
- 在使用旧版本gcc / glibc / libstdc++的计算机上运行用gcc 4.7编译的c++ 11可执行文件的问
- 在GLIBC版本较低的目标系统上,从.so文件导入Python模块失败
- 链接到特定的GLIBC版本
- 在不同版本的Linux和glibc上构建和运行c++代码
- 从Java调用c++,但是Java加载了错误的Glibc版本