发布我的 *.so文件时,应使用哪个版本的glibc

Which version of glibc should be used when release my *.so file?

本文关键字:glibc 版本 布我的 我的 文件 so      更新时间:2023-10-16

我正在研究一个支持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 
  1. 我在ubuntu14.04(同一版本)中编译了演示,它可以正常工作。
  2. 我在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 
  1. 我在ubuntu14.04(同一版本)中编译了演示,效果很好。
  2. 我在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

问题:

  1. 当我编译我的 *.SO文件时,应链接哪个版本的GLIBC,以便在尽可能多的Linux中工作正常?
  2. 确实有办法避免对GLIBC的依赖?我在第三轮尝试中尝试了一下,但失败了。
  3. 还有其他建议吗?

当我编译 *.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似乎是唯一的选择。