编译原理与语法(五)——CMake语法详解

  • 在Android Studio 2.2及以上,构建原生库的默认工具是CMake
  • CMake是一个跨平台的支持产出各种不同的构建脚本的一个工具
  • CMake并不直接构建出最终的软件,而是产生其他工具的脚本(如makefile)

注释

单行注释:
# 注释内容

多行注释:
# [[注释内容
注释内容
注释内容]]

变量

声明变量:set(变量名 变量值)
移除变量:unset(变量名)
引用变量: ${变量名}

set(var 123)
message(WARNING "var = ${var}")

结果:var = 123

message

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

  • (none) = 重要消息
  • STATUS = 附带消息
  • WARNING = CMake警告,继续处理
  • AUTHOR_WARNING = CMake警告(dev),继续处理
  • SEND_ERROR = CMake错误,继续处理,但跳过生成
  • FATAL_ERROR = CMake错误,停止处理和生成
  • DEPRECATION = 如果分别启用了变量CMAKE_ERROR_DEPRECATED或CMAKE_WARN_DEPRECATED,则CMake弃用错误或警告,否则无消息

在高版本的CMake中,(none) 和 STATUS 两种级别的 message 不会直接打印出来,要使用其他级别

指定abi

abiFilters "armeabi", "armeabi-v7a" , "arm64-v8a", "x86", "x86_64", "mips", "mips64"

defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 25
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
                abiFilters "armeabi-v7a"
            }
        }
    }

列表

声明列表:set(列表名 值1 值2 ...值N)
声明列表:set(列表名 "值1;值2;...值N")
引用列表:${列表名}

set(list1 111 222 333)
message(WARNING "list1 = ${list1}")
set(list2 "aaa;bbb;ccc")
message(WARNING "list2 = ${list2}")

结果:
list1 = 111;222;333
list2 = aaa;bbb;ccc

流程控制

操作符
类型 名称
一元 EXIST,COMMAND,DEFINED
二元 EQUAL,LESS,LESS_EQUAL,GREATER,GREATER_EQUAL,STREQUAL,STRLESS,STRLESS_EQUAL,STRGREATER,STRGREATER_EQUAL,VERSION_EQUAL,VERSION_LESS,VERSION_LESS_EQUAL,VERSION_GREATER,VERSION_GREATER_EQUAL,MATCHES
逻辑 NOT,AND,OR
布尔常量值
类型
true 1,ON,YES,TRUE,Y,非0值
false 0,OFF,NO,FALSE,N,IGNORE,NOTFOUND,空字符串,以-NOTFOUND结尾的字符串
条件命令
  • 语法格式:
    if(表达式)
    COMMAND(ARGS...)
    endif(表达式)
    COMMAND(ARGS...)
    endif(表达式)
    COMMAND(ARGS...)
    end(表达式)
    COMMAND(ARGS...)
    endif(表达式)
    缩进和空格对语句没有影响
set(controloff OFF)
set(controlon ON)

if(${controloff})
    message(WARNING "if")
elseif(${controloff})
    message(WARNING "elseif1")
elseif(${controloff})
    message(WARNING "elseif2")
else(${controloff})
    message(WARNING "else")
endif(${controloff})

结果:else

循环命令
  • 语法格式:
    while(表达式)
    COMMAND(ARGS...)
    endwhile(表达式)
  • break()命令可以跳出整个循环,continue()可以跳出当前循环
set(a "")

while(NOT a STREQUAL "xxx")
  set(a "${a}x")
  message("a = ${a}")
endwhile()

结果:
a = x
a = xx
a = xxx
b = y
b = yyy
b = yyyy

循环遍历一

语法格式
foreach(循环变量 参数1 参数2 ... 参数N)
COMMAND(ARGS...)
endforeach(循环变量)

foreach(item 1 2 3)
  message(WARNING "item = ${item}")
endforeach(item)

结果:
item = 1
item = 2
item = 3

循环遍历二
  • 语法格式
    foreach(循环变量 RANGE total)
    COMMAND(ARGS...)
    endforeach(循环变量)
  • 循环范围从0到total
foreach(item RANGE 3)
  message(WARNING "item = ${item}")
endforeach(item)

结果:
item = 0
item = 1
item = 2
item = 3

