在Ubuntu 20.04上搞定ORB-SLAM3编译:一个C++14标准设置救了我的命
在Ubuntu 20.04上搞定ORB-SLAM3编译:一个C++14标准设置救了我的命
如果你正在Ubuntu 20.04上尝试编译ORB-SLAM3,却在make阶段被一连串错误 1卡住,这篇文章就是为你准备的。作为一个在计算机视觉领域深耕多年的开发者,我深知这种看似简单的编译错误可能让人抓狂——尤其是当网上大多数教程都只告诉你"按照步骤来"却没人解释为什么会出现这些错误时。
ORB-SLAM3作为目前最先进的视觉SLAM系统之一,其代码质量相当高,但它的编译过程却可能成为新手的第一道门槛。特别是在Ubuntu 20.04这个长期支持版本上,由于系统默认的编译器版本和C++标准设置,你很可能会遇到各种奇怪的编译错误。本文将深入剖析这些错误的根源,并提供经过实战验证的解决方案。
1. 理解编译错误的本质
当你看到终端中不断滚动的错误信息时,第一反应可能是"我哪里做错了?"。但实际上,这些错误大多源于一个简单但容易被忽视的问题:C++标准版本不匹配。
典型的错误输出看起来像这样:
make[2]: *** [CMakeFiles/ORB_SLAM3.dir/build.make:375:CMakeFiles/ORB_SLAM3.dir/src/MLPnPsolver.cpp.o] 错误 1 make[2]: *** [CMakeFiles/ORB_SLAM3.dir/build.make:76:CMakeFiles/ORB_SLAM3.dir/src/Tracking.cc.o] 错误 1 ... make: *** [Makefile:84:all] 错误 2这些错误看似分散在不同的源文件中,但它们都有一个共同点:都是由于编译器无法正确处理代码中的C++14特性导致的。ORB-SLAM3大量使用了C++14标准引入的特性,而Ubuntu 20.04默认的g++编译器(g++ 9.3.0)虽然支持C++14,但CMake默认可能不会启用。
1.1 为什么C++标准如此重要?
C++标准决定了编译器如何处理你的代码。不同标准之间可能存在语法和功能上的差异:
| C++标准 | 主要特性 | 兼容性 |
|---|---|---|
| C++11 | auto类型推导, lambda表达式 | 广泛支持 |
| C++14 | 泛型lambda, 二进制字面量 | 需要显式启用 |
| C++17 | 结构化绑定, if constexpr | 较新编译器 |
ORB-SLAM3特别依赖C++14的几个关键特性:
- 泛型lambda表达式(用于灵活的算法封装)
- 变量模板(用于数学运算的通用实现)
- 自动返回类型推导(简化模板代码)
2. 两种解决方案的深度对比
解决这个问题的核心在于告诉CMake使用C++14标准编译。有两种主要方法可以实现这一点,各有优缺点。
2.1 方法一:设置CMAKE_CXX_STANDARD
这是最直接的方法,只需在ORB-SLAM3的CMakeLists.txt中添加一行:
set(CMAKE_CXX_STANDARD 14)优点:
- 明确指定整个项目的C++标准
- 只影响当前项目,不会干扰系统其他部分
- CMake会自动处理相关的编译器标志
缺点:
- 如果项目中有子模块需要不同标准,可能需要额外处理
- 某些旧的CMake版本可能不完全支持这个指令
实际操作步骤:
- 使用文本编辑器打开ORB-SLAM3根目录下的CMakeLists.txt
- 在
project(ORB_SLAM3)声明之后添加上述set命令 - 保存文件并重新运行cmake和make
2.2 方法二:使用add_compile_options
另一种方法是通过编译选项直接指定标准:
add_compile_options(-std=c++14)优点:
- 更底层,对所有编译器都有效
- 可以与其他编译选项组合使用
- 在某些复杂项目中可能更可靠
缺点:
- 会影响到所有编译单元,可能产生副作用
- 需要手动确保与其他选项的兼容性
选择建议: 对于大多数情况,方法一更为推荐。它更符合现代CMake的最佳实践,且能更好地处理项目依赖关系。只有在遇到特殊编译问题时,才考虑使用方法二。
3. 其他常见问题的解决方案
除了C++标准问题,编译ORB-SLAM3时还可能遇到其他几个典型问题。
3.1 OpenCV的pkg-config问题
错误信息通常为:
Package opencv was not found in the pkg-config search path这是因为OpenCV 4.x默认不生成.pc文件。解决方法:
cd /usr/local/lib sudo mkdir pkgconfig cd pkgconfig sudo touch opencv.pc sudo nano opencv.pc然后在opencv.pc文件中添加以下内容:
prefix=/usr/local exec_prefix=${prefix} includedir=${prefix}/include libdir=${exec_prefix}/lib Name: opencv Description: The opencv library Version:4.0.1 Cflags: -I${includedir}/opencv4 Libs: -L${libdir} -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core3.2 Eigen版本兼容性问题
高版本的Eigen可能会导致编译警告,在资源有限的设备(如Jetson或树莓派)上甚至会导致编译过程卡死。建议:
- 使用Eigen 3.3.x版本
- 如果必须使用新版本,可以尝试禁用某些优化:
add_definitions(-DEIGEN_DONT_VECTORIZE) add_definitions(-DEIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
3.3 内存不足问题
在小型设备上编译时,可能会因内存不足而失败。可以尝试:
- 增加swap空间
- 使用
make -j2而非make -j$(nproc)限制并行编译任务数 - 关闭不必要的程序释放内存
4. 系统版本选择的考量
虽然原始文章建议使用Ubuntu 18.04,但Ubuntu 20.04 LTS仍然是完全可行的选择,只要你注意以下几点:
编译器版本:
- Ubuntu 20.04默认的g++ 9.3.0完全支持C++14
- 如果需要C++17特性,可以考虑安装g++-10或更新版本
依赖管理:
sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-devPython兼容性:
- Ubuntu 20.04默认的Python3版本为3.8
- 某些脚本可能需要调整以适应新版本
提示:如果你确实遇到无法解决的问题,可以考虑使用Docker容器来创建一个与Ubuntu 18.04兼容的编译环境,而不必更换整个系统。
在实际项目中,我发现在Ubuntu 20.04上正确配置后,ORB-SLAM3的运行效率反而比在18.04上有所提升,特别是当利用新版本编译器的优化特性时。关键是要理解每个错误的根源,而不是盲目跟随教程。
