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应用编程指南》
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 sigma_poet@126.com