“重新定位 R_X86_64_32S”链接错误

我试图链接一个静态库到一个共享库,我得到以下错误

/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,也没有解决这个问题

我尝试了建议 给你-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

然后是编译我的共享库:

  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
152656 次浏览

假设您正在生成一个共享库,最可能发生的情况是您正在使用的 liblog4cplus.a的变体没有用 -fPIC编译。在 linux 中,可以通过从静态库和 检查他们的搬迁中提取目标文件来确认这一点:

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

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

由于静态库包含已经编译的对象代码,因此提供-fPIC 标志没有帮助。

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

在安装需要 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

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

针对未定义符号重新定位 R _ X86 _ 64 _ PC32,通常发生在 LDFLAGS 设置为硬化而 CFLAGS 不设置时。
也许只是用户错误:
如果在链接时使用-specs =/usr/lib/rpm/redhat/redhat- 硬化了的-ld, 您还需要在编译时使用-specs =/usr/lib/rpm/redhat/redhat-harded-cc1,并且由于您同时进行编译和链接,因此需要两者兼备,或者删除-specs =/usr/lib/rpm/redhat/redhat-harded-ld。 常见问题:
Https://bugzilla.redhat.com/show_bug.cgi?id=1304277#c3
Https://github.com/rpmfusion/lxdream/blob/master/lxdream-0.9.1-implicit.patch

在尝试将静态编译的 Fontconfig外籍人士链接到 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开关,而它的缺失可能会覆盖相同的设置。将开关传递到 configure脚本,依赖关系将用 -fPIC正确编译。

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" )

这解决了我的问题。