“重定位 R_X86_64_32S 反对”链接错误

Posted

技术标签:

【中文标题】“重定位 R_X86_64_32S 反对”链接错误【英文标题】:"relocation R_X86_64_32S against " linking Error 【发布时间】:2013-11-15 02:29:30 【问题描述】:

我正在尝试将静态库链接到共享库,但出现以下错误

/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(fileappender.o): 重定位 R_X86_64_32S 反对 `a local symbol' 在制作共享对象时不能使用;使用 -fPIC 重新编译 ../../../libraries/log4cplus/liblog4cplus.a:无法读取符号:错误值 collect2: ld 返回 1 个退出状态

但这在 32 位机器上工作,没有任何此类错误。我尝试手动将 -fPIC 标志添加到 Makefile 中,但也没有解决问题

我按照here 的建议尝试了-whole-archive 标志,但没有成功。

/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(appenderattachableimpl.o): 重定位 R_X86_64_32S 对 `vtable for log4cplus::spi::AppenderAttachable' 无法使用共享对象;使用 -fPIC 重新编译 ../../../libraries/log4cplus/liblog4cplus.a(appenderattachableimpl.o):无法读取符号:错误值 collect2: ld 返回 1 个退出状态

创建 liblog4cplus.a:

    unzip log4cplus-1.1.0.zip ./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

【问题讨论】:

你能粘贴完整的命令行吗?如果您确切地指出“将静态库链接到共享库”的含义,那也很好。您是从静态库中生成共享库吗? @MichaelFoukarakis 不是真的... 对于那些将来要问的人:有时这只是由于发行版更改而发生的,可以通过快速清理构建目录来解决。 What do R_X86_64_32S and R_X86_64_64 relocation mean?的可能重复 【参考方案1】:

假设您正在生成一个共享库,很可能发生的情况是您使用的liblog4cplus.a 的变体不是用-fPIC 编译的。在linux中,您可以通过从静态库中提取目标文件和checking their relocations来确认这一点:

ar -x liblog4cplus.a  
readelf --relocs fileappender.o | egrep '(GOT|PLT|JU?MP_SLOT)'

如果输出为空,则静态库不是位置无关的,不能用于生成共享对象。

由于静态库包含已编译的目标代码,提供 -fPIC 标志将无济于事。

您需要获取使用-fPIC 编译的liblog4cplus.a 版本并使用该版本。

【讨论】:

您好,感谢您的回复,很抱歉回复晚了,您的回答帮助我确定了问题。【参考方案2】:

CMAKE_CXX_FLAGSCMAKE_C_FLAG末尾添加-fPIC

例子:

set( CMAKE_CXX_FLAGS  "$CMAKE_CXX_FLAGS -Wall --std=c++11 -O3 -fPIC" )
set( CMAKE_C_FLAGS  "$CMAKE_C_FLAGS -Wall -O3 -fPIC" )

这解决了我的问题。

【讨论】:

【参考方案3】:

我在安装需要 CCD lib(libccd) 的 FCL 时遇到类似的错误,如下所示:

/usr/bin/ld: /usr/local/lib/libccd.a(ccd.o): 重定位 R_X86_64_32S 反对 `a local symbol' 在制作共享对象时不能使用;用 -fPIC 重新编译

我发现有两个不同的文件名为“libccd.a”:

    /usr/local/lib/libccd.a /usr/local/lib/x86_64-linux-gnu/libccd.a

我通过删除第一个文件解决了这个问题。

【讨论】:

【参考方案4】:

针对未定义符号重定位 R_X86_64_PC32,通常发生在 LDFLAGS 设置为硬化而 CFLAGS 未设置时。 也许只是用户错误: 如果您在链接时使用 -specs=/usr/lib/rpm/redhat/redhat-hardened-ld, 您还需要在编译时使用 -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ,并且在同时编译和链接时,您需要两者之一,或者删除 -specs=/ usr/lib/rpm/redhat/redhat-hardened-ld 。 常见修复:https://bugzilla.redhat.com/show_bug.cgi?id=1304277#c3https://github.com/rpmfusion/lxdream/blob/master/lxdream-0.9.1-implicit.patch

【讨论】:

【参考方案5】:

在尝试将静态编译的 fontconfig 和 expat 链接到 linux 共享对象时,我也遇到了类似的问题:

/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: /3rdparty/fontconfig/lib/linux-x86_64/libfontconfig.a(fccfg.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: /3rdparty/expat/lib/linux-x86_64/libexpat.a(xmlparse.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
[...]

这与我已经通过CFLAGS 变量传递-fPIC 标志的事实相反,并且其他编译器/链接器变体(clang/lld)完美地使用相同的构建配置。最终这些依赖通过卑鄙的autoconf 脚本控制与位置无关的代码设置,并且在linux gcc/ld 组合的构建配置期间需要--with-pic 开关,并且它的缺失可能会覆盖CFLAGS 中的相同设置。将开关传递给configure 脚本,依赖项将使用-fPIC 正确编译。

【讨论】:

以上是关于“重定位 R_X86_64_32S 反对”链接错误的主要内容,如果未能解决你的问题,请参考以下文章

链接器错误 - 不确定它没有链接

为啥链接器链接了错误的函数?

显式链接错误 - 语法错误:缺少 ';'由 bazel 编译时在 '*' 之前

C++编译链接错误

GLEW 链接器错误

奇怪的链接器错误