4.CMAKE_LEARNING

4 类ORBSLAM2工程框架CMAKE

主要由下列几部分构成(删减了相对不重要部分)

├── build					# cmake生成文件存放位置
├── CMakeLists.txt			
├── cmake_modules			# cmake模块,链接本地其他库
│   └── FindEigen3.cmake
├── Examples				# 工程示例可存在多个文件夹
│   ├── Monocular
│   ├── RGB-D
│   ├── ROS
│   └── Stereo
├── include					# 个人库文件
├── lib						# 生成动态库位置
├── README.md				# 工程说明markdown文本
├── src						# 个人源文件			
└── Thirdparty				# 第三方库

按照类似结构,构建了一个读取数据集并展示的DEMO

├── build
├── CMakeLists.txt
├── cmake_modules
│   └── FindEigen3.cmake
├── Examples
│   └── Dataset_DEMO
│       └── main.cpp
├── include
│   ├── Camera_pose.h
│   ├── custom_struct.h
│   └── slam_visualizer.h
├── lib
└── src
    ├── Camera_pose.cpp
    └── slam_visualizer.cpp

效果如下:

4.1相关库版本

4.1.1Eigen3.3.7

locate eigen3
# 找到路径Eigen路径中的src/Core/util/,我的路径是/usr/include/eigen3/Eigen/src/Core/util/
cd /usr/include/eigen3/Eigen/src/Core/util/
vim Macros.h #打开Macros.h
其中
##########################
#define EIGEN_WORLD_VERSION 3
#define EIGEN_MAJOR_VERSION 3
#define EIGEN_MINOR_VERSION 7
##########################
即为版本号

4.1.2opencv4.2.0

终端输入

# 查看opencv3以及以下版本:  
pkg-config --modversion opencv  
# 查看opencv4版本:  
pkg-config --modversion opencv4

4.1.3Pangolin

4.2

CMakeList.txt

# 限制cmake版本
cmake_minimum_required(VERSION 2.8)
# 设置工程名为NEWBMI,可通过预定义变量PROJECT_NAME读取
project(DEMO1)
# 如果没有确定CMAKE类型则设置为Release类型
IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE Release)
ENDIF()
# 输出Build type
# MESSAGE("-- Build type: " ${CMAKE_BUILD_TYPE})
# 设置C和C++编译标志,' -Wall '标志启用所有警告,' -O3 '标志启用最高级别的优化,' -march=native '标志针对主机的体系结构优化代码
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  -Wall  -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall   -O3 -march=native")
# 检查C++编译器是否支持给定的标志
include(CheckCXXCompilerFlag)
# 使用标志-std=c++11编译程序,并将结果存储在变量COMPILER_SUPPORTS_CXX11中
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
   # 将编译器的C++标准设置为C++14
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
   # 添加宏定义 调试用
   add_definitions(-DCOMPILEDWITHC11)
   message(STATUS "Using flag -std=c++14.")
elseif(COMPILER_SUPPORTS_CXX0X)
   # 将编译器的C++标准设置为C++0x
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
   # 添加宏定义 调试用
   add_definitions(-DCOMPILEDWITHC0X)
   message(STATUS "Using flag -std=c++0x.")
else()
   message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
endif()
# 加入cmake_modules的位置
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
MESSAGE("-- Set up project-related libraries")
############################################################################################################################
# “QUIET”选项会抑制“find_package”命令的输出
find_package(OpenCV 4.2 QUIET)
if(NOT OpenCV_FOUND)
   find_package(OpenCV 2.4.3 QUIET)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
   endif()
else()
   MESSAGE("-- opencv version is : 4.2.0")
endif()
# NO_MODULE选项指定FindEigen3.cmake 
find_package(Eigen3 3.1.0 REQUIRED NO_MODULE)
#添加Pangolin依赖
find_package(Pangolin REQUIRED)
include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
${EIGEN3_INCLUDE_DIR}
${Pangolin_INCLUDE_DIRS}
)
# 指定应放置编译库文件的目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
# 添加动态库
add_library(${PROJECT_NAME} SHARED
src/Camera_pose.cpp
src/slam_visualizer.cpp
)
# 链接指定库
target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
)
# 构建示例
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Dataset_DEMO)
add_executable(datasetDemo Examples/Dataset_DEMO/main.cpp)
target_link_libraries(datasetDemo ${PROJECT_NAME})

子模块FindEigen3.cmake

