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

时间:2013-11-04 13:02:21

标签: c++ linux shared-libraries static-libraries

我正在尝试将静态库链接到共享库,我收到了以下错误

/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(fileappender.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
../../../libraries/log4cplus/liblog4cplus.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

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

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

 
/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(appenderattachableimpl.o): relocation R_X86_64_32S against `vtable for log4cplus::spi::AppenderAttachable' can not be used when making a shared object; recompile with -fPIC
../../../libraries/log4cplus/liblog4cplus.a(appenderattachableimpl.o): could not read symbols: Bad value
collect2: ld returned 1 exit status

创建liblog4cplus.a:

  1. unzip log4cplus-1.1.0.zip
  2. ./configure --enable-static=yes --enable-threads=yes
  3. vi Makefile并将-fPIC添加到CXXFLAGS和CFLAGS
  4. make
  5. 然后编译我的共享库:

    1. g++ -frtti -w -c -fPIC -I"Include_Directory" myfile.cpp
    2. g++ -shared -fPIC -frtti -I"Include_Directory" -o mysofile.so myfile.o -Wl,--whole-archive "../../../libraries/log4cplus/liblog4cplus.a" -Wl,--no-whole-archive -ldl

5 个答案:

答案 0 :(得分:81)

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

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

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

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

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

答案 1 :(得分:2)

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

  

/ usr / bin / ld:/usr/local/lib/libccd.a(ccd.o):在创建共享对象时,不能使用针对“本地符号”的重定位R_X86_64_32S;用-fPIC重新编译

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

  1. /usr/local/lib/libccd.a
  2. /usr/local/lib/x86_64-linux-gnu/libccd.a
  3. 我通过删除第一个文件解决了这个问题。

答案 2 :(得分:2)

将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#c3
https://github.com/rpmfusion/lxdream/blob/master/lxdream-0.9.1-implicit.patch

答案 3 :(得分:1)

-fPICCMAKE_CXX_FLAGS的末尾添加CMAKE_C_FLAG

示例:

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

这解决了我的问题。

答案 4 :(得分:0)

尝试将静态编译的fontconfigexpat链接到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
[...]

这与我已经通过-fPIC变量传递CFLAGS标志以及其他编译器/链接器变体(clang / lld)完全在同一构建配置下工作这一事实相反。最终,这些依赖关系通过卑鄙的autoconf脚本控制与位置无关的代码设置,并且需要在Linux gcc / ld组合上的构建配置期间切换--with-pic,而缺少它可能会覆盖{{1 }}。将开关传递到CFLAGS脚本,将使用configure正确编译依赖项。