深入浅出CMake(二): 基础语法
在《深入浅出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(二): 基础语法相关推荐
- PHP从入门到跑路(二),基础语法,数据库操作
基础语法 前言 一, 变量定义及使用 二,数据库操作 三, php开发细节躺坑 前言 博主不会php, 是从JAVA转过来的, PHP教程总结实际开发使用, 更加偏向于实际, 理论比较薄弱, 一直想总 ...
- Vue2.0学习笔记二 基础语法
1. Mustache语法 Mustache语法也叫插值表达式,Mustache语法式通过{{}}渲染到页面,并且数据是响应式的. 数据的响应式:数据的变化导致页面的内容随之变化 效果图: 2. 指令 ...
- 专科 java转go 翱翔之路(二)基础语法:匿名组合,方法,接口,map,json,异常处理,channel管道,select用法
2.4 面向对象编程 2.4.1匿名组合 type Person struct {id intname stringage int }type Student struct {Person //只有类 ...
- Scala语法(一) 基础语法(变量常量判断循环数组集合)
前言 在前面的章节中, 我们介绍了如何在Eclipse内安装Scala环境. 本章开始, 我们将讲解下Scala的基本语法. PS: 1. 个人虽然没有想转Scala语言开发的思想, 但是近来Scal ...
- Python基础教程(二):基础语法、变量类型
Python 基础语法 Python语言与Perl,C和Java等语言有许多相似之处.但是,也存在一些差异. 在本章中我们将来学习Python的基础语法,让你快速学会Python编程. 第一个Pyth ...
- python设计一个函数定义计算并返回n价调和函数_音乐编程语言musicpy教程(第三期) musicpy的基础语法(二)...
这个是我在github上给我的项目musicpy写的wiki,分为数据结构,基础语法,实际应用三大部分来为大家讲解这门音乐编程语言,主要是想给大家写一个musicpy的详细的教程与介绍,目前wiki只 ...
- 【Drools二】打工人学习Drools基础语法
目录 0.项目搭建 1. 规则文件 1.1 构成 1.2规则体 2.基础语法 2.1 注释 2.2 Pattern模式匹配 2.3比较操作符 2.3.1 实践 2.3执行指定规则 3.Drools内置 ...
- java基础语法(二)--单列模式
java基础语法(二)--单列模式 /*** 功能:单列模式* @author Administrator**/ public class SingletonTest {public static v ...
- HiveQL学习笔记(二):Hive基础语法与常用函数
本系列是本人对Hive的学习进行一个整理,主要包括以下内容: 1.HiveQL学习笔记(一):Hive安装及Hadoop,Hive原理简介 2.HiveQL学习笔记(二):Hive基础语法与常用函数 ...
最新文章
- winRAR 没有右键选项
- c++ shared_ptr的使用
- 移动界面控件Essential Studio for Mobile MVC图表控件解析
- 一种去中心化的manager设计思路
- Microsoft Operations Management Suite 启用NPM网络性能监视
- 对线程与进程的区别以及对多线程并发的理解
- linux chrome 安装过程记录
- 软件工程----9软件实现
- Python自省(反射) 与 inspect 模块
- 构造方法重载 java 1615136407
- python面板数据分析代码_用python预处理面板数据(续)
- 自定义一个可复用的BaseAdapter
- keras学习率下降策略
- 一道面试题引发的pythonic
- Vue+flvjs播放flv文件
- 软件工程造价师有用吗?
- 微信小程序跳转微信公众号
- MAC上有哪些优秀的日常软件| 入门级Mac OS 用户必备软件
- c语言偶数求和while,C语言中编程计算1至100以内的奇数和偶数并分别求和,求代码...
- row format delimited fields terminated by ','