在《深入浅出CMake(一):基础篇》文章中,我们已经知道了怎么依葫芦画瓢编写简单的 CMake 构建文件了,但如果应对复杂的工程的话,这还是远远不够的。

CMake 是一套编译构建体系,所以它有自己的一套语法概念,也有自己的 CMake Language,你可以讲它看做是一套脚本语言,所以它能做很多编程的事情。
这篇博文的目的是对 CMake 的基础语法进行概括,文章最后用一个九九乘法表的例子让读者加深印象。

文章开始前,让我们先回想 C/C++、JAVA、PYTHON 等等这些编程语言有什么特征

  • 能够进行条件判断 if/else
  • 能够循环处理 while/for/foreach
  • 能够操作字符串string
  • 能够读写文件

这些特征足够我们在日常开发中编写常见的算法逻辑,处理很多问题了。
幸运的是 CMake 有类似的语法,能实现类似的功能。
CMake 有一个很重要的概念叫做命令.

COMMAND()

CMake 构建过程的操作基本上依靠各种各样的命令完成的,比如之前我们见过的

project(test)
add_executable(hello hello.cpp)

相信不难理解,官网中关于命令完整介绍在这里
下面开始,简单对 CMake 中一些语法过一眼
条件判断 if()/endif()
比如,它可以进行条件判断

if(<condition>)<commands>
elseif(<condition>) # optional block, can be repeated<commands>
else()              # optional block<commands>
endif()

if() 和 endif() 是配对使用的。
循环判断 foreach()/while()

foreach(<loop_var> <items>)<commands>
endforeach()

items 是一个 list,里面的元素用分号 ; 或者空格分割开来
比如

foreach(index A B C D)

也可以这样

foreach(index RANGE 9)

RANGE 是指定的迭代模型,index 取值从 0 到 9,包括 9.

while(<condition>)<commands>
endwhile()

while 循环和普通的开发无多大差别,这个不细说。
当然跳出当前判断也有

break()
continue()
return()

设置变量 set()/unset()
CMake 的变量可以分为 普通变量、系统环境变量。
set() 命令可以设置普通变量、系统环境变量、和缓存。

set(<variable> <value>... [PARENT_SCOPE])

设置普通的变量,将 value 的值赋值给 variable,后面的参数是可选的,代表有效域。

set(ENV{<variable>} [<value>])

设置系统环境变量

set(<variable> <value>... CACHE <type> <docstring> [FORCE])

设置缓存
访问变量的时候用 ${variable}

list
有自己的数据结构

Readinglist(LENGTH <list> <out-var>)list(GET <list> <element index> [<index> ...] <out-var>)list(JOIN <list> <glue> <out-var>)list(SUBLIST <list> <begin> <length> <out-var>)Searchlist(FIND <list> <value> <out-var>)Modificationlist(APPEND <list> [<element>...])list(FILTER <list> {INCLUDE | EXCLUDE} REGEX <regex>)list(INSERT <list> <index> [<element>...])list(REMOVE_ITEM <list> <value>...)list(REMOVE_AT <list> <index>...)list(REMOVE_DUPLICATES <list>)list(TRANSFORM <list> <ACTION> [...])Orderinglist(REVERSE <list>)list(SORT <list> [...])

CMake 对于 list 操作手段比较丰富,涉及到读取 list 信息,查找元素,修改、添加、插入元素及排序。

篇幅限制,这里不一一展开。

读写文件 file()
可以读写文件

Readingfile(READ <filename> <out-var> [...])file(STRINGS <filename> <out-var> [...])file(<HASH> <filename> <out-var>)file(TIMESTAMP <filename> <out-var> [...])Writingfile({WRITE | APPEND} <filename> <content>...)file({TOUCH | TOUCH_NOCREATE} [<file>...])file(GENERATE OUTPUT <output-file> [...])Filesystemfile({GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...])file(RENAME <oldname> <newname>)file({REMOVE | REMOVE_RECURSE } [<files>...])file(MAKE_DIRECTORY [<dir>...])file({COPY | INSTALL} <file>... DESTINATION <dir> [...])file(SIZE <filename> <out-var>)file(READ_SYMLINK <linkname> <out-var>)file(CREATE_LINK <original> <linkname> [...])Path Conversionfile(RELATIVE_PATH <out-var> <directory> <file>)file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)Transferfile(DOWNLOAD <url> <file> [...])file(UPLOAD <file> <url> [...])Lockingfile(LOCK <path> [...])