# - 寻找Eigen3库
#
# 本模块可以设置Eigen3最小要求版本
# 如果没设置Eigen3_FIND_VERSION
if(NOT Eigen3_FIND_VERSION)
  if(NOT Eigen3_FIND_VERSION_MAJOR)
    set(Eigen3_FIND_VERSION_MAJOR 2)
  endif(NOT Eigen3_FIND_VERSION_MAJOR)
  if(NOT Eigen3_FIND_VERSION_MINOR)
    set(Eigen3_FIND_VERSION_MINOR 91)
  endif(NOT Eigen3_FIND_VERSION_MINOR)
  if(NOT Eigen3_FIND_VERSION_PATCH)
    set(Eigen3_FIND_VERSION_PATCH 0)
  endif(NOT Eigen3_FIND_VERSION_PATCH)
  # 将主、次和补丁版本号分别设置为2,91和0
  # 保存到Eigen3_FIND_VERSION中
  set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
endif(NOT Eigen3_FIND_VERSION)

# CMAKE宏 ,在主cmake文件中以读取Eigen情况下才会调用宏
macro(_eigen3_check_version)
  # 读取位于${eigen3_include_dir}/eigen/src/core/util/中的macros.h文件 并存入_eigen3_version_header
  file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
  # 从macros.h匹配 define EIGEN_WORLD_VERSION [0-9] ,获取数字存入_eigen3_world_version_match
  string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
  set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
  string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
  set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
  string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
  set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
  # 设置从macros.h读取到的版本号存入EIGEN3_VERSION
  set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
  # 读取的EIGEN3_VERSION 小于 设置的Eigen3_FIND_VERSION
  if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
    set(EIGEN3_VERSION_OK FALSE)
  else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
    set(EIGEN3_VERSION_OK TRUE)
  endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
  # 输出EIGEN3_VERSION_OK 区分版本大于设置版本还是小于设置版本
  
  # 如果读取版本小于设置版本
  if(NOT EIGEN3_VERSION_OK)
    message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
                   "but at least version ${Eigen3_FIND_VERSION} is required")
  endif(NOT EIGEN3_VERSION_OK)
endmacro(_eigen3_check_version)

# 如果设置了 EIGEN3_INCLUDE_DIR
if (EIGEN3_INCLUDE_DIR)
  # makefile cache文件中已经读取
  # 通过宏读取版本号
  _eigen3_check_version()
  set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})

else (EIGEN3_INCLUDE_DIR)

  # 判断是否为win32
  if (WIN32)
    set(EIGEN_ADDITIONAL_SEARCH_PATHS ${EIGEN_ADDITIONAL_SEARCH_PATHS} "C:/Program Files/Eigen/include" "C:/Program Files (x86)/Eigen/include")
  endif(WIN32)
  # 寻找signature_of_eigen3_matrix_library文件 从${CMAKE_INSTALL_PREFIX}/include(CMAKE_INSTALL_PREFIX默认为usr/local),${EIGEN_ADDITIONAL_SEARCH_PATHS},${KDE4_INCLUDE_DIR}
  find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
      PATHS
      ${CMAKE_INSTALL_PREFIX}/include
      ${EIGEN_ADDITIONAL_SEARCH_PATHS}
      ${KDE4_INCLUDE_DIR}
      PATH_SUFFIXES eigen3 eigen
    )
   # PATH_SUFFIXES:在每个搜索路径的子目录下搜索eigen3 eigen
  # 读取完成 利用宏检索Eigen版本
  if(EIGEN3_INCLUDE_DIR)
    _eigen3_check_version()
  endif(EIGEN3_INCLUDE_DIR)
  include(FindPackageHandleStandardArgs)
  # FindPackageHandleStandardArgs.cmake 是 CMake 内置的一个模块,它用于定义一个宏,可以用于在找到一个包之后,对其进行一些标准化的处理,它通常用于在CMake中查找和配置外部库或工具包
  find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
  # 将命名的缓存变量标记为高级
  mark_as_advanced(EIGEN3_INCLUDE_DIR)
endif(EIGEN3_INCLUDE_DIR)

在build文件夹下

cmake ..
make

在Examples/Dataset_DEMO/中会生成可执行文件,在该目录下执行

./datasetDemo  /home/whf/文档/ORB_SLAM2/data/rgbd_dataset_freiburg1_room/

后面为数据集文件夹路径,数据集文件格式为

├── accelerometer.txt
├── depth
├── depth.txt
├── groundtruth.txt
├── rgb
└── rgb.txt

Github地址

posted @ 2023-11-12 20:36  DOinging  阅读(27)  评论(0)    收藏  举报