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

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

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

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

查找 G2O 主要组件

G2O 由多个子模块组成,如 corestuff、求解器(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 并进行链接。

相关推荐
Humbunklung34 分钟前
Rust方法语法:赋予结构体行为的力量
开发语言·后端·rust
萧曵 丶40 分钟前
Rust 内存结构:深入解析
开发语言·后端·rust
算法练习生1 小时前
Qt核心类QWidget及其派生类详解
开发语言·c++·qt
oioihoii1 小时前
C++11标准库算法:深入理解std::none_of
java·c++·算法
1024小神1 小时前
tauri项目在windows上的c盘没有权限写入文件
c语言·开发语言·windows
老虎06271 小时前
数据结构(Java)--位运算
java·开发语言·数据结构
yanjiaweiya1 小时前
云原生-集群管理续
java·开发语言·云原生
Swift社区1 小时前
Swift 解 LeetCode 320:一行单词有多少种缩写可能?用回溯找全解
开发语言·leetcode·swift
写不出来就跑路1 小时前
暑期实习感悟与经验分享:从校园到职场的成长之路
java·开发语言·经验分享·spring boot
No Silver Bullet1 小时前
软件工程功能点估算法常用术语介绍
java·开发语言·软件工程