我正在开发一个支持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
我使用命令 objdump -p libmyssl.so.1.0 | grep NEEDED 来了解它取决于以下库:
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
我删除了“-lz lssl -lcrypto”,所以命令如下
g++ -v -shared -Wl,-soname,libmyssl.so.1,-o libmyssl.so.1.0 myssl.o
我使用命令 objdump -p libmyssl.so.1.0 | grep NEEDED 来了解它取决于以下库:
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
我在CentOS中编译了这个演示版(openssl 0.9.8e),没有报告ssl链接错误,但它报告glibc链接错误如下:
对'memcpy@GLIBC_2.14'的未定义引用
更新CertOS的glibc后,演示工作正常。
我尝试删除依赖于“libc.so.6”和“libstdc ++。so.6”,所以我在编译命令中添加了选项“-nodefaultlibs”:
g++ -nodefaultlibs -v -shared -Wl,-soname,libmyssl.so.1,-o libmyssl.so.1.0 myssl.o
我以相同的方式在上面的演示代码中使用 libmyssl.so.1.0 :
g++ -D UNIX64 -o ssldemo ssldemo.cpp ./libmyssl.so.1.0 -lz -lssl -lcrypto
它始终在Ubuntu14.04和CentOS5.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
答案 0 :(得分:0)
编译* .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相比,你需要重新实现IO,memcpy等,质量/性能更低)。你确定要沿着这条道路前进吗?
还有其他建议吗?
对于完整的应用程序,有两种常见的解决方案
但是在你的情况下(孤立的共享库),目标是支持最低的Glibc似乎是唯一的选择。