前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入浅出CMake(二):基础语法及实现九九乘法表

深入浅出CMake(二):基础语法及实现九九乘法表

作者头像
Frank909
发布2019-03-19 10:51:57
9050
发布2019-03-19 10:51:57
举报
文章被收录于专栏:Frank909

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

CMake 是一套编译构建体系,所以它有自己的一套语法概念,也有自己的 CMake Language,你可以讲它看做是一套脚本语言,所以它能做很多编程的事情。

这篇博文的目的是对 CMake 的基础语法进行概括,文章最后用一个九九乘法表的例子让读者加深印象。

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

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

这些特征足够我们在日常开发中编写常见的算法逻辑,处理很多问题了。

幸运的是 CMake 有类似的语法,能实现类似的功能。

CMake 有一个很重要的概念叫做命令.

代码语言:javascript
复制
COMMAND()

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

代码语言:javascript
复制
project(test)
add_executable(hello hello.cpp)

相信不难理解,官网中关于命令完整介绍在这里

下面开始,简单对 CMake 中一些语法过一眼

条件判断 if()/endif()

比如,它可以进行条件判断

代码语言:javascript
复制
if(<condition>)
  <commands>
elseif(<condition>) # optional block, can be repeated
  <commands>
else()              # optional block
  <commands>
endif()

if() 和 endif() 是配对使用的。

循环判断 foreach()/while()

代码语言:javascript
复制
foreach(<loop_var> <items>)
  <commands>
endforeach()

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

比如

代码语言:javascript
复制
foreach(index A B C D)

也可以这样

代码语言:javascript
复制
foreach(index RANGE 9)

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

代码语言:javascript
复制
while(<condition>)
  <commands>
endwhile()

while 循环和普通的开发无多大差别,这个不细说。

当然跳出当前判断也有

代码语言:javascript
复制
break()
continue()
return()

设置变量 set()/unset()

CMake 的变量可以分为 普通变量系统环境变量

set() 命令可以设置普通变量、系统环境变量、和缓存。

代码语言:javascript
复制
set(<variable> <value>... [PARENT_SCOPE])

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

代码语言:javascript
复制
set(ENV{<variable>} [<value>])

设置系统环境变量

代码语言:javascript
复制
set(<variable> <value>... CACHE <type> <docstring> [FORCE])

设置缓存

访问变量的时候用 ${variable}

list

有自己的数据结构

代码语言:javascript
复制
Reading
  list(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>)

Search
  list(FIND <list> <value> <out-var>)

Modification
  list(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> [...])

Ordering
  list(REVERSE <list>)
  list(SORT <list> [...])

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

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

读写文件 file()

可以读写文件

代码语言:javascript
复制
Reading
  file(READ <filename> <out-var> [...])
  file(STRINGS <filename> <out-var> [...])
  file(<HASH> <filename> <out-var>)
  file(TIMESTAMP <filename> <out-var> [...])

Writing
  file({WRITE | APPEND} <filename> <content>...)
  file({TOUCH | TOUCH_NOCREATE} [<file>...])
  file(GENERATE OUTPUT <output-file> [...])

Filesystem
  file({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 Conversion
  file(RELATIVE_PATH <out-var> <directory> <file>)
  file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)

Transfer
  file(DOWNLOAD <url> <file> [...])
  file(UPLOAD <file> <url> [...])

Locking
  file(LOCK <path> [...])

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

操作字符串 string()

也可以对 string 文本进行操作

代码语言:javascript
复制
Search and Replace
  string(FIND <string> <substring> <out-var> [...])
  string(REPLACE <match-string> <replace-string> <out-var> <input>...)

Regular Expressions
  string(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>...)

Manipulation
  string(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>)

Comparison
  string(COMPARE <op> <string1> <string2> <out-var>)

Hashing
  string(<HASH> <out-var> <input>)

Generation
  string(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()

也可以向终端打印。

代码语言:javascript
复制
message([<mode>] "message to display" ...)

message() 命令可以向终端打印字符串

并且,它支持不同类型

  • none
  • STATUS
  • WARNING
  • AUTHOR_WARNING
  • SEND_ERROR
  • FATAL_ERROR
  • DEPRECATION

开发者可以根据实际情况定义不同的消息等级

数学运算 math()

还能做数学运算

代码语言:javascript
复制
math(EXPR <variable> "<expression>" [OUTPUT_FORMAT <format>])

上面命令的用法是,计算数学表达是 experssion,然后将结果保存在 variable 中,后面是指定的格式为 10 进制还是 16 进制。

正因为有了这些灵活的命令,CMake 显得无所不能,带来的好处也显而易见,程序员编写 CMakeLists.txt 会更加得心应手。

下面,我们就把 CMake 当做是一种编码语言,写一个简单的例子。

九九乘法表

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

代码语言:javascript
复制
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 .命令。

可以看到终端打印了如下结果

代码语言:javascript
复制
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 文件了。

下一篇,讲解如何用 CMake 查找第三方库。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年03月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 条件判断 if()/endif()
  • 循环判断 foreach()/while()
  • 设置变量 set()/unset()
  • list
  • 读写文件 file()
  • 操作字符串 string()
  • 终端打印 message()
  • 数学运算 math()
  • 九九乘法表
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档