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}")

练习代码

参考文献

  • 《正点原子 I.MX6U 嵌入式Linux C应用编程指南》
说点什么
请文明发言!
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...