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

相关推荐
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧1 分钟前
C语言_数据结构总结7:顺序队列(循环队列)
c语言·开发语言·数据结构·算法·visualstudio·visual studio
LIUJH12333 分钟前
数据结构——单调栈
开发语言·数据结构·c++·算法
shylyly_40 分钟前
list的模拟实现
数据结构·c++·链表·迭代器·list·list的模拟实现
Tomorrow'sThinker1 小时前
Python零基础学习第三天:函数与数据结构
开发语言·windows·python
元媛媛1 小时前
Python - 轻量级后端框架 Flask
开发语言·python·flask
zhengtianzuo1 小时前
006-获取硬件序列号
c++
钢板兽2 小时前
Java后端高频面经——Spring、SpringBoot、MyBatis
java·开发语言·spring boot·spring·面试·mybatis
爱吃柠檬呀2 小时前
《C陷阱与缺陷》读书笔记(一)
c语言·开发语言·算法·《c陷阱与缺陷》·编写程序
行码棋2 小时前
【Python】omegaconf 用法详解
开发语言·python
awonw2 小时前
[java][基础] 悲观锁 vs 乐观锁
java·开发语言