返回

如何解决“relocation R_X86_64_32S against `a local symbol'`链接错误?

Linux

如何解决 “relocation R_X86_64_32S against a local symbol' 链接错误

摘要

如果你在将静态库链接到共享库时遇到“relocation R_X86_64_32S against a local symbol'错误,表明静态库未使用位置无关代码 (PIC) 编译。本文将逐步指导你使用 -fPIC 标志重新编译静态库和共享库,并使用适当的链接标志来解决此错误。

了解 PIC 和链接错误

位置无关代码 (PIC) 是一种编译技术,允许代码在内存中的任意位置加载和执行。当构建共享库时,需要 PIC 以确保共享库可以在不同的程序中使用,而无需重新编译。

如果静态库未使用 PIC 编译,链接器就会生成上述错误,表示局部符号在构建共享对象时无法使用。

解决方案

1. 使用 -fPIC 标志重新编译静态库

  • 编辑静态库的 Makefile,向 CXXFLAGS 和 CFLAGS 中添加 -fPIC 标志。
  • 重新编译静态库,确保它使用 -fPIC 标志进行编译。

2. 使用 -fPIC 标志编译共享库

  • 编译共享库时,使用 -fPIC 标志编译源代码。这将确保共享库也使用 PIC 进行编译。

3. 使用 -Wl,--whole-archive-Wl,--no-whole-archive 标志链接共享库

  • 链接共享库时,使用 -Wl,--whole-archive-Wl,--no-whole-archive 标志。这将确保链接器包含静态库中的所有对象文件。

示例 Makefile 片段

CXXFLAGS += -fPIC
CFLAGS += -fPIC

# 其他 Makefile 规则...

完整命令

# 重新编译静态库
make clean
./configure --enable-static=yes --enable-threads=yes
vi Makefile # 添加 -fPIC 到 CXXFLAGS 和 CFLAGS
make

# 编译共享库
g++ -frtti -w  -c -fPIC -I"Include_Directory" myfile.cpp
g++ -shared -fPIC -frtti -I"Include_Directory" -o mysofile.so myfile.o -Wl,--whole-archive "../../../libraries/log4cplus/liblog4cplus.a" -Wl,--no-whole-archive -ldl

结论

通过遵循上述步骤,你可以重新编译静态库和共享库,并使用适当的链接标志,从而解决“relocation R_X86_64_32S against a local symbol'链接错误。

常见问题解答

  1. 为什么我需要使用 PIC 编译?
    PIC 允许代码在内存中的任意位置加载和执行,对于构建共享库至关重要。

  2. 如何检查代码是否使用 PIC 编译?
    可以在命令行中使用 readelf -d 命令来检查目标文件或库是否使用 PIC 编译。

  3. 我可以跳过重新编译静态库吗?
    不,静态库需要使用 PIC 重新编译,否则错误将持续存在。

  4. 链接标志 -Wl,--whole-archive-Wl,--no-whole-archive 的作用是什么?
    这些标志确保链接器包含静态库中的所有对象文件。

  5. 如果我仍然遇到错误怎么办?
    确保已正确安装和配置编译器和链接器。还应检查静态库和共享库的架构是否与目标系统匹配。