Linux 下 C++ 编程过程中开发环境中踩过的坑
[TOC]
本文记录一些 Linux 下 C++ 编程过程中典型的配置开发环境中踩过的坑, 以期待举一反三. 并持续整理更新.
缺失库
报错输出: 一般比较简单, 关键词是 not found.
问题解决思路:
首先查找系统中是不是在别的位置中存在该库. 暴力手段如下:
1
sudo find / -name LIB_NAME
如果报错信息中不存在缺失库的名字, 可以用
ldd
命令查找无法运行的库的依赖库项.如果查到了创建其软链接到调用库的目录下, 观察是否可以使用.
系统中不存在此库, 或者版本不匹配. 此时最关键的问题来了, 很多库名不是直接对应其源码包/二进制文件名的, 需要耐心搜索. 例如我在
ros2 run rviz2 rviz2
时报错缺失libassimp.so.5
, 搜到其对应的 apt 库名字为libassimp-dev
. 这个算是对照比较工整的名字了.- 网上下载二进制文件
- 下载源码包, 编译后安装到所需位置.
查不到, 下载不了, 还是不匹配: 找同事拷贝吧.
库匹配错误
虽然找到了库, 但是应用发现库不匹配. 通过实例介绍.
ROS 中不匹配库
例如在 ROS 中不匹配库的报错示例:
1 | symbol lookup error LIB_NAME.so: undefined symbol |
还是 ros2 run rviz2 rviz2
报错 symbol lookup error librcl_logging_spdlog.so: undefined symbol
, 这个库应该是 ROS 生态圈里的专用库, 因此用搜索引擎搜索都得不到什么结果. 因为报错信息里有库名, 先直接 find
搜索. 发现果然有 2 处目录下存在相同的库.
1 | /opt/ros/galatic/lib/librcl_logging_spdlog.so #报错的是此库 |
然后用 md5sum
检查两个库的 checksum 值, 发现果然不一样, 得出结论: 另一个位置的库可能是可用的. 备份替换:
1 | sudo mv /opt/ros/galatic/lib/librcl_logging_spdlog.so /opt/ros/galatic/lib/librcl_logging_spdlog.so_bk |
再运行一遍发现报错消除了.
问题的关键是, 不知道什么原因这个库在安装后(/opt/ros/galatic/lib/
)与 ROS2 官方二进制压缩包(/home/USER/ros/galatic/lib/
)里的库相比发生了变化.
除了软链接, 可以将 /home/USER/ros/galatic/lib
与 /opt/ros/galatic/lib/
的位置在 LD_LIBRARY_PATH
环境变量里调换, 调整优先使用顺序.
上面调整顺序的方法不太优雅, 原因如下:
- 修改环境变量打字很麻烦.
- 最关键的是, 整个目录下所有的库的优先级都被调整了, 如何只针对一个库的优先级进行调整呢?
动态库加载顺序
Linux 下动态库的一般加载顺序如下:
- 编译目标代码时使用
-Wl, -rpath
指定的动态库搜索路径. 这个具有最高优先级. - 环境变量
LD_PRELOAD
指定的目录. 无论程序是否依赖于它们,LD_PRELOAD
里面指定的共享库或目标文件都会被装载. 全局符号就会覆盖后面加载的同名全局符号, 这使得我们可以很方便地做到改写标准 C 库中的某个或某几个函数而不影响其他函数, 对于程序的调试或测试非常有用. - 环境变量
LD_LIBRARY_PATH
指定的动态库搜索路径. - 配置文件
/etc/ld.so.conf
中指定的动态库搜索路径. 配置后要运行ldconfig
命令才能生效. - 默认的动态库搜索路径
/lib
. - 默认的动态库搜索路径
/usr/lib
.
根据我们对优雅性的要求, 我们可以发现 LD_LIBRARY_PATH
指定最符合要求, 编辑/删除都比较方便, 只影响一个库而不是一堆库:
1 | export LD_LIBRARY_PATH=/home/USER/ros/galatic/lib/librcl_logging_spdlog.so:$LD_LIBRARY_PATH |
如果需要么此启动终端都加入, 将上面命令放入 ~/.bashrc
中.
这种方法虽然没有软链接这么直接, 但是在保证不同版本的库共存的前提下还是很有用的思路.
环境变量设置
还是 ros2 run rviz2 rviz2
报错…
1 | Qt: Session Management Error |
解除现有的 SESSION_MANAGER
环境变量设置:
1 | export -n SESSION_MANAGER |
并放入 ~/.bashrc
中不用每次配置.
此案例参考链接.
参考链接:
Linux 下 C++ 编程过程中开发环境中踩过的坑
https://www.chuxin911.com/linux_cpp_development_environment_config_20220519/