CMake编译报错/usr/bin/ld: ../lib/libXXX.a(XXX.cc.o): relocation R_X86_64_PC32 against symbol

在Ubuntu上,使用CMake编译C++工程文件时,报错:

解决办法是:在子工程中所有生成了库(除INTERFACE_LIBRARY之外的库)的工程的CMakeList中设置-fPIC参数,具体操作方法为在生成库文件的代码

add_library(XXX
    a.cc
    b.cc
)

语句后添加一行代码,为:

set_property(TARGET XXX PROPERTY POSITION_INDEPENDENT_CODE ON)

其中,XXX为库的名字。

详细原理个人理解如下:

当前工程的需求是把调用了boost库的C++工程编译成为一个动态链接库以供Python调用,(boos

的使用过程也有些曲折,详细过程及模板伪代码请见本人的这篇博客: ),但是在调整完成wrapper.cc后,编译,报错提示

/usr/bin/ld: ../lib/libXXX.a(XXX.cc.o): relocation R_X86_64_PC32 against symbol `_ZN8planning4eudm31_LonSimDetail_default_instance_E' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status

然后查询一些资料之后,因为编译动态链接库时需要设置-fPIC参数,目的是使得生成的动态链接库与位置无关

gcc编译参数-fPIC的一些问题_逐鹿之城的博客-CSDN博客_fpic

(先放个链接吧,挖个坑,之后补上我的理解~)

而要想生成这样的链接库,那它所链接的库都必须是位置无关的,即有-fPIC参数设置,所以就要在链接库的工程中进行设置了。

同理,后面在生成动态链接库时,因为用到了boost_python库,所以要在CMakeList里加上对应的链接库,如果库名是boost_python,则会寻找到libboost_python.a,结果也会报如上错误

target_link_libraries(py_solver_util
    (其他库)
    boost_python39)

如果不加这boost_python这个依赖库,那编译时不会报错,但Python调用就会报错

ImportError: /home/jp/ego_solver/lib/XXX(生成的库名).so: undefined symbol: _ZTIN5boost6python15instance_holderE

而且注意要用来调用C++的Python的版本必须与这个依赖库指定的版本一致,否则会报错:

ImportError: /lib/x86_64-linux-gnu/libboost_python39.so.1.71.0: undefined symbol: _Py_tracemalloc_config

如果像我一样,boost是用apt-get install的最新版,那可能出现boost的python版本与系统版本不一致的问题,如果要源码编译重新安装boost的话,一定要注意自己安装的头文件和库的位置,如果安装失败了的话记得清理,否则可能会导致环境里面boost版本混乱,出现玄学问题(就比如我之前博客里的那个只有boost头文件,没有lib带来的玄学问题),建议可以用conda重新建立一个环境,再用

conda install boost

命令安装一个boost,就可以避免这个问题啦,但是需要注意两个问题,分别是Python和boost的问题:

        一是Python,要在自己工程的CMakeList里的include_directories里面指定Python的库(pyconfig.h)路径,否则会报找不到这个头文件的错误。

        二是boost,由于我使用的是conda里的libboost_python39.so动态链接库,所以它的路径是不在gcc的默认编译路径里的,所以需要修改环境变量,否则会报错

        /usr/bin/ld: cannot find -lboost_python39
        collect2: error: ld returned 1 exit status

具体修改方法为

首先寻找库的路径,可以在文件中搜索libboost_python39.so,找到路径后,执行

$ sudo gedit ~/.bashrc
在文件中加上这一行:
export LD_LIBRARY_PATH=/上文找到的库路径/lib/:$LD_LIBRARY_PATH

或者执行:
$ echo 'export LD_LIBRARY_PATH=/上文找到的库路径/lib/:$LD_LIBRARY_PATH' >> ~/.bashrc
$ source ~/.bashrc

来修改环境变量 LD_LIBRARY_PATH,加入库文件所在路径。

若修改变量 LD_LIBRARY_PATH 不奏效,则修改变量 LIBRARY_PATH 。(重点!!!而且我亲测只修改LD_LIBRARY_PATH 不得行~所以还要修改LIBRARY_PATH)

$ sudo gedit ~/.bashrc
在文件中加上这一行:
export LIBRARY_PATH=/上文找到的库路径/lib/:$LIBRARY_PATH

或者执行:
$ echo 'export LIBRARY_PATH=/上文找到的库路径/lib/:$LIBRARY_PATH' >> ~/.bashrc
$ source ~/.bashrc

ps:conda建虚拟环境确实不错哎,我过程中本来用的是Python3.8,下载的boost也是,但是后续发现要用到我生成的链接库的那个工程只能用Python3.9,所以我只能重新再编,本来以为要重新配环境,后来发现conda里面重新安装Python很方便,只需要执行

conda install python==3.9 -n xxx(虚拟环境名字)

就可以,而且对应的其他库(比如boost)也会重新安装,确实不错,打call!!
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值