在 cmake_modules 目录下编写 FindG2O.cmake 以集成 G2O

发布于:2025-03-12 ⋅ 阅读:(19) ⋅ 点赞:(0)

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 头文件

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 来查找它们。

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 依次在 DebugRelease 目录中查找库文件,确保适用于不同的编译模式。

  • 支持多个常见的库文件搜索路径,如 /usr/local/lib/usr/lib 等。

  • 如果 Debug 版本找不到,则默认使用 Release 版本。

查找 G2O 主要组件

G2O 由多个子模块组成,如 corestuff、求解器(solver)、类型(types)等,因此需要调用 FIND_G2O_LIBRARY 查找各个组件。

#查找核心库
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 是否成功找到

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 并进行链接。