最近需要部署PyKDL库,遇见奇怪的问题,困扰了好几天,下面列出问题描述和我的解决过程
orocos-kdl库的github的仓库地址:
https://github.com/orocos/orocos_kinematics_dynamics
之前已经在另一台电脑上按照install.md安装并测试过kdl-py库,但是今天在新电脑上部署时却出现了问题:
ModuleNotFoundError: No module named 'PyKDL'
一开始以为是conda中的环境无法链接/usr/local/lib
的动态库,所以直接把动态库扔进conda中python环境下的site-packages目录下,出现如下报错:
undefined symbol: PyFrame_GetBack
对于符号未定义的问题,通过以下方法溯源:
nm -gDC PyKDL.so | grep Py
可以看到大部分python中的符号都没有被定义,所以,不是conda无法链接动态库,而是在使用pybind11编译C++库的时候出现了问题。
在cmake时没有提示pybind11的报错,说明其安装没有问题,那么还是环境的问题,所以直接看pykdl中的cmakelist,注意到如下部分:
if(DEFINED ENV{ROS_PYTHON_VERSION})
SET(PYTHON_VERSION $ENV{ROS_PYTHON_VERSION} CACHE STRING "Python Version")
else()
SET(PYTHON_VERSION 3 CACHE STRING "Python Version")
endif()
发现它的cmake是使用ROS的Python版本,而我的电脑中只有conda环境下的python,
所以在cmake的时候,我们需要指定python及其库文件的路径:
cmake -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.8.so \
-DPYTHON_INCLUDE_DIR=/usr/include/python3.8 \
-DPYTHON_EXECUTABLE=/usr/bin/python3.8 ..
然后,把编译出来的动态库丢到envs中的site-packages里,直接import就可以使用了。