在Ubuntu 20.04上搞定ORB-SLAM3编译:一个C++14标准设置救了我的命 在Ubuntu 20.04上搞定ORB-SLAM3编译一个C14标准设置救了我的命如果你正在Ubuntu 20.04上尝试编译ORB-SLAM3却在make阶段被一连串错误 1卡住这篇文章就是为你准备的。作为一个在计算机视觉领域深耕多年的开发者我深知这种看似简单的编译错误可能让人抓狂——尤其是当网上大多数教程都只告诉你按照步骤来却没人解释为什么会出现这些错误时。ORB-SLAM3作为目前最先进的视觉SLAM系统之一其代码质量相当高但它的编译过程却可能成为新手的第一道门槛。特别是在Ubuntu 20.04这个长期支持版本上由于系统默认的编译器版本和C标准设置你很可能会遇到各种奇怪的编译错误。本文将深入剖析这些错误的根源并提供经过实战验证的解决方案。1. 理解编译错误的本质当你看到终端中不断滚动的错误信息时第一反应可能是我哪里做错了。但实际上这些错误大多源于一个简单但容易被忽视的问题C标准版本不匹配。典型的错误输出看起来像这样make[2]: *** [CMakeFiles/ORB_SLAM3.dir/build.make:375CMakeFiles/ORB_SLAM3.dir/src/MLPnPsolver.cpp.o] 错误 1 make[2]: *** [CMakeFiles/ORB_SLAM3.dir/build.make:76CMakeFiles/ORB_SLAM3.dir/src/Tracking.cc.o] 错误 1 ... make: *** [Makefile:84all] 错误 2这些错误看似分散在不同的源文件中但它们都有一个共同点都是由于编译器无法正确处理代码中的C14特性导致的。ORB-SLAM3大量使用了C14标准引入的特性而Ubuntu 20.04默认的g编译器(g 9.3.0)虽然支持C14但CMake默认可能不会启用。1.1 为什么C标准如此重要C标准决定了编译器如何处理你的代码。不同标准之间可能存在语法和功能上的差异C标准主要特性兼容性C11auto类型推导, lambda表达式广泛支持C14泛型lambda, 二进制字面量需要显式启用C17结构化绑定, if constexpr较新编译器ORB-SLAM3特别依赖C14的几个关键特性泛型lambda表达式用于灵活的算法封装变量模板用于数学运算的通用实现自动返回类型推导简化模板代码2. 两种解决方案的深度对比解决这个问题的核心在于告诉CMake使用C14标准编译。有两种主要方法可以实现这一点各有优缺点。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和make2.2 方法二使用add_compile_options另一种方法是通过编译选项直接指定标准add_compile_options(-stdc14)优点更底层对所有编译器都有效可以与其他编译选项组合使用在某些复杂项目中可能更可靠缺点会影响到所有编译单元可能产生副作用需要手动确保与其他选项的兼容性选择建议 对于大多数情况方法一更为推荐。它更符合现代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完全支持C14如果需要C17特性可以考虑安装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上有所提升特别是当利用新版本编译器的优化特性时。关键是要理解每个错误的根源而不是盲目跟随教程。