当前位置: 首页 > news >正文

在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++11auto类型推导, 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版本可能不完全支持这个指令

实际操作步骤:

  1. 使用文本编辑器打开ORB-SLAM3根目录下的CMakeLists.txt
  2. project(ORB_SLAM3)声明之后添加上述set命令
  3. 保存文件并重新运行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_core

3.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仍然是完全可行的选择,只要你注意以下几点:

  1. 编译器版本

    • Ubuntu 20.04默认的g++ 9.3.0完全支持C++14
    • 如果需要C++17特性,可以考虑安装g++-10或更新版本
  2. 依赖管理

    sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
  3. Python兼容性

    • Ubuntu 20.04默认的Python3版本为3.8
    • 某些脚本可能需要调整以适应新版本

提示:如果你确实遇到无法解决的问题,可以考虑使用Docker容器来创建一个与Ubuntu 18.04兼容的编译环境,而不必更换整个系统。

在实际项目中,我发现在Ubuntu 20.04上正确配置后,ORB-SLAM3的运行效率反而比在18.04上有所提升,特别是当利用新版本编译器的优化特性时。关键是要理解每个错误的根源,而不是盲目跟随教程。

http://www.cnnetsun.cn/news/2691064.html

相关文章:

  • 暗黑破坏神2存档编辑器终极指南:5分钟实现角色自由定制,告别复杂十六进制编辑
  • STM32C542开发(1)----点亮LED
  • Grok犯下183宗罪、4天“灭国”,GPT直接把自己“饿死”!让AI“统治”社会15天,只有Claude撑到了最后
  • Avidemux视频编辑神器:3分钟学会开源视频剪辑的终极指南
  • 基于Arduino Uno的温湿度数据记录器:从传感器采集到SD卡存储
  • 基于GreenPAK可编程逻辑的步进电机控制器设计与实现
  • 终极免费方案:WandEnhancer如何让你的游戏修改器体验升级
  • 树莓派+Neopixel打造IT服务状态可视化云:硬件搭建与软件实现全解析
  • 如何在Mac上高效抢购火车票:12306ForMac专业工具实战指南
  • R语言实战:手把手教你安装Decontam、SCRUB和FEAST三大微生物污染处理包(含BiocManager避坑指南)
  • 从广播星历切换到精密星历:GPS/Galileo/BDS多系统DCB/TGD改正避坑指南(附Python代码片段)
  • YimMenu终极指南:GTA5最强开源模组菜单完全解析
  • 从改机到隐藏Root:用雷电模拟器+Magisk+LSPosed打造手游防检测环境
  • VCO-CARE技术:革新皮肤电活动监测的无校准模拟前端
  • 基于ESP32与MQTT的智能植物监测系统:从传感器到云端全链路实践
  • 别再只用Etcher了!资深极客教你用Linux dd命令搞定SD卡系统镜像的精准克隆与压缩备份
  • 从‘松类’到‘数字资产’:手把手教你用Blender为华山松、白皮松创建3D模型(附植物渲染技巧)
  • AI 硬件 — 算力 —Token 的关系
  • 告别串口扩展坞!用CH348L芯片低成本搞定工控多设备调试(兼容3.3V/5V电平)
  • Qt QChart实战:从零封装一个工业监控风格的曲线图(支持缩放、图例、多曲线)
  • 到底HTTP 请求是如何被 PHP 接收的?
  • 太阳能乐高小车:从光能到动能的DIY能源系统实践
  • 实战解析:开源Windows Defender控制工具defender-control深度指南
  • 从电路设计到物联网硬件实践:ESP32智能监测器全流程开发指南
  • 3分钟掌握AI抠图神器:ComfyUI-BiRefNet-ZHO让你轻松实现专业级背景去除
  • 基于Arduino与物联网的智能情感交互灯:从3D打印到云端通信全流程实践
  • 基于Arduino与红外遥控的健壮计算器:从状态机设计到工程实践
  • 免费视频翻译神器:5分钟让视频跨越语言障碍的完整指南
  • 云手机 网页版稳定性强
  • 从单模型到多模型协作:构建高效AI编程工作流的实战指南