【笔记】【cmake】

qt支持cmake文件的编写,具有自动补全的功能,带来不少便利

解决问题:
cmake过程中如何打印消息?
什么是隐式变量?
如何设置显示变量?
如何执行判断语句?
如何添加子目录?
如何将向子目录输出二进制文件?

基本语法规则

  1. 变量使用${}方式取值,但是在IF控制语句中是直接使用变量名
  2. 指令(参数 1 参数 2…)
    参数使用括弧括起,参数之间使用空格或分号;分开
  3. 指令是大小写无关的,参数和变量是大小写相关的

cmake 常用隐式变量
CMAKE_SOURCE_DIRPROJECT_SOURCE_DIR<projectname>_SOURCE_DIR,都是工程顶层目录
CMAKE_BINARY_DIRPROJECT_BINARY_DIR<projectname>_BINARY_DIR,如果是 in source 编译,指的就是工程顶层目录,如果是 out-of-source 编译,指的是工程编译发生的目录,如,./build

CMAKE_CURRENT_SOURCE_DIR, 指的是当前处理的 CMakeLists.txt 所在的路径,比如src 子目录
CMAKE_CURRRENT_BINARY_DIR,如果是 in-source 编译,它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是 out-ofsource 编译,他指的是 target 编译目录,即 ./build路径

CMAKE_MODULE_PATH,这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理CMakeLists.txt时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。
语法:

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

如下:

# 添加cmake模块以使用g2o
list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules )

cmake 调用环境变量的方式
使用$ENV{NAME}指令就可以调用系统的环境变量了


SET 指令
用来显式的定义变量

SET(SRC_LIST main.c t1.c t2.c)

MESSAGE 指令
用于向终端输出用户定义的信息,包含了三种类型:

  • SEND_ERROR,产生错误,生成过程被跳过。
  • SATUS,输出前缀为—的信息。
  • FATAL_ERROR,立即终止所有 cmake 过程.

语法:

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

例如,打印隐式变量,注意STATUS大写

message(STATUS "this is a test: " ${PROJECT_SOURCE_DIR})

ADD_LIBRARY指令
生成库文件,库文件名随便起,有人使用工程名,不过这里只是指生成的库的名称,跟工程名不冲突

## 查找指定目录下的所有源文件,然后将结果存进指定变量名
AUX_SOURCE_DIRECTORY(./src/hello SRC_DIR_HELLO)
## 库文件名为hello_shared,也可设置为工程名称,亦没有问题
ADD_LIBRARY(hello_shared SHARED
    ${SRC_DIR_HELLO}
)
add_executable( create_marker ./src/create_marker.cpp  )
## 使用生成的库
target_link_libraries( create_marker hello_shared )

add_subdirectory 指令
这个指令用于向当前工程添加存放源文件的子目录(子目录下需要再写一个CMakeList.txt文件),并可以指定中间二进制和目标二进制存放的位置。
语法:

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除。
亦可通过下面的方式,省略src目录下的CMakeList.txt文件

add_executable( detect_maker ./src/detect_maker.cpp  )

更改目标二进制存放路径
通过SET 指令重新定义EXECUTABLE_OUTPUT_PATHLIBRARY_OUTPUT_PATH变量来指定最终的目标二进制的位置
如下,可执行二进制的输出路径为 ./bin 和库的输出路径为./lib .

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

我应该把这两条指令写在工程的 CMakeLists.txt 还是 src 目录下的CMakeLists.txt把握一个简单的原则,在哪里 ADD_EXECUTABLEADD_LIBRARY,如果需要改变目标存放路径,就在哪里加入上述的定义。

实践

cmake_minimum_required( VERSION 2.8 )
project( aruco_detect_project )

set( CMAKE_BUILD_TYPE "Release" )
set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )
set(OpenCV_DIR "/home/leather/slambook/opencv3/share/OpenCV")
set(OpenCV_INCLUDE_DIRS "/home/leather/slambook/opencv3/include/")
set(OpenCV_LIBS "/home/leather/slambook/opencv3/lib/")

# 添加cmake模块以使用g2o
list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules )

find_package( OpenCV 3.1 REQUIRED )
# find_package( OpenCV REQUIRED ) # use this if in OpenCV2 
find_package( G2O REQUIRED )
find_package( CSparse REQUIRED )

include_directories(
    ##将src目录下的头文件加入
    ./src/
    ${CMAKE_CURRENT_SOURCE_DIR} #当前处理的 CMakeLists.txt 所在的路径
    ${OpenCV_INCLUDE_DIRS} 
    ${G2O_INCLUDE_DIRS}
    ${CSPARSE_INCLUDE_DIR}
    "/usr/include/eigen3/"
)

##一次性将需要用到的库放到一起使用,使用新名称:LINK_LIBS
LIST(APPEND LINK_LIBS
    ${OpenCV_LIBS}
)

## 源文件路径(整个文件夹路径)命名,方便使用
AUX_SOURCE_DIRECTORY(./src/aruco SRC_DIR_ARUCO)

## 生成库文件
ADD_LIBRARY(aruco_detect_project SHARED
    ${SRC_DIR_ARUCO}
)

## 链接二进制库
TARGET_LINK_LIBRARIES(aruco_detect_project
    ${LINK_LIBS}
)

## 生成可执行文件(二进制)
add_executable( aruco_detect ./src/aruco_detect.cpp  )
target_link_libraries( aruco_detect aruco_detect_project )

猜你喜欢

转载自blog.csdn.net/hzwwpgmwy/article/details/80016248