这两天重装了一遍系统,突然发现有更好的解决方法,以前这种方法简直是弱智。。
======================================
以前的方法:
orb-slam2和3在执行的时候都会出现这个问题,错误为:
symbol lookup error: /home/smz/slam_demo/ORB_SLAM3/lib/libORB_SLAM3.so: undefined symbol: _ZN5DBoW24FORB1LE
1、确定问题类型:从错误提示中可以看出是发生了so库调用异常,说明链接出了问题。
2、确定问题链接:~/slam_demo/ORB_SLAM3/lib 目录下 ldd -r libORB_SLAM3.so
拉到最后可以看到 undefined symbol: _ZN5DBoW24FORB1LE (./libORB_SLAM3.so)
c++filt _ZN5DBoW24FORB1LE
可以看到是DBoW2::FORB::L的问题
从orb-slam的readme可知,作者修改了DBoW2库,因此必须使用作者提供的这个库才可以
3、解决问题
1) ldd -r libORB_SLAM3.so 中找libDBoW2.so 到底链接了什么
我这边由于装过其他slam,其链接路径是
libDBoW2.so => /home/smz/slam_demo/kimera_ros/devel/lib/libDBoW2.so (0x00007fbb6c71a000)
2)在cmakelist中指定库的路径
set(DBOW_LIB /home/smz/slam_demo/ORB_SLAM3/Thirdparty/DBoW2/lib/libDBoW2.so)
重新编译
结果并不管用。
3)在cmakelist注销掉Build examples下所有内容,并注销${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
理论上应该通不过编译,但是实际上仍旧可以通过编译,同时 libDBoW2.so一项消失
在这个基础上 编译一个执行程序
add_executable(stereo_euroc
Examples/Stereo/stereo_euroc.cc)
target_link_libraries(stereo_euroc ${PROJECT_NAME})
此时报错
4)通过设置库的路径,再试
set(DBOW_LIB /home/smz/slam_demo/ORB_SLAM3/Thirdparty/DBoW2/lib/libDBoW2.so)
target_link_libraries(${DBOW_LIB})
add_executable(stereo_euroc
Examples/Stereo/stereo_euroc.cc)
target_link_libraries(stereo_euroc ${PROJECT_NAME} ${DBOW_LIB})
依旧没用
(也试过find_package,link_*,在bashrc中设置环境路径等方法)
可以确定libORB_SLAM3.so这个库生成和makelists设置关系并不大。
5)研究其引用的这个库 /home/smz/slam_demo/kimera_ros/devel/lib/libDBoW2.so
这个文件是在ros环境下生成的,理论上把它删了,就可以解决这个问题,在bashrc中,把/home/smz/slam_demo/kimera_ros/这个环境干掉,就可以解决这个问题。
总结:由于库的路径有点紊乱,直接指定路径可能并没有效果,那就直接干掉误引用的库就好。
后续思考:1、ros好像是因为其植根于系统,导致其中库优先度很高,尤其是catkin build生成的库,总是被优先查找,即便是在cmakelist下指定路径也是不管用的。
2、编译的时候库到底是如何找的?优先级到底是怎样的,为什么ros优先度这么高,这是通过哪个文件给的路径?
====================================
现在的方法:
突然想明白,它找错位置是因为有一个同名的文件,那把它改的不是同名的不就好了么
修改 /ORB_SLAM3/Thirdparty/DBoW2/CMakeLists.txt
然后更改
${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
改成
${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2_1.so
即可解决问题。
(感觉自己好智障。。)