Ubuntu下ORB_SLAM3链接OpenCV4.9.0时std::condition_variable::wait未定义问题
在Ubuntu 18.04上使用GCC 9.4.0构建依赖源码编译的OpenCV 4.9.0(位于Anaconda环境)的ORB_SLAM3项目时,链接mono_tum可执行文件出现以下链接错误:
/path/to/libopencv_core.so.4.9.0: undefined reference to `std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30'
环境配置
- 编译器:GCC 9.4.0
- OpenCV:4.9.0,源码编译后安装在Anaconda环境中
- ORB_SLAM3:使用CMake以C++14标准编译
库细节
- 系统
libstdc++.so.6版本为libstdc++.so.6.0.32,已确认/usr/lib/x86_64-linux-gnu/libstdc++.so中存在GLIBCXX_3.4.30 - 通过
ldd检查libopencv_core.so.4.9.0依赖,显示其链接到/usr/lib/x86_64-linux-gnu/libstdc++.so.6 - 用
readelf验证libstdc++.so.6中的condition_variable符号,确认包含wait符号:
1348: 00000000000d96a0 8 FUNC GLOBAL DEFAULT 13 _ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE@@GLIBCXX_3.4.30
- 已显式设置环境变量:
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LIBRARY_PATH
观察结果
- OpenCV编译无错误,仅ORB_SLAM3编译时出现该未定义引用错误
- 在CMakeLists.txt中显式链接
-lstdc++也无法解决问题
咨询问题
- 符号已存在却出现未定义引用错误的原因是什么?
- OpenCV 4.9.0、GCC 9.4.0与libstdc++ 6.0.32之间是否存在兼容性问题?
- 是否是Anaconda环境配置导致的问题,如何确保一致使用系统库?
希望得到解决该链接错误的思路、调试技巧或建议。
1. 符号存在却报未定义引用的原因
最常见的原因是链接顺序错误:如果libopencv_core.so在libstdc++.so之前被链接,链接器处理OpenCV的符号时还未找到libstdc++中的对应符号,就会报未定义引用。
其次是实际链接的库版本不一致:即使你设置了环境变量,CMake可能在配置阶段缓存了Anaconda自带的libstdc路径,导致ORB_SLAM3编译时链接了低版本的Anaconda libstdc,而非系统的高版本库。
另外,极小概率是ABI不匹配:比如OpenCV编译时用了更高的C标准(如C17),但GCC 9.x中C14与C17的std::condition_variable::wait签名兼容,这种情况几乎不会出现。
2. 三者的兼容性问题
GCC 9.4.0对应的libstdc版本为6.0.28及以上,而libstdc 6.0.32来自更高版本的GCC(12.x),高版本libstdc向下兼容低版本编译器生成的代码,因此GCC 9.4.0、OpenCV 4.9.0与libstdc 6.0.32不存在兼容性问题,OpenCV官方也明确支持GCC 9.x版本。
3. Anaconda环境的影响及解决方法
Anaconda自带的libstdc版本通常较低(多为GCC 7.x对应版本),会干扰CMake的库查找逻辑,导致ORB_SLAM3和OpenCV链接的libstdc版本不一致,进而出现符号缺失。
确保一致使用系统库的方法:
- 退出Anaconda环境编译:直接在系统原生环境下编译ORB_SLAM3,避免Anaconda的库路径干扰。
- 强制CMake使用系统库:在ORB_SLAM3的CMakeLists.txt中添加以下配置:
# 强制指定系统libstdc++路径 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/lib/x86_64-linux-gnu") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/lib/x86_64-linux-gnu -lstdc++") # 禁止CMake查找Anaconda的库 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - 清理CMake缓存:删除ORB_SLAM3编译目录下的
CMakeCache.txt和CMakeFiles文件夹,重新运行cmake确保新配置生效。
额外调试技巧
- 查看完整链接命令:运行
make VERBOSE=1,找到mono_tum的链接命令行,检查库路径顺序(确保-lstdc++在libopencv_core.so之后),以及是否出现Anaconda路径的libstdc++。 - 检查最终依赖:若能编译出
mono_tum的半成品,用ldd ./mono_tum查看实际链接的libstdc++路径,确认是否为系统版本。 - 验证OpenCV的依赖:用
readelf -d /path/to/libopencv_core.so.4.9.0 | grep NEEDED查看其依赖的libstdc++版本,确认与系统库一致。
内容的提问来源于stack exchange,提问作者thercorp

