【问题标题】:How do you repackage the gnu gcc standard libraries stdc++, gcc, and gcc_eh?如何重新打包 gnu gcc 标准库 stdc++、gcc 和 gcc_eh?
【发布时间】:2011-12-09 13:39:52
【问题描述】:

在不修改和重新编译 gnu gcc 和 stdc++ 库构建的情况下,我需要能够使用不同的嵌入式 soname 重现这些库的动态加载版本。

我想我会很聪明,使用可用的静态版本并用这样的东西重新打包它们: ld -E -shared -static "-lstdc++" -lgcc -lgcc_eh -o librepackaged_standard.so

librepacked_standard.so 已创建,没有警告或错误,但 ldd 报告它不是动态库,而 readelf 仅报告这些基本符号:

Symbol table '.symtab' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000201000     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     2: 0000000000201000     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
     3: 0000000000201000     0 NOTYPE  GLOBAL DEFAULT  ABS _end

我不确定为什么 ld 没有引入所有静态定义的符号。我也不知道是否需要提供任何其他特殊参数才能使其正常工作。

另一个选择是如果有一种已知的跨平台方法来简单地更改嵌入在原始精灵库中的 soname。我目前只关心精灵格式的二进制文件。我对编写自己的工具来更改现有二进制文件中的 .soname 不感兴趣。

更新: 没有编译符号的原因是ld 处理静态二进制文件的方式不同于 .o 文件。默认情况下,它不会从 .a 文件中导入任何符号,除非链接行上的另一个库需要它们。我通过提供 --whole-archive 选项解决了这个问题。

但是,这给了我另一个错误,relocation R_X86_64_32S against_ZSt12_S_first_one' 在制作共享对象时不能使用;使用 -fPICand 重新编译无法读取符号:错误值` 它们都来自 bitset.o 存档中的 libstdc++.a。所以我不能只是将 .a 重新编译成动态库,因为默认情况下,GNU GCC 编译器不会使用 PIC 选项编译用于静态库的目标文件。

这让我不得不找到一个 elf 工具或重新编译 GNU GCC 并对其构建进行修改。

正如其中一个答案所述,许可问题可能是这些方法中的任何一个都存在的问题。我的最佳答案是,我们需要改变我们的要求并找到一个不涉及以任何方式更改或重新打包 GCC 标准库的不同解决方案。

【问题讨论】:

    标签: gcc gnu ld std libstdc++


    【解决方案1】:

    没有符号被编译到共享库中的原因是ld 处理静态二进制文件的方式不同于 .o 文件。默认情况下,它不会从 .a 文件中导入任何符号,除非链接行上的另一个库需要它们。该特定问题的答案是使用 --whole-archive 选项并直接链接 .a 文件通常有效。

    但是,要使其正常工作,静态存档中包含的 .o 文件需要在编译时使用 -fPIC 选项进行编译。但是,用于静态库的目标文件未使用可用静态库中的该选项进行编译。

    因此,更改 SONAME 的解决方案是使用 ELF 二进制实用程序或重新构建修改为使用不同 SONAME 的 GNU GCC。

    由于在这种情况下存在许可问题,因此任何解决方案都不适用于该项目,因为它不是开源的,我们不希望要求为我们所有平台重新分发修改后的 GNU GCC 源版本。

    【讨论】:

      【解决方案2】:
      1. -static 可能解散了-shared
      2. 传统上,您会从静态库中提取目标文件,然后将这些目标文件打包到共享库中 - 依赖于 PIC(位置无关代码)的普遍使用,以便静态库中的对象可以安全地转换为共享库。您也许可以不使用该提取步骤,但我对此表示怀疑。
      3. 您可能需要考虑是否符合许可条款和条件。

      【讨论】:

      • -static 的 ld 手册页声明:不要链接到共享库。 您可以在命令行上多次使用此选项:它会影响库搜索后面的 -l 选项。 此选项可与 -shared 一起使用。这样做意味着正在创建一个共享库,但必须通过从静态库中拉入条目来解析该库的所有外部引用。
      • 关于许可,这是向给我要求的人提出的一个好点。我试图让他们相信,最好的选择是要求在受支持的平台上安装最小版本的 stdc++ 库包,AFAIK 是软件的常见做法。
      猜你喜欢
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多