循环遍历三
  • 语法格式
    foreach(循环变量 RANGE start stop step)
    COMMAND(ARGS...)
    endforeach(循环变量)
  • 循环范围从start到stop,循环增量为step
foreach(item RANGE 1 8 2)
  message(WARNING "item = ${item}")
endforeach(item)

结果:
item = 1

item = 3
item = 5
item = 7

循环遍历四

语法格式
foreach(循环变量 IN LISTS 列表)
COMMAND(ARGS...)
endforeach(循环变量)

set(list_foreach 1 3 ass qw3dd)
foreach(item IN LISTS list_foreach)
    message(WARNING "item = ${item}")
endforeach(item)

结果:
item = 1
item = 3
item = ass
item = qw3dd

自定义函数

命令格式:
function(name arg1 arg2 arg3 ...)
COMMAND()
endfunction(name)

function(func a b c)
  message(WARNING "a= ${a}")
  message(WARNING "b= ${b}")
  message(WARNING "c= ${c}")
  message(WARNING "ARGC= ${ARGC}")
  message(WARNING "ARGV0= ${ARGV0}")
  message(WARNING "ARGV1= ${ARGV1}")
  message(WARNING "ARGV2= ${ARGV2}")
  message(WARNING "ARGV3= ${ARGV3}")
  message(WARNING "ARGV= ${ARGV}")
endfunction(func)

func(1 www 222)

结果:
a= 1
b= www
c= 222
ARGC= 3
ARGV0= 1
ARGV1= www
ARGV2= 222
ARGV3=
ARGV= 1;www;222

变量 含义
ARGC 函数有多少个参数
ARGV+N N代表第几个参数 ARGV0第一个参数,ARGV2第二个参数,依次类推
ARGV 打印所有的参数

自定义宏命令

命令格式:
macro(name arg1 arg2 arg3 ...)
COMMAND()
endmacro(name)

macro(ma x y z)
  message(WARNING "x= ${x}")
  message(WARNING "y= ${y}")
  message(WARNING "z= ${z}")
  message(WARNING "ARGC= ${ARGC}")
  message(WARNING "ARGV0= ${ARGV0}")
  message(WARNING "ARGV1= ${ARGV1}")
  message(WARNING "ARGV2= ${ARGV2}")
  message(WARNING "ARGV3= ${ARGV3}")
  message(WARNING "ARGV= ${ARGV}")
endmacro(ma)

ma(1 2 3)

结果:
x= 1
y= 2
z= 3
ARGC= 3
ARGV0= 1
ARGV1= 2
ARGV2= 3
ARGV3=
ARGV= 1;2;3

与函数的区别

函数有自己的作用域,宏的作用域与调用者是一样的

set(funcdifmacro 100)

function(funcdif)
    set(funcdifmacro 200)
    message(WARNING "in funcdif value = ${funcdifmacro}")
endfunction(funcdif)
funcdif()
message(WARNING "out funcdif value = ${funcdifmacro}")

macro(madif)
    set(funcdifmacro 200)
    message(WARNING "in madif value = ${funcdifmacro}")
endmacro(madif)
madif()
message(WARNING "out madif value = ${funcdifmacro}")

结果:
in funcdif value = 200
out funcdif value = 100
in madif value = 200
out madif value = 200
可以看到,function里面改变的funcdifmacro 值在外部并没有生效,function使用外部变量时,会拷贝一份外部变量来操作,所以并不会改变外部变量

变量的作用域
  • 全局层:cache变量,在整个项目范围可见,一般在set定义变量时,指定CACHE参数就能定义为cache变量
  • 目录层:在当前目录CMakeLists.txt中定义,以及在该文件包含的其他cmake源文件中定义的变量
  • 函数层:在命令函数中定义的变量,属于函数作用域内的变量
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,306评论 0 5
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,618评论 0 10
  • CMake 全称“cross platform make”,是开源、跨平台的自动化构建系统。CMake 由 Kit...
    神齐阅读 3,894评论 0 6
  • 0 源文件 Cmake的源码文件,可以包含命令+注释+空格+换行。 以cmake编写的源文件以CMakeLists...
    赵国开阅读 11,555评论 1 7
  • CMake学习 本篇分享一下有关CMake的一些学习心得以及相关使用。 本文目录如下: [1、CMake介绍] [...
    AlphaGL阅读 12,151评论 11 79