CMake 在构建过程中,避免不了要读写一些配置文件,这个时候 file() 命令就显得很有必要了。

操作字符串 string()
也可以对 string 文本进行操作

Search and Replacestring(FIND <string> <substring> <out-var> [...])string(REPLACE <match-string> <replace-string> <out-var> <input>...)Regular Expressionsstring(REGEX MATCH <match-regex> <out-var> <input>...)string(REGEX MATCHALL <match-regex> <out-var> <input>...)string(REGEX REPLACE <match-regex> <replace-expr> <out-var> <input>...)Manipulationstring(APPEND <string-var> [<input>...])string(PREPEND <string-var> [<input>...])string(CONCAT <out-var> [<input>...])string(JOIN <glue> <out-var> [<input>...])string(TOLOWER <string1> <out-var>)string(TOUPPER <string1> <out-var>)string(LENGTH <string> <out-var>)string(SUBSTRING <string> <begin> <length> <out-var>)string(STRIP <string> <out-var>)string(GENEX_STRIP <string> <out-var>)Comparisonstring(COMPARE <op> <string1> <string2> <out-var>)Hashingstring(<HASH> <out-var> <input>)Generationstring(ASCII <number>... <out-var>)string(CONFIGURE <string1> <out-var> [...])string(MAKE_C_IDENTIFIER <string> <out-var>)string(RANDOM [<option>...] <out-var>)string(TIMESTAMP <out-var> [<format string>] [UTC])string(UUID <out-var> ...)

string() 命令包含的功能很多,文章篇幅限制,有机会我之后会单独写一篇博文详细介绍。

终端打印 message()
也可以向终端打印。

message([<mode>] "message to display" ...)

message() 命令可以向终端打印字符串
并且,它支持不同类型

  • none
  • STATUS
  • WARNING AUTHOR_WARNING
  • SEND_ERROR
  • FATAL_ERROR
  • DEPRECATION
    开发者可以根据实际情况定义不同的消息等级

数学运算 math()
还能做数学运算

math(EXPR <variable> "<expression>" [OUTPUT_FORMAT <format>])

上面命令的用法是,计算数学表达是 experssion,然后将结果保存在 variable 中,后面是指定的格式为 10 进制还是 16 进制。
正因为有了这些灵活的命令,CMake 显得无所不能,带来的好处也显而易见,程序员编写 CMakeLists.txt 会更加得心应手。
下面,我们就把 CMake 当做是一种编码语言,写一个简单的例子。

九九乘法表
我们的目的是用 CMake 在屏幕上打印一个九九乘法表。

cmake_minimum_required(VERSION 2.8.11)
project(test)foreach(i RANGE 1 9)set(exp "")foreach(j RANGE 1 ${i})math(EXPR value "${j} * ${i}")string(APPEND exp "${j}" "*")string(APPEND exp "${i}" "=")string(APPEND exp "${value}" " ")endforeach()message(${exp})
endforeach()

这是 CMakeLists.txt 中的代码,可以看到主要运用了 foreach()、string()、set()、message() 几个命令。
在当前目录运行 cmake .命令。
可以看到终端打印了如下结果

1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
-- Configuring done
-- Generating done

CMake 的命令很多,但只要我们把握大概的方向,在实际编码当中就可以现学现用,掌握了 CMake 的基本语法,我们就可以比较从容去应对在复杂的工程当中配置复杂的 CMakeLists.txt 文件了。

备注:
点击下面链接,进入奥比中光开发者社区,了解更多3D视觉技术信息:https://developer.orbbec.com.cn/
或扫描下方二维码,进入奥比中光开发者社区:

