1. 方案选型VS 2022 vcpkg g2o这套组合究竟好在哪1.1 这套配置解决的是哪一类痛点做机器人、自动驾驶或者三维视觉方向的朋友对g2o这个名字应该都不陌生。g2oGeneral Graph Optimization是一个专门做图优化和参数优化的C库SLAM的前端跑完了回环检测也出结果了后端怎么把这些带噪声的位姿约束整体拧一遍g2o基本是绕不开的标配工具。但g2o的配置一直是公认的费劲事。它本身源码依赖一堆底层库Eigen、稀疏矩阵求解器、各类型定义组件传统手动编译流程里每一层依赖都要单独下载、编译、配置中途任何一个版本不匹配都会让整个工程卡壳。我之前用老办法踩坑折腾两天才跑起来一个最小示例换台电脑重新配又花了一整天。后来我把工作流切到了VS 2022 vcpkg这套组合从环境准备到跑通g2o优化程序基本上十几分钟就能完成。这篇文章把这条我认为最省心的路径完整写下来目标是让卡在配置环节的人照着走一遍就能结束战斗。这篇文章适合三类人刚进入SLAM/机器人方向需要在Windows上搭C开发环境的初学者在Linux上写代码很顺突然被要求在Windows上出demo的开发者被手动编译g2o折磨过想找一个稳定可复现方案的工程师。1.2 三种安装g2o的主流方案对比g2o的安装方式并不止一种我大致整理了一下常见路线方案大体流程优势短板源码编译克隆源码逐个解析依赖CMake生成工程后自己编译可修改源码构建细节透明依赖梳理量大Eigen/CSparse等版本敏感很耗时vcpkg安装一条install命令交付所有库和依赖自动适配VS快速、可复现、依赖自动解决想对g2o本身做深度定制稍麻烦第三方预编译包直接下载编译好的库文件使用速度最快和编译器、依赖库匹配风险高出问题难排查源码编译并不是完全没必要比如你要动手改g2o内部算法做二次研究那自己编译是唯一选择。但如果你只是想正常使用g2o做图优化而不是研究g2o本身那么vcpkg的价值就非常明显了它会自动处理所有依赖关系装g2o的同时把Eigen、稀疏求解器、类型模块等底层包全部处理到位版本是验证过的组合不需要自己操心A版本配不配B版本。vcpkg还有一个很大的优势就是它对VS 2022做了深度支持。装完库之后一条integrate install命令就能让VS工程自动识别include路径和库路径对平时习惯用VS的开发者来说非常友好。2. 环境准备把VS 2022和vcpkg的地基打好2.1 安装VS 2022这一步很多人一开始就踩坑安装VS看起来是再基础不过的事情但实际踩坑率相当高。最常见的现象是VS明明装好了新建项目开始写C结果编译时报找不到MSBuild、找不到Windows SDK、找不到cl.exe。罪魁祸首通常是安装时没有勾选合适的工作负载。正确的做法是在Visual Studio Installer里安装VS 2022时务必勾选“使用C的桌面开发”这个工作负载。它默认并不总是被勾选只勾默认组件的话装完主要支持C#和基础编辑器。勾选“使用C的桌面开发”后MSVC编译器、Windows SDK、CMake工具这些才会一并安装。装完以后可以在“工具—获取工具和功能”里随时补装组件不用重新安装整个VS。另外在“单个组件”页面里建议顺带把“C CLang工具”或者“适用于最新v143生成工具的C CMake工具”这类和CMake、工具链相关的组件勾上。如果你的项目会用到Qt或者其他依赖较多框架的库可以把“C MFC”相关组件也一并装上免得后面跑vcpkg时某些依赖库报缺运行库。环境验证很简单打开“开始菜单”里的“开发人员命令提示符”输入cl能看到编译器版本信息就说明C工具链正常。2.2 克隆vcpkg仓库并执行初始化vcpkg用Git管理仓库所以电脑上需要先有Git环境。没有Git的先去安装一个Git客户端这个是硬前提。取得vcpkg代码最推荐的方式是直接克隆仓库git clone https://github.com/microsoft/vcpkg.git cd vcpkg这里有一个很实际的建议vcpkg仓库路径不要放得太深。Windows下编译时如果源码路径过长容易触发路径长度限制导致莫名其妙的构建失败。我习惯把它放到类似C:\src\vcpkg这种浅路径。别小看这个操作关键时刻能帮你省掉很多烦躁。初始化在Windows上通过批处理完成bootstrap-vcpkg.bat这条命令会生成vcpkg.exe同时把vcpkg内置的CMake工具也准备好。执行结束后可以用下面命令验证.\vcpkg version注意vcpkg的命令需要在vcpkg目录下执行。如果不想每次切换目录可以把vcpkg.exe所在路径加入系统环境变量PATH。后续所有示例都假设你已经在PATH里配置好了vcpkg或者是在vcpkg目录下执行的。3. 正式安装g2o命令只有一条但细节不能马虎3.1 用vcpkg安装g2o以及常用编译特性安装g2o的命令非常简单vcpkg install g2o:x64-windows这里:x64-windows是vcpkg的triplet表示编译64位Windows版本。有的教程会省略这个后缀直接写vcpkg install g2o那样会走默认triplet。在x64机器上通常结果一致但为了构建目标明确建议每次都写清楚指定。执行过程中vcpkg会先分析g2o的依赖关系把Eigen等底层库编译好再编译g2o各个模块。第一次安装会比较耗时因为CSparse、SuiteSparse这些稀疏矩阵求解依赖是真正参与编译的不是复制几个头文件就完事。根据机器性能整个过程一般在几分钟到十几分钟。g2o在vcpkg里还提供了一些可选特性最常用的是tools它会把g2o自带的图形化工具g2o_viewer编译出来。这个工具在做SLAM调试时非常有用能直观查看图结构的顶点、边、误差分布。需要的话安装命令是vcpkg install g2o[tools]:x64-windows想查看当前g2o端口支持哪些特性可以执行vcpkg search g2o vcpkg port info g2o后者会列出Features和说明信息。装完以后再想补充特性不需要把整个包重装一遍vcpkg会针对特性做增量编译。3.2 验证安装结果头文件、库文件、CMake配置都要确认安装完成后vcpkg会打印Summary信息列出已安装的包和triplet。更稳妥的做法是直接到目录里检查产物。以默认的x64-windows路径为例安装后的目录结构大致如下vcpkg\ installed\ x64-windows\ include\g2o\... # g2o头文件 include\Eigen\... # Eigen头文件 lib\ # Release模式的库 debug\lib\ # Debug模式的库 share\g2o\ # CMake配置文件 tools\g2o\ # tools特性编译的工具检查include\g2o下有没有core、types、solvers这些子目录再看一眼lib目录里的.lib文件。g2o在Windows上的库文件命名规律一般是g2o_core.lib、g2o_stuff.lib、g2o_types_slam3d.lib一个模块对应一个库文件。这里要特别说一下vcpkg的设计它把Release和Debug版本的库分开放置lib对应Releasedebug\lib对应Debug。这解决了过去手动区分调试库和发布库的麻烦后面在VS里链接时根本不需要自己切换目录。share\g2o里存放的是CMake配置文件。这意味着走CMake工程路线时可以用一行find_package(g2o CONFIG REQUIRED)引入整个库不必手工硬编码一堆包含路径。4. 在VS 2022中把g2o真正用起来4.1 全局集成模式一条命令让所有VS工程自动识别库库装好了接下来要让VS工程能认识这些库。这一步vcpkg提供了全局集成命令vcpkg integrate install这条命令会在系统层面注册MSBuild集成把vcpkg管理的include目录、lib目录、debug目录信息注入到VS工程属性里。执行后新建或者打开的C工程在工程属性里会出现“vcpkg”配置项只要确保“使用vcpkg”是“是”项目就能自动找到g2o的头文件和库文件。这个集成的体验确实是“真香”级别的。以前手动配置g2o每次新建一个工程就要在VC目录、链接器附加目录、附加依赖项里重复填一堆路径漏一个就链接报错。有了全局集成之后这条线基本断了。同时也要留意一点integrate install作用的是整台机器上所有VS工程。如果你有几个工程不想用vcpkg需要在对应工程的属性里把“使用vcpkg”设为“否”。另外这种集成方式针对的是基于MSBuild的VS工程如果用了其他构建系统比如Qt的qmake或者纯命令行make那要用另外的集成思路。4.2 在CMake工程中链接g2o如果只是临时验证一个最小示例直接建VS控制台项目就行。但如果这是正经项目我还是建议用CMake组织工程尤其在SLAM这类依赖复杂的场景CMake的可读性和可移植性要好得多。用CMake配合vcpkg时需要指定vcpkg的工具链文件cmake -B build -S . -DCMAKE_TOOLCHAIN_FILEC:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake然后在CMakeLists.txt中这样写cmake_minimum_required(VERSION 3.22) project(g2o_example) find_package(g2o CONFIG REQUIRED) add_executable(demo main.cpp) target_link_libraries(demo PRIVATE g2o::core g2o::stuff )这里用到了g2o导出的CMake target。不同小版本的g2o在导出target命名上可能有差异如果g2o::core没有被识别到share/g2o目录里查看CMake导出配置可以看到所有可用的target名称。在VS 2022里创建CMake工程时强烈建议把工具链配置固化到CMakePresets.json。这样团队协作时成员只要拉下仓库用VS打开就能进入同一套构建环境不需要记住一长串CMake参数。4.3 写一个最小的g2o优化示例验证整个环境配置成不成功写代码跑一遍是最直接的检验方式。下面这个示例做的是创建一个图优化器配置LM迭代算法添加两个位姿顶点和一条边约束然后执行优化。它不解决什么实际问题目的就是确认include路径、库文件、链接配置、运行时依赖全部正常。#include iostream #include memory #include g2o/core/sparse_optimizer.h #include g2o/core/block_solver.h #include g2o/core/optimization_algorithm_levenberg.h #include g2o/solvers/csparse/linear_solver_csparse.h #include g2o/types/slam3d/vertex_se3.h #include g2o/types/slam3d/edge_se3.h int main() { g2o::SparseOptimizer optimizer; optimizer.setVerbose(true); using BlockSolverType g2o::BlockSolverg2o::BlockSolverTraits6, 3; using LinearSolverType g2o::LinearSolverCSparseBlockSolverType::PoseMatrixType; optimizer.setAlgorithm(new g2o::OptimizationAlgorithmLevenberg( std::make_uniqueBlockSolverType( std::make_uniqueLinearSolverType()) )); // 创建两个位姿顶点 g2o::VertexSE3* v1 new g2o::VertexSE3(); v1-setId(0); v1-setEstimate(g2o::SE3Quat()); optimizer.addVertex(v1); g2o::VertexSE3* v2 new g2o::VertexSE3(); v2-setId(1); v2-setEstimate(g2o::SE3Quat()); optimizer.addVertex(v2); // 在两个顶点之间加一条边模拟一次相对测量 g2o::EdgeSE3* edge new g2o::EdgeSE3(); edge-setVertex(0, v1); edge-setVertex(1, v2); edge-setMeasurement(g2o::SE3Quat()); Eigen::Matrixdouble, 6, 6 info Eigen::Matrixdouble, 6, 6::Identity(); edge-setInformation(info); optimizer.addEdge(edge); optimizer.initializeOptimization(); optimizer.optimize(5); std::cout g2o environment is ok std::endl; return 0; }把这个文件放到工程里编译运行如果正常打印g2o environment is ok整个配置链路就算彻底跑通了。如果这步卡住重点看一下5.2节里关于链接失败的内容绝大多数问题都出在那一块。5. 常见问题与排错实录5.1 vcpkg提示找不到合适的版本或匹配的triplet这类问题多半不是因为网络而是因为vcpkg仓库版本太旧。vcpkg的端口定义文件是随着仓库一起更新的如果本地vcpkg还是几个月之前克隆的可能根本没有g2o的新版本记录或者端口定义已经变了。处理办法是先把vcpkg仓库更新到最新git pull更新完重新执行bootstrap-vcpkg.bat然后再次安装。我遇到过的几次“安装失败”“找不到版本”的怪问题最终都是vcpkg仓库太老引起的切到最新版之后一切正常。还有一种类似情况是VS的MSVC工具集版本过旧。vcpkg在安装包时对编译器版本有要求如果VS 2022缺少最新的v143生成工具编译依赖库时会直接报错。这时打开Visual Studio Installer把“最新v143生成工具”相关组件补上即可。5.2 编译通过链接时出现大量“无法解析的外部符号”LNK2019和LNK2001是配置g2o时期出现率最高的错误。典型画面是编译阶段非常顺利头文件全都能找到一到链接阶段终端或输出窗口刷出几十条未解析符号几乎全都和g2o::有关。遇到这种情况按排查顺序来检查VS工程属性里“使用vcpkg”是否为“是”。检查当前配置平台是不是x64不要用Win32平台去链接x64库。打开“链接器—输入—附加依赖项”确认需要用到模块的.lib都添加了。如果是CMake工程检查target_link_libraries里是否真的链接了对应模块。用到EdgeSE3就必须链接g2o_types_slam3d相关模块只链接core是过不去的。额外提醒一点在VS里手动添加多个.lib时依赖顺序也有讲究。基本原则是被依赖的库放在后面。比如g2o_types_slam3d依赖g2o_core那么列表里g2o_core.lib要排在g2o_types_slam3d.lib后面。5.3 Debug/Release库混用导致运行期诡异崩溃vcpkg默认在安装时会同时编译Release和Debug两种变体Release库放在lib目录Debug库放在debug\lib目录。VS集成会自动根据工程配置选择对应目录正常情况下不需要干预。但如果你手动改动过库目录设置就很容易出现编译时用的是Debug配置链接的却是Release库或者反过来。这种混用有时候不会在编译链接阶段报错而是在运行到某个数据清理、内存释放时突然崩溃非常难排查。这类问题最好的解决方式就是让配置保持统一。工程用Debug模式明确确认链接的是debug\lib里的库用Release模式链接lib目录里的库。如果不想分心直接全部用Release x64配置跑通整个流程再回头处理Debug配置。5.4 和其他库出现Eigen版本冲突g2o底层强依赖Eigen而且对Eigen版本非常敏感。如果工程里同时用了PCL、Sophus等同样依赖Eigen的库很容易出现Eigen版本不一致导致的编译错误表现形式通常是报找不到头文件、模板展开失败、Eigen版本太老之类。vcpkg在装g2o时已经拉好了一个经过验证的Eigen版本。如果你在自己的工程里又手动指定了另一个Eigen路径那么编译器实际用哪个Eigen取决于“附加包含目录”的搜索顺序。最简单的处理方式把自己手动添加的Eigen路径删掉只保留vcpkg管理的Eigen。如果项目里确实需要明确知道Eigen版本可以直接让vcpkg显式安装Eigenvcpkg install eigen:x64-windows这样至少版本号是明牌排查问题时有据可依。5.5 vcpkg安装过程中下载慢或反复超时vcpkg安装g2o时需要从上游下载源码包网络状态不好时会触发下载中断。这通常不是什么致命问题vcpkg有本地缓存和断点续传重复执行就好。几个实用技巧第一次下载超时后重新执行同一条安装命令vcpkg会跳过已完成的步骤继续干活。不要把vcpkg仓库放在带中文、空格或者其他特殊字符的路径下源码包下载和解压时可能触发编码问题。安装过程中尽量别强行中断中断次数多了缓存容易出问题。如果确认缓存损坏删除vcpkg目录下的downloads文件夹再重试。5.6 开了tools特性但g2o_viewer运行不起来g2o[tools]安装完成后工具一般会出现在vcpkg\installed\x64-windows\tools\g2o目录下。双击没反应或者启动报错最常见的原因是运行时缺少Qt动态库。g2o_viewer基于Qt开发vcpkg编译时会自动带上Qt库但运行时可能需要把Qt的dll目录加入PATH或者从命令行带参数启动。其实如果只是开发调试很多场景不一定要打开GUI。把SparseOptimizer的setVerbose(true)打开优化过程的迭代信息会直接输出到终端反而更适合快速验证结果。6. 配置完成之后的进阶路线环境跑通只是开始接下来可以做几件事让这套配置发挥更大价值。第一跑一个真正的位姿图优化示例。g2o最核心的应用是处理带噪声的位姿图构造一串二维或三维位姿节点加上带噪声的边约束然后让g2o把累计漂移消除掉。跑通以后把优化前后的位姿画出来比较误差的变化能让人对图优化有非常直观的理解。第二研究一下g2o源码里的示例目录。vcpkg安装的是编译产物但把g2o源码也拉下来里面会有大量现成demo覆盖2D SLAM、3D SLAM、Bundle Adjustment等典型场景。挑一个最贴近项目的demo编译运行后边看边改是掌握g2o最快的一条路。第三把项目工程改成CMake Presets管理模式。将vcpkg工具链路径、编译配置、输出目录固化在CMakePresets.json里团队成员拉下代码后用VS直接打开就能进入同一套构建环境。这一步提升的不仅是配置效率更重要的是可复现性。我个人的经验是配置环境最怕的不是慢而是不透明——换个人、换台机器就装不出来。vcpkg把依赖和版本都锁定住了配合CMake Presets基本能做到“一次配置处处复现”。如果在配置中遇到上面没写到的奇怪问题建议先回退一步把vcpkg更新到最新确认VS相关组件齐全确认编译平台是x64再重新走一遍。这条流程我自己完整走过多次每次都能在二十分钟内从零恢复环境。配置这个东西第一次熟悉以后后面就是机械操作了。
阅读完成 · 觉得有帮助?