1、CMake简介
CMake是一个用于管理源代码的跨平台构建工具
可以方便地根据目标平台和编译工具产生对应的编译文件
主要用于C/C++语言的构建,但是也可以用于其它编程语言的源代码。
如同使用make命令工具解析Makefile文件一样
cmake命令工具依赖于一个CMakeLists.txt的文件
该文件定义了代码的编译规则和目标等信息。
官方文档说明:https://cmake.org/cmake/help/v3.17/index.html
2、CMake 注释
单行注释 #
# 单行注释
多行注释 #[[ ]]
#[[ 多行注释
多行注释
多行注释 ]]
3、CMake 变量
CMake 中所有变量都是 String 类型
set() 声明变量
# set(变量名 变量值)
set(name 小明)
unset() 移除一个变量
# unset(变量名)
unset(name)
${} 引用变量
# ${变量名}
${name}
message() 打印变量
# message("name = ${变量名}")
message("name = ${name}")
4、CMake列表
列表也是字符串,可以把列表看做是一个特殊的变量,这个变量有多个值。
列表格式 (设置列表有两种方式)
# set(列表名 值1 值2 ... 值n)
set(list_age 1 2 ... n)
# set(列表名 "值1; 值2; 值3")
set(list_age "1;2;3")
5、CMake流程控制
操作符
优先级:() > 一元 > 二元 > 逻辑
类型 |
名称 |
一元 |
EXIST、COMMAND、DEFINED |
二元 |
EQUAL、LESS、LESS_EQUAL、GREATER、GREATER_EQUAL、
STREQUAL、STRLESS、STRLESS_EQUAL、STRGREATER、
STRGREATER_EQUAL、VERSION_EQUAL、VERSION_LESS、
VERSION_LESS_EQUAL、VERSION_GREATER、
VERSION_GREATER_EQUAL、MATCHES
|
布尔常量值
类型 |
值 |
true |
1、ON、YES、TRUE、Y、非0的值 |
false |
0、OFF、NO、FALSE、N、IGNORE、NOTFOUND
空字符串、一-NOTFOUND结尾的字符串
|
条件判断 if()
语法:
if(表达式)
....
elseif(表达式)
...
else(表达式)
...
endif()
循环命令 while()
语法:
while(表达式)
...
endwhile()
循环遍历 foreach()
循环遍历分为两种:
#循环范围从start到stop,循环增量为step
foreach(循环变量 RANGE start stop step)
...
endforeach(循环变量)
foreach(循环遍历 IN LISTS 列表)
...
endforeach(循环变量)
6、CMake自定义函数
语法:
function(<name> arg1 arg2 arg3)
...
endfunction(<name>)
调用:
name(arg1 arg2 arg3)
7、CMake自定义宏命令
语法:
macro(<name> arg1 arg2 arg3)
...
endmacro(<name>)
调用:
name(arg1 arg2 arg3)
8、CMake常用变量
CMake预设了一些常用变量
这些变量通常会在编写CMakeLists.txt文件时使用到:
变量值 |
作用 |
CMAKE_MAJOR_VERSION |
cmake 主版本号 |
CMAKE_MINOR_VERSION |
cmake 次版本号 |
CMAKE_C_FLAGS |
设置 C 编译选项 |
CMAKE_CXX_FLAGS |
设置 C++ 编译选项 |
PROJECT_SOURCE_DIR |
工程的根目录 |
PROJECT_BINARY_DIR |
运行 cmake 命令的目录 |
CMAKE_CURRENT_SOURCE_DIR |
当前CMakeLists.txt 所在路径 |
CMAKE_CURRENT_BINARY_DIR |
目标文件编译目录 |
EXECUTABLE_OUTPUT_PATH |
重新定义目标二进制可执行文件的存放位置 |
LIBRARY_OUTPUT_PATH |
重新定义目标链接库文件的存放位置 |
UNIX |
如果为真,表示为UNIX-like的系统,包括AppleOSX和CygWin |
WIN32 |
如果为真,表示为 Windows 系统,包括 CygWin |
APPLE |
如果为真,表示为 Apple 系统 |
CMAKE_SIZEOF_VOID_P |
表示void*的大小(例如为4或者8),可以使用其来判断当前构建为32位还是64位 |
CMAKE_CURRENT_LIST_DIR |
表示正在处理的CMakeLists.txt文件所在目录的绝对路径 |
CMAKE_ARCHIVE_OUTPUT_DIRECTORY |
用于设置ARCHIVE目标的输出路径 |
CMAKE_LIBRARY_OUTPUT_DIRECTORY |
用于设置LIBRARY目标的输出路径 |
CMAKE_RUNTIME_OUTPUT_DIRECTORY |
用于设置RUNTIME目标的输出路径 |
9、CMakeLists.txt 常用语法
project 命令:
# 命令语法:project(<projectname> [languageName1 languageName2 ...])
# 设置项目名称 (工程名称为 projectName)
project(projectName)
cmake_minimum_required 命令:
# cmake_minimum_requried(VERSION major[.minor[.patch)
# 设置 CMake 最低版本 (最低版本 3.14)
cmake_minimum_required(VERSION 3.14.0)
aux_source_directory命令:
# aux_source_directory(<dir> <variable>)
# 用于包含源文件目录,dir目录下的所有源文件的名字保存在变量variable中
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src DIR_SRCS)
add_executable命令:
# add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN)
# 用于指定从一组源文件source1 source2 ... sourceN 编译出一个可执行文件且命名为name
add_executable(Main $(DIR_SRCS))
add_library命令:
# add_library([STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1source2 … sourceN)
# 用于指定从一组源文件 source1 source2 ... sourceN编译出一个库文件且命名为name
add_library(Lib $(DIR_SRCS))
add_dependencies命令:
# add_dependencies(target-name depend-target1 depend-target2 …)
# 用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。
# 这里的目标必须是add_executable、add_library、add_custom_target命令创建的目标
add_subdirectory命令:
# add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
# 用于添加一个需要进行构建的子目录
add_subdirectory(Lib)
target_link_libraries命令:
# target_link_libraries(<target> [item1 [item2 […]]][[debug|optimized|general] ] …)
# 用于指定target需要链接item1 item2 ...。这里target必须已经被创建,链接的item可以是已经存在的target(依赖关系会自动添加)
target_link_libraries(Main Lib)
set命令:
# 用于设定变量 variable 的值为 value。如果指定了 CACHE 变量将被放入 Cache(缓存)中。
# set(<variable> <value> [[CACHE <type><docstring> [FORCE]] | PARENT_SCOPE])
set(ProjectName Main)
unset命令:
# unset(<variable> [CACHE])
# 用于移除变量 variable。如果指定了 CACHE 变量将被从 Cache 中移除。
unset(VAR CACHE)
message命令:
# message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] “message todisplay”…)
# 用于输出信息
message(“Hello World”)
include_directories命令:
# include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
# 用于设定目录,这些设定的目录将被编译器用来查找 include 文件
include_directories(${PROJECT_SOURCE_DIR}/lib)
find_path命令:
# find_path(<VAR> name1 [path1 path2 …])
# 用于查找包含文件name1的路径,如果找到则将路径保存在VAR中(此路径为一个绝对路径),如果没有找到则结果为<VAR>-NOTFOUND.默认情况下,VAR会被保存在Cache中,这时候我们需要清除VAR才可以进行下一次查询(使用unset命令)
find_path(LUA_INCLUDE_PATH lua.h ${LUA_INCLUDE_FIND_PATH})
if(NOT LUA_INCLUDE_PATH)
message(SEND_ERROR "Header file lua.h not found")
endif()
find_library命令:
# find_library(<VAR> name1 [path1 path2 …])
# 用于查找库文件 name1 的路径,如果找到则将路径保存在 VAR 中(此路径为一个绝对路径),
# 如果没有找到则结果为 <VAR>-NOTFOUND。
# 一个类似的命令 link_directories 已经不太建议使用了
add_definitions命令:
# add_definitions(-DFOO -DBAR …)
# 用于添加编译器命令行标志(选项),通常的情况下我们使用其来添加预处理器定义
add_definitions(-D_UNICODE -DUNICODE)
file命令:
# 此命令提供了丰富的文件和目录的相关操作(这里仅说一下比较常用的)
使用范例:
# 目录的遍历
# GLOB 用于产生一个文件(目录)路径列表并保存在variable 中
# 文件路径列表中的每个文件的文件名都能匹配globbing expressions(非正则表达式,但是类似)
# 如果指定了 RELATIVE 路径,那么返回的文件路径列表中的路径为相对于 RELATIVE 的路径
file(GLOB variable [RELATIVE path][globbing expressions]...)
# 获取当前目录下的所有的文件(目录)的路径并保存到 ALL_FILE_PATH 变量中
file(GLOB ALL_FILE_PATH ./*)
# 获取当前目录下的 .h 文件的文件名并保存到ALL_H_FILE 变量中
# 这里的变量CMAKE_CURRENT_LIST_DIR 表示正在处理的 CMakeLists.txt 文件的所在的目录的绝对路径(2.8.3 以及以后版本才支持)