cmake简介
-
cmake诞生主要是为了解决make+Makefile这种方式无法实现跨平台编译的问题,cmake是可以实现跨平台的编译工具。
在不同平台下,make工具遵循着不同的规范和标准,对应的makefile文件语法、格式也不同。
-
cmake工具通过解析CMakeLists.txt,自动生成Makefile。
-
cmake官方教程
文档链接地址:https://cmake.org/documentation/
培训教程:https://cmake.org/cmake/help/latest/guide/tutorial/index.html
CMakeLists.txt语法
简单语法介绍
-
“#”进行单行注释
-
command(参数1 参数2 参数3)
多个参数分隔使用空格
参数分为必要参数:<参数>,可选参数:[参数]
命令不区分大小写,例如project和PROJECT等价。建议小写,因为cmake的内置变量名称都是使用大写。
-
set(变量 值)
变量分为cmake内置变量和自定义变量
变量可以使用set变量设置
使用${变量}来引用变量
部分常用命令
command | 用法 | 说明 | 备注 |
---|---|---|---|
add_executable | add_executable(\<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) | 添加一个可执行程序目标,并设置目标所需的源文件 | |
add_library | add_library(\<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 [source2...]) | 添加一个库文件目标,并设置目标所需的源文件 | STATIC:静态库 SHARED:动态库 |
add_subdirectory | add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) | 去指定目录中寻找源码(CMakeLists.txt)并执行 | 非当前源码子目录,要显式指定binary_dir;会向下传递头文件搜索列表、链接库搜索列表 |
aux_source_directory | aux_source_directory(\<dir> \<variable>) | 从指定目录中查找源文件,并将源文件路径信息保存到variable变量中 | |
include_directories | include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2...]) | 设置头文件的搜索路径,相当于 gcc 的-I 选项 | 默认将指定目录添加到头文件搜索列表最后面 |
link_directories | link_directories(directory1 directory2 ...) | 设置库文件的搜索路径,相当于gcc的-L选项 | |
link_libraries | link_libraries([item1 [item2 [...]]] [[debug|optimized|general] \<item>] ...) | 设置需要链接的库文件,相当于gcc的-l选项 |
- list
命令 | 说明 |
---|---|
list(LENGTH \<list> <output variable>) | 返回列表长度 |
list(GET \<list> \<element index> [\<element index> ...] \<output_variable>) | 从列表中返回由索引值指定的元素 |
list(APPEND \<list> [\<element> ...]) | 将元素追加到列表后面 |
list(FIND \<list> \<value> \<output variable>) | 返回列表中指定元素的索引值,未找到返回-1 |
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>) | 将列表按字母序排序 |
-
message
message([\<mode>] "message to display")
也可以用message打印变量:message(${VAL})
mode | 说明 |
---|---|
none(无) | 重要信息、普通信息 |
STATUS | 附带信息 |
WARNING | Cmake警告,继续处理 |
AUTHOR_WARNING | Cmake警告(开发),继续处理 |
SEND_ERROR | Cmake错误,继续处理,但跳过生成 |
FATAL_ERROR | Cmake错误,停止处理和生成 |
DEPRECATION | 如果变量CMAKE_ERROR_DEPRECATED或CMAKE_WARN_DEPRECATED分别启用,则Cmake弃用错误或警告,否则没有消息 |
-
project
project(HELLO)
执行之后会引入两个变量:HELLO_SOURCE_DIR和HELLO_BINARY_DIR,前者指工程源码目录,后者指工程源码的输出文件目录。如果不设置project(HELLO),这两个变量不存在,Cmake中PROJECT_SOURCE_DIR和PROJECT_BINARY_DIR分别与这两个变量等价。
-
set
set(
... [PARENT_SCOPE]) 用于设置变量的值
用于实现字符串列表:set(SRC_LIST 1.c 2.c 3.c 4.c 5.c)
-
target_include_directories 和 target_link_libraries
target_include_directories 为指定目标设置头文件搜索路径
target_include_directories(\<target> [SYSTEM] [BEFORE] \<INTERFACE|PUBLIC|PRIVATE> [items1...] [\<INTERFACE|PUBLIC|PRIVATE> [items2...]...])
target_link_directories 为指定目标设置链接库文件搜索路径
target_link_directories(\<target> \<INTERFACE|PUBLIC|PRIVATE> [item...] [\<INTERFACE|PUBLIC|PRIVATE> [item...]...])
\<target>指的是add_executable、add_library命令所创建的目标。
- PRIVATE:包含目录列表仅用于当前目标
- INTERFACE:包含目录列表不用于当前目标,只能用于依赖该目标的其它目标
- PUBLIC:包含目录列表既用于当前目标、也会传递给当前目标的依赖目标
尽量使用target_include_directories和target_link_libraries,避免include_directories和link_libraries的向下传递,使得整个工程目标的逻辑保持清晰。
部分常用变量
提供信息的变量
变量 | 说明 |
---|---|
PROJECT_SOURCE_DIR | 工程顶层源码目录,即顶层CMakeLists.txt源码所在目录 |
PROJECT_BINARY_DIR | 工程输出目录,即顶层CMakeLists.txt源码的输出文件目录 |
CMAKE_SOURCE_DIR | 等价于PROJECT_SOURCE_DIR |
CMAKE_BINARY_DIR | 等价于PROJECT_BINARY_DIR |
CMAKE_CURRENT_SOURCE_DIR | 当前源码路径 |
CMAKE_CURRENT_BINARY_DIR | 当前源码的输出文件目录 |
CMAKE_MAJOR_VERSION | cmake的主版本号 |
CMAKE_MINOR_VERSION | cmake的次版本号 |
CMAKE_VERSION | cmake的版本号 |
PROJECT_VERSION_MAJOR | 工程的主版本号 |
PROJECT_VERSION_MINOR | 工程的次版本号 |
PROJECT_VERSION | 工程的版本号 |
CMAKE_PROJECT_NAME | 工程的名字 |
PROJECT_NAME | 与CMAKE_PROJECT_NAME等价 |
改变行为的变量
变量 | 说明 | 值 |
---|---|---|
BUILD_SHARED_LIBS | 控制cmake是否生成动态库 | on/off |
CMAKE_BUILD_TYPE | 指定工程的构建类型,release或debug | Debug:会生成相关调试信息,可用gdb进行调试 Release:不会生成调试信息 |
CMAKE_SYSROOT | 对应编译器的--sysroot选项,会将该变量传递给编译器--sysroot选项 | |
CMAKE_IGNORE_PATH | 设置为find_xxx命令忽略的目录列表 | |
CMAKE_INCLUDE_PATH | 为find_file()和find_path()命令指定搜索路径的目录列表 | |
CMAKE_INCLUDE_DIRECTORIES_BEFORE | 用于控制include_directories命令的行为 | |
CMAKE_LIBRARY_PATH | 指定find_library()命令的搜索路径的目录列表 | |
CMAKE_MODULE_PATH | 指定要由Include()或find_package()命令加载的Cmake模块的搜索路径的目录列表 | |
CMAKE_PROGRAM_PATH | 指定find_program()命令的搜索路径的目录列表 |
描述系统的变量
变量 | 说明 |
---|---|
CMAKE_HOST_SYSTEM_NAME | 运行cmake的操作系统名称(uname -s) |
CMAKE_HOST_SYSTEM_PROCESSOR | 运行cmake的操作系统的处理器名称(uname -p) |
CMAKE_HOST_SYSTEM | 运行cmake的操作系统(复合信息) |
CMAKE_HOST_SYSTEM_VERSION | 运行cmake的操作系统的版本号(uname -r) |
CMAKE_HOST_UNIX | 如果运行cmake的操作系统是unix和类unix,则该变量为true,否则为空值 |
CMAKE_HOST_WIN32 | 如果运行cmake的操作系统是windows,则该变量为true,否则为空值 |
CMAKE_SYSTEM_NAME | 目标主机操作系统的名称 |
CMAKE_SYSTEM_PROCESSOR | 目标主机的处理器名称 |
CMAKE_SYSTEM_VERSION | 目标主机的操作系统的版本号 |
CMAKE_SYSTEM | 目标主机的操作系统 |
ENV | 用于访问环境变量 |
UNIX | 与CMAKE_HOST_UNIX等价 |
WIN32 | 与CMAKE_HOST_WIN32等价 |
控制编译的变量
变量 | 说明 |
---|---|
EXECUTABLE_OUTPUT_PATH | 可执行程序的输出路径 |
LIBRARY_OUTPUT_PATH | 库文件的输出路径 |
双引号
-
命令参数
例如:project("Hello World")
cmake会将双引号引起来的内容作为一个整体
-
引用变量
set(MY_LIST Hello World China)
message("${MY_LIST}")
会输出 Hello;World;China
如果直接message(${MY_LIST})
会输出 HelloWorldChina
条件判断
-
条件判断形式如下:
if(expression)
command1(args ...)
command2(args ...)
elseif(expression2)
command1(args ...)
command2(args ...)
else(expression)
command1(args ...)
command2(args ...)
endif(expression)
else和endif中的expression可写可不写,如果写,需和if中的expression保持一致。
-
expression表达式链接:https://cmake.org/cmake/help/v3.5/command/if.html
循环语句
foreach()循环
-
基本用法
foreach(loop_var arg1 arg2)
command1(args ...)
command2(args ...)
...
endforeach(loop_var)
例如:
foreach(loop_var A B C D)
message("${loop_var}")
endforeach()
输出为A B C D
endforeach中的loop_var可写可不写,如果写要与foreach保持一致
-
RANGE用法
foreach(loop_var RANGE stop) 会从0循环到指定的数字stop,闭区间
foreach(loop_var RANGE start stop [step]) 从start循环到stop,步长为step,默认步长为1,闭区间
-
IN用法
foreach(loop_var IN [LISTS [list1 [...]]] [ITEMS [item1 [...]]]) 循环列表(LISTS)中的每一个元素,或者直接指定循环元素(ITEMS)
while()循环
-
while用法
while(condition)
command1(args)
command1(args)
endwhile(condition)
break & continue
- break用于跳出循环
- continue用于结束本次循环,进行下一次循环
数学运算
-
用法
math(EXPR \<output variable> \<math expression>)
例如:
math(EXPR out_var "1+1")
message("${out_var}")
练习代码
- gitee代码仓库链接:https://gitee.com/sigmapoet/cmake-exercise
参考文献
- 《正点原子 I.MX6U 嵌入式Linux C应用编程指南》
本文地址: cmake入门与进阶——入门篇