- cmake 内置命令是不区分大小写的
- 但是注意区分变量的大小写
aux_source_directory
- 在目录中查找所有源文件
1
aux_source_directory(<dir> <variable>)
例子
工程格式
1
2
3
4
5
6
7./Demo2
|
+--- main.cc
|
+--- MathFunctions.cc
|
+--- MathFunctions.h写法1
1
2
3
4
5
6
7
8# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo2)
# 指定生成目标
add_executable(Demo main.cc MathFunctions.cc)写法2
1
2
3
4
5
6
7
8
9
10
11
12# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo2)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
打印变量
- status 表示这是一般的打印信息
1
2set(USER_KEY, "Hello World")
message( STATUS "this var key = ${USER_KEY}.")
Set 的用法
Set赋值给一般变量(normal variables)
什么是一般变量,一般变量和代码中变量相似,仅在自身所在作用域起作用,除非后面使用PARENT_SCOPE。
每一个新的目录或者函数都会创建新的作用域,当在新的作用域创建一般变量且后面加上PARENT_SCOPE,该变量可以在父目录或者调用新函数的函数上起作用。
举个栗子:
1
2set(FOO “x”)。 //FOO作用域为当前作用域.
set(FOO "x" PARENT_SCOPE) //FOO作用域跳上一级.
Set赋值给缓存变量(cache variables)
什么是缓存变量,缓存变量可以理解为当第一次运行cmake时,这些变量缓存到一份文件中(即编译目录下的CMakeCache.txt)。当再次运行cmake时,这些变量会直接使用缓存值,可以利用ccmake或者cmake-gui等工具来重新赋值。缓存变量在整个cmake运行过程中都可以起作用。
当使用CACHE时,且缓存(cache)中没有该变量时,变量被创建并存入缓存(cache)中,如果原缓存(cache)中有该变量,也不会改变原缓存中该变量的值,除非后面使用FORCE。
举个栗子:
1
2
3set(FOO, "x" CACHE <type>)
//原缓存中没有FOO则将FOO赋值为x且存入cache中。
//原缓存中有FOO则不做任何改变,即便原cache中FOO存的不是x。
1 | set(FOO, "x" CACHE <type><docstring> FORCE) |
使用CACHE的同时,要设定
<type>
和<docstring>
,<type>
可以理解为所存入变量类型,<docstring>
为变量的描述。<type>
分为以下几种类型:1
2
3
4
5FILEPATH = File chooser dialog.
PATH = Directory chooser dialog.
STRING = Arbitrary string.
BOOL = Boolean ON/OFF checkbox.
INTERNAL = No GUI entry (used for persistent variables).其中INTERNAL将变量为内部变量,即cmake-gui不会向用户显示这类变量,而其它类型的缓存变量用户都可以通cmake-gui按照特定的类型改变。
例子:
- 如果编译的时候没有带
CMAKE_BUILD_TYPE
参数的话,则会默认为Release
1
2
3
4
5
6
7
8#---------------------------------------------------------------------------------------
# Set default build type to release
#---------------------------------------------------------------------------------------
if (UNIX)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE)
endif ()
endif ()
注意
CACHE 与 PARENT_SCOPE 不能一起使用
同一名称(例FOO)的一般变量和缓存变量可以同时存在,但在调用该变量时(${FOO})会在先取一般变量的值,一般变量中没有再取缓存变量的值。
1
2
3
4set(FOO “x”) //设置一般变量FOO,不会触及cache,但是会隐藏cache中的FOO。
set(FOO “x” CACHE ...) //忽视相同名称的一般变量,在cache中检查FOO是否存在,
//如果不存在则存入cache中,存在也不会对cache中FOO重新赋值。当改变cache中的变量时,同名的一般变量会被删除。一般不建议使用相同名称的一般变量和缓存变量。
然而在有些工程中可以很好的借助这一交互例如:
- 一个工程利用ADD_SUBDIRECTOTY()添加子工程,子工程有它自己的CMakeList.txt。如果在父工程和子工程中都对同一缓存变量赋值,cmake时父工程率先将变量存入cache中,子工程直接在cache中调用该值,保证了父子工程的一致性。当父工程需要改变该变量,而子程序需要利用原值时,可以直接在父工程中设置同名称的一般变量即可。
Option 的用法
- 使用场景 : 编译脚本传递参数 -> CMake脚本接收option -> 源代码宏
编译脚本传入参数
1 |
|
CMake脚本接收option
- cmake 脚本定义TEST_DEBUG 默认关闭OFF
1
2
3
4
5
6
7
8project(test)
option(TEST_DEBUG "option for debug" OFF)\
if (TEST_DEBUG)
add_definitions(-DTEST_DEBUG)
endif ()
...
源代码宏 test.c
1 |
|
add_subdirectory 的用法
一般情况下,我们的项目各个子项目都在一个总的项目根目录下,但有的时候,我们需要使用外部的文件夹,怎么办呢?
add_subdirectory命令,可以将指定的文件夹加到build任务列表中。
add_library
使用指定的源文件向工程中添加一个库
1
2
3add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)其中
表示库文件的名字,该库文件会根据命令里列出的源文件来创建。而 STATIC、SHARED 和 MODULE 的作用是指定生成的库文件的类型。 - STATIC库是目标文件的归档文件,在链接其它目标的时候使用。
- SHARED库会被动态链接(动态链接库),在运行时会被加载。
- MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。
默认状态下,库文件将会在于源文件目录树的构建目录树的位置被创建,该命令也会在这里被调用。
而语法中的 source1 source2 分别表示各个源文件。
- 使用下述格式,add_library命令也可以用来创建导入的库目标:
1
add_library(${PROJECT_NAME} SHARED src/track/Tracking.cpp)
link_directories
- 该指令的作用主要是指定要链接的库文件的路径,该指令有时候不一定需要。因为find_package和find_library指令可以得到库文件的绝对路径。
- 不过你自己写的动态库文件放在自己新建的目录下时,可以用该指令指定该目录的路径以便工程能够找到。
- 例子如下:
1
2
3link_directiories(
lib
)
target_link_libraries
- 该指令的作用为将目标文件与库文件进行链接。该指令的语法如下:
1
2target_link_libraries(<target> [item1] [item2] [...]
[[debug|optimized|general] <item>] ...) - 上述指令中的
是指通过 add_executable() 和 add_library() 指令生成已经创建的目标文件。而 [item] 表示库文件没有后缀的名字。 - 默认情况下,库依赖项是传递的。当这个目标链接到另一个目标时,链接到这个目标的库也会出现在另一个目标的连接线上。
- 这个传递的接口存储在interface_link_libraries的目标属性中,可以通过设置该属性直接重写传递接口
- 例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14link_directiories(
${svo_SOURCE_DIR}/include/svo
${svo_SOURCE_DIR}/include/svo/track
)
add_library(${PROJECT_NAME} SHARED
src/track/Tracking.cpp
)
add_executable(${PROJECT_NAME}_node src/svo_node.cpp src/system.cpp)
target_link_libraries(${PROJECT_NAME}_node
${PROJECT_NAME}
)
include_directories
- 设置头文件位置
一些关键字
UNIX
: 在所有的类UNIX平台为TRUE,包括OS X和cygwinWIN32
: 在所有的win32平台为TRUE,包括cygwin