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

时间:2016-11-25 04:14:56

标签: c++ linux hyperlink shared-libraries glibc

我正在开发一个支持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 
  1. 我在Ubuntu14.04(相同版本)中编译了演示,它运行正常。
  2. 我在CentOS(openssl 0.9.8e)中编译了演示,它链接失败,因为无效的openssl版本
  3. 第二轮

    我删除了“-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 
    
    1. 我在Ubuntu14.04(相同版本)中编译了演示,它运行正常。
    2. 我在CentOS中编译了这个演示版(openssl 0.9.8e),没有报告ssl链接错误,但它报告glibc链接错误如下:

      对'memcpy@GLIBC_2.14'的未定义引用

    3. 更新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
      
      • 我使用命令 objdump -p libmyssl.so.1.0 | grep NEEDED 只获取空字符串。
      • 我使用命令 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中报告以下错误:
      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. 还有其他建议吗?

1 个答案:

答案 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等,质量/性能更低)。你确定要沿着这条道路前进吗?

  

还有其他建议吗?

对于完整的应用程序,有两种常见的解决方案

  • 静态链接
  • 将它们与stdlib捆绑在一起,它们被链接在一起(它们当然需要使用特殊的LD_LIBRARY_PATH或-Wl,-rpath运行)

但是在你的情况下(孤立的共享库),目标是支持最低的Glibc似乎是唯一的选择。