76

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

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

我按照这里的建议尝试了该-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:

  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
4

5 回答 5

115

假设您正在生成一个共享库,很可能发生的情况是liblog4cplus.a您使用的变体未使用-fPIC. 在 linux 中,您可以通过从静态库中提取目标文件并检查它们的重定位来确认这一点:

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

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

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

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

于 2013-11-04T13:06:48.220 回答
7

在和-fPIC末尾添加CMAKE_CXX_FLAGSCMAKE_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" )

这解决了我的问题。

于 2020-06-19T18:40:24.427 回答
3

I've got a similar error when installing FCL that needs CCD lib(libccd) like this:

/usr/bin/ld: /usr/local/lib/libccd.a(ccd.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC

I find that there is two different files named "libccd.a" :

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

I solved the problem by removing the first file.

于 2014-04-20T20:29:02.823 回答
3

针对未定义符号重定位 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

于 2016-07-26T01:32:14.800 回答
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脚本控制与位置无关的代码设置,并且--with-pic在 linux gcc/ld 组合上的构建配置期间需要切换,并且它的缺失可能会覆盖CFLAGS. 将开关传递给configure脚本,依赖项将使用-fPIC.

于 2020-04-08T08:54:13.267 回答