深入浅出CMake(二): 基础语法相关推荐

  1. PHP从入门到跑路(二),基础语法,数据库操作

    基础语法 前言 一, 变量定义及使用 二,数据库操作 三, php开发细节躺坑 前言 博主不会php, 是从JAVA转过来的, PHP教程总结实际开发使用, 更加偏向于实际, 理论比较薄弱, 一直想总 ...

  2. Vue2.0学习笔记二 基础语法

    1. Mustache语法 Mustache语法也叫插值表达式,Mustache语法式通过{{}}渲染到页面,并且数据是响应式的. 数据的响应式:数据的变化导致页面的内容随之变化 效果图: 2. 指令 ...

  3. 专科 java转go 翱翔之路(二)基础语法:匿名组合,方法,接口,map,json,异常处理,channel管道,select用法

    2.4 面向对象编程 2.4.1匿名组合 type Person struct {id intname stringage int }type Student struct {Person //只有类 ...

  4. Scala语法(一) 基础语法(变量常量判断循环数组集合)

    前言 在前面的章节中, 我们介绍了如何在Eclipse内安装Scala环境. 本章开始, 我们将讲解下Scala的基本语法. PS: 1. 个人虽然没有想转Scala语言开发的思想, 但是近来Scal ...

  5. Python基础教程(二):基础语法、变量类型

    Python 基础语法 Python语言与Perl,C和Java等语言有许多相似之处.但是,也存在一些差异. 在本章中我们将来学习Python的基础语法,让你快速学会Python编程. 第一个Pyth ...

  6. python设计一个函数定义计算并返回n价调和函数_音乐编程语言musicpy教程(第三期) musicpy的基础语法(二)...

    这个是我在github上给我的项目musicpy写的wiki,分为数据结构,基础语法,实际应用三大部分来为大家讲解这门音乐编程语言,主要是想给大家写一个musicpy的详细的教程与介绍,目前wiki只 ...

  7. 【Drools二】打工人学习Drools基础语法

    目录 0.项目搭建 1. 规则文件 1.1 构成 1.2规则体 2.基础语法 2.1 注释 2.2 Pattern模式匹配 2.3比较操作符 2.3.1 实践 2.3执行指定规则 3.Drools内置 ...

  8. java基础语法(二)--单列模式

    java基础语法(二)--单列模式 /*** 功能:单列模式* @author Administrator**/ public class SingletonTest {public static v ...

  9. HiveQL学习笔记(二):Hive基础语法与常用函数

    本系列是本人对Hive的学习进行一个整理,主要包括以下内容: 1.HiveQL学习笔记(一):Hive安装及Hadoop,Hive原理简介 2.HiveQL学习笔记(二):Hive基础语法与常用函数 ...

最新文章

  1. winRAR 没有右键选项
  2. c++ shared_ptr的使用
  3. 移动界面控件Essential Studio for Mobile MVC图表控件解析
  4. 一种去中心化的manager设计思路
  5. Microsoft Operations Management Suite 启用NPM网络性能监视
  6. 对线程与进程的区别以及对多线程并发的理解
  7. linux chrome 安装过程记录
  8. 软件工程----9软件实现
  9. Python自省(反射) 与 inspect 模块
  10. 构造方法重载 java 1615136407
  11. python面板数据分析代码_用python预处理面板数据(续)
  12. 自定义一个可复用的BaseAdapter
  13. keras学习率下降策略
  14. 一道面试题引发的pythonic
  15. Vue+flvjs播放flv文件
  16. 软件工程造价师有用吗?
  17. 微信小程序跳转微信公众号
  18. MAC上有哪些优秀的日常软件| 入门级Mac OS 用户必备软件
  19. c语言偶数求和while,C语言中编程计算1至100以内的奇数和偶数并分别求和,求代码...
  20. row format delimited fields terminated by ','

热门文章

  1. 转载:如何区分空间参考、坐标系统、投影、基准面和椭圆体?
  2. 灰鸽子敢说自己不是病毒?
  3. 微服务架构10个最重要的设计模式
  4. 字节开启员工期权兑换,126美元每股;
  5. 为了追求更快,CPU、内存、I/O都做了哪些努力?
  6. 面试官:谈谈分布式锁的实现
  7. 秒懂JVM的三大参数类型,就靠这十个小实验了
  8. 漫画:小白为了面试如何刷题?(呕心沥血算法指导篇)
  9. Java stream! Kafka steam!流式处理这么火!它究竟是个啥?
  10. 这7个实用工具类网站,你用过几个?