1. 简介
在使用 G2O(General Graph Optimization)库进行优化问题求解时,通常需要在 CMake 项目中正确配置 G2O 的头文件和库文件路径。由于 G2O 并未提供官方的 CMake 配置文件,因此需要手动编写 FindG2O.cmake
以确保 CMake 能够正确找到 G2O 的依赖项。本文将详细解析 FindG2O.cmake
的编写方式,并介绍其工作原理。

2. CMake 中的 FindG2O.cmake
作用
CMake 允许我们通过 find_package(G2O REQUIRED)
语句查找 G2O 库,而 FindG2O.cmake
负责定义 G2O 头文件路径、库文件路径,并检查必要的依赖项是否存在,以便正确链接 G2O。
3. FindG2O.cmake
代码解析
以下是 FindG2O.cmake
代码的主要部分,分为头文件查找、库文件查找、G2O 组件查找等部分。
查找 G2O 头文件
cpp
FIND_PATH(G2O_INCLUDE_DIR g2o/core/base_vertex.h
${G2O_ROOT}/include
$ENV{G2O_ROOT}/include
$ENV{G2O_ROOT}
/usr/local/include
/usr/include
/opt/local/include
/sw/local/include
/sw/include
NO_DEFAULT_PATH
)
解析:
FIND_PATH
用于查找 G2O 的头文件g2o/core/base_vertex.h
,确保编译时能够找到 G2O 的核心 API。- 头文件查找路径包括:
G2O_ROOT
环境变量下的include
目录- 常见的 Linux 头文件目录(如
/usr/local/include
、/usr/include
)
查找 G2O 库
G2O 包含多个核心库文件,因此需要定义一个 CMake 宏 FIND_G2O_LIBRARY
来查找它们。
cpp
MACRO(FIND_G2O_LIBRARY MYLIBRARY MYLIBRARYNAME)
FIND_LIBRARY("${MYLIBRARY}_DEBUG"
NAMES "g2o_${MYLIBRARYNAME}_d"
PATHS
${G2O_ROOT}/lib/Debug
${G2O_ROOT}/lib
$ENV{G2O_ROOT}/lib/Debug
$ENV{G2O_ROOT}/lib
NO_DEFAULT_PATH
)
FIND_LIBRARY("${MYLIBRARY}_DEBUG"
NAMES "g2o_${MYLIBRARYNAME}_d"
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
/opt/local/lib
/sw/local/lib
/sw/lib
)
FIND_LIBRARY(${MYLIBRARY}
NAMES "g2o_${MYLIBRARYNAME}"
PATHS
${G2O_ROOT}/lib/Release
${G2O_ROOT}/lib
$ENV{G2O_ROOT}/lib/Release
$ENV{G2O_ROOT}/lib
NO_DEFAULT_PATH
)
FIND_LIBRARY(${MYLIBRARY}
NAMES "g2o_${MYLIBRARYNAME}"
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
/opt/local/lib
/sw/local/lib
/sw/lib
)
IF(NOT ${MYLIBRARY}_DEBUG)
IF(MYLIBRARY)
SET(${MYLIBRARY}_DEBUG ${MYLIBRARY})
ENDIF(MYLIBRARY)
ENDIF( NOT ${MYLIBRARY}_DEBUG)
ENDMACRO(FIND_G2O_LIBRARY LIBRARY LIBRARYNAME)
解析:
-
该宏
FIND_G2O_LIBRARY(MYLIBRARY MYLIBRARYNAME)
用于查找 G2O 的静态库或动态库。 -
通过
FIND_LIBRARY
依次在Debug
和Release
目录中查找库文件,确保适用于不同的编译模式。 -
支持多个常见的库文件搜索路径,如
/usr/local/lib
、/usr/lib
等。 -
如果
Debug
版本找不到,则默认使用Release
版本。
查找 G2O 主要组件
G2O 由多个子模块组成,如 core
、stuff
、求解器(solver)、类型(types)等,因此需要调用 FIND_G2O_LIBRARY
查找各个组件。
cpp
#查找核心库
FIND_G2O_LIBRARY(G2O_STUFF_LIBRARY stuff)
FIND_G2O_LIBRARY(G2O_CORE_LIBRARY core)
FIND_G2O_LIBRARY(G2O_CLI_LIBRARY cli)
#查找求解器
FIND_G2O_LIBRARY(G2O_SOLVER_CHOLMOD solver_cholmod)
FIND_G2O_LIBRARY(G2O_SOLVER_CSPARSE solver_csparse)
FIND_G2O_LIBRARY(G2O_SOLVER_CSPARSE_EXTENSION csparse_extension)
FIND_G2O_LIBRARY(G2O_SOLVER_DENSE solver_dense)
FIND_G2O_LIBRARY(G2O_SOLVER_PCG solver_pcg)
FIND_G2O_LIBRARY(G2O_SOLVER_SLAM2D_LINEAR solver_slam2d_linear)
FIND_G2O_LIBRARY(G2O_SOLVER_STRUCTURE_ONLY solver_structure_only)
FIND_G2O_LIBRARY(G2O_SOLVER_EIGEN solver_eigen)
#查找数据类型支持库
FIND_G2O_LIBRARY(G2O_TYPES_DATA types_data)
FIND_G2O_LIBRARY(G2O_TYPES_ICP types_icp)
FIND_G2O_LIBRARY(G2O_TYPES_SBA types_sba)
FIND_G2O_LIBRARY(G2O_TYPES_SCLAM2D types_sclam2d)
FIND_G2O_LIBRARY(G2O_TYPES_SIM3 types_sim3)
FIND_G2O_LIBRARY(G2O_TYPES_SLAM2D types_slam2d)
FIND_G2O_LIBRARY(G2O_TYPES_SLAM3D types_slam3d)
解析:
- 通过
FIND_G2O_LIBRARY
查找 G2O 组件,包括求解器(如solver_csparse
)、类型支持库(如types_slam2d
),确保 G2O 功能完整。
检查 G2O 是否成功找到
cpp
SET(G2O_SOLVERS_FOUND "NO")
IF(G2O_SOLVER_CHOLMOD OR G2O_SOLVER_CSPARSE OR G2O_SOLVER_DENSE OR G2O_SOLVER_PCG OR G2O_SOLVER_SLAM2D_LINEAR OR G2O_SOLVER_STRUCTURE_ONLY OR G2O_SOLVER_EIGEN)
SET(G2O_SOLVERS_FOUND "YES")
ENDIF()
#只要至少找到一个求解器,就设置 G2O_SOLVERS_FOUND = YES,确保 G2O 可用。
总结
FindG2O.cmake
负责自动查找 G2O 头文件和库文件,使 CMake 可以轻松集成 G2O。- 通过
FIND_G2O_LIBRARY
宏查找 G2O 的各个子模块,包括核心库、求解器和数据类型库。 - 通过
G2O_FOUND
变量确认 G2O 是否被正确找到,以便 CMake 配置 G2O 依赖。
这样,我们就可以在 CMake 项目中使用 find_package(G2O REQUIRED)
直接找到 G2O 并进行链接。