第九章0.4的CMakeLists.txt结构
最开始看这一章的时候,将CMakeLists.txt部分跳过了,没有看。后来看高博RGBD-SLAM时候,第一讲降到了cmake的用法,发现有新的东西,又回头看:
最原始的0.4文件夹下是这样的:
有最基本的bin、lib、include、src。还有需要的cmake_modules、config和test文件夹。当然还有CMakeList.txt。
先来看根目录下的这个CMakeList.txt:
#定义需求版本和工程名称#
cmake_minimum_required( VERSION 2.8 )
project ( myslam )
#cmake相关的一些设定#
set( CMAKE_CXX_COMPILER "g++" )
set( CMAKE_BUILD_TYPE "Release" )
set( CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3" )
#添加单独的cmake模块和设定可执行文件与库文件的输出路径#
list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules )
set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin )
set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib )
############### 第三方库的头文件include;dependencies ######################
# Eigen
include_directories( "/usr/include/eigen3" )
# OpenCV
find_package( OpenCV 3.1 REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Sophus
find_package( Sophus REQUIRED )
include_directories( ${Sophus_INCLUDE_DIRS} )
# G2O
find_package( G2O REQUIRED )
include_directories( ${G2O_INCLUDE_DIRS} )
#第三方的库文件路径参数#
set( THIRD_PARTY_LIBS
${OpenCV_LIBS}
${Sophus_LIBRARIES}
g2o_core g2o_stuff g2o_types_sba
)
############### 自己写的头文件include。dependencies ######################
include_directories( ${PROJECT_SOURCE_DIR}/include )
#增加子目录#
add_subdirectory( src )
add_subdirectory( test )
然后src中的CMakeList.txt:
#由此一堆生成自己写的一个库文件,名为myslam,这个库是链接在第三方库基础上的。
add_library( myslam SHARED
frame.cpp
mappoint.cpp
map.cpp
camera.cpp
config.cpp
g2o_types.cpp
visual_odometry.cpp
)
此库文件需要链接上方定义好的第三方库,${THIRD_PARTY_LIBS}路径参数。
target_link_libraries( myslam
${THIRD_PARTY_LIBS}
)
然后test中的CMakeList.txt:
#最终到这里,添加可执行文件
add_executable( run_vo run_vo.cpp )
#可执行文件链接在自己写的库文件myslam上#
target_link_libraries( run_vo myslam )
我们的目标是:
写一个VO库,此库呢需要一些第三方库(Eigen、OpenCV、Sophus、G2O)。写完并生成此VO库之后呢,还需要用一个测试程序run_vo调用其跑一跑,看看效果。
根据目标,看一下结构:
1、src中一堆.cpp就是我们写的,要用于生成一个名为myslam的VO库。
2、同时,myslam会利用第三方库,所以需要include第三方库的头文件和链接库文件。
头文件在这里就一通find并include进来了。
库文件则被整合成了一个大的THIRD_PARTY_LIBS路径变量,以备后面target_link_libraries用。
3、src中的CMakeList.txt中生成myslam库,并链接到上层定义的THIRD_PARTY_LIBS库文件路径。
4、test中的CMakeList.txt中就是简单的生成可执行文件,并将源文件链接到我们写的myslam库文件上。
单独说一下这一句:
list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules )
cmake_modules是cmake模块,如果你的工程比较复杂,就有可能会自己编写一些 cmake 模块,这些 cmake 模块会随你的工程发布。
一点点说:
list:
用途:提供一些列表操作
list(LENGTH <list><output variable>)
list(GET <list> <elementindex> [<element index> ...]
<output variable>)
list(APPEND <list><element> [<element> ...])
list(FIND <list> <value><output variable>)
list(INSERT <list><element_index> <element> [<element> ...])
list(REMOVE_ITEM <list> <value>[<value> ...])
list(REMOVE_AT <list><index> [<index> ...])
list(REMOVE_DUPLICATES <list>)
list(REVERSE <list>)
list(SORT <list>)
LENGTH返回列表的长度
GET返回列表中指定下标的元素
APPEND添加新元素到列表中
INSERT 将新元素插入到列表中指定的位置
REMOVE_ITEM从列表中删除某个元素
REMOVE_AT从列表中删除指定下标的元素
REMOVE_DUPLICATES从列表中删除重复的元素
REVERSE 将列表的内容实地反转,改变的是列表本身,而不是其副本
SORT 将列表按字母顺序实地排序,改变的是列表本身,而不是其副本
列表的子命令APPEND, INSERT, REMOVE_AT, REMOVE_ITEM,REMOVE_DUPLICATES, REVERSE以及SORT在当前的CMake变量域创建一些新值。与SET命令类似,即使列表本身是在父域中定义的,LIST命令也只会在当前域创建新的变量值,为了将这些操作的结果向上传递,需要通过SET PARENT_SCOPE, SET CACHE INTERNAL或其他值域扩展的方法。
注意:cmake中的列表是以分号隔开的一组字符串。可以使用set命令创建一个列表。例如:set(var a b c d e)创建了一个这样的列表:a;b;c;d;e。 set(var “a b c d e”)创建了一个字符串或只有一个元素的列表。
当指定索引值时,<element index>为大于或等于0的值。它从列表的开始处索引,0代表列表的第一个元素。如果<element index>为小于或等于-1的值,它从列表的结尾处索引,-1代表列表的最后一个元素。
再看一下:CMAKE_MODULE_PATH:
这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理CMakeLists.txt 时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。
比如
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
这时候你就可以通过 INCLUDE 指令来调用自己的模块了。
以上两个为摘抄。
从上可以看出:
1、CMAKE_MODULE_PATH这个变量是一个列表,具体就是cmake模块的路径列表,可以好多路径,存在各个地方。
2、list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules )
这句的意思也就很明了了,就是将工程根目录下的cmake_modules文件夹路径,添加到CMAKE_MODULE_PATH路径列表中。
上一篇: Windows下CMake安装使用
下一篇: Oracle的一些函数(待补充)