在不修改和重新编译 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' 在制作共享对象时不能使用;使用 -fPIC 重新编译and
无法读取符号:错误值` 它们都来自 bitset.o 存档中的 libstdc++.a。所以我不能只将 .a 重新编译成动态库,因为默认情况下,GNU GCC 编译器不会使用 PIC 选项编译用于静态库的目标文件。
这让我不得不找到一个精灵工具或重新编译 GNU GCC 并对其构建进行修改。
正如其中一个答案所述,许可问题可能是这些方法中的任何一个都存在的问题。我最好的答案是我们需要改变我们的要求并找到一个不涉及以任何方式更改或重新打包 GCC 标准库的不同解决方案。