CMake入门

CMake是一个跨平台的构建工具,可以用简单的语句来描述所有平台的安装(编译)过程,能够输出各种各样的makefile或者project文件。CMake并不直接构建出最终的软件,而是产生其他工具的脚本(如makefile),然后再依据这个工具的构建方式使用。

  • Android利用CMake生成的是ninja(ninja是个小型的关注速度的构建系统)。
  • CMake源文件中所有的有效语句都是命令,可以是内置命令或自定义的函数/宏命令。

1. 基础语法

注释
#[[多行注释
多行注释
多行注释]]
定义变量

CMake中所有的变量都是string类型,可以使用set()和unset()命令来声明或者移除一个变量。

#set(变量名 变量值)
set(var 123)
#message() 打印
message("var = ${var}")
列表

列表也是一个字符串,可以把列表看成一个特殊的变量,这个变量有多个值。

#列表声明 set(列表名 值1 值2 值3) 或者 set(列表名 "值1;值2;值3")
set(list_var 1 2 3)
set(list_var1 "1;2;3")
message("list_var = ${list_var}")
条件命令
#和其他语言差不多,不过if和else都可以加表达式,注意endif,而且缩进和空格对语句解析没有影响
set(if_tap OFF)
set(elseif_tap ON)
if(${if_tap})
    message("if")
elseif(${elseif_tap})
    message("elseif")
else(${if_tap})
    message("else")
endif(${if_tap})
循环命令

while(表达式)
COMMAND(ARGS...)
endwhile(表达式)

break()命令可以跳出整个循环,continue()可以跳出当前循环

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

循环遍历
foreach(循环变量 参数1 参数2 参数3)
COMMAND(ARGS...)
endforeach(循环变量)

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

foreach(循环变量 RANGE total)
COMMAND(ARGS...)
endforeach(循环变量)
total循环范围为 0-total

foreach(item RANGE 3)
   message("item = ${item}")
endforeach(item)

foreach(循环变量 RANGE start stop step)
COMMAND(ARGS...)
endforeach(循环变量)

循环范围为 start-stop 增量为step

foreach(item RANGE 1 5 2)
    message("item = ${item}")
endforeach(item)

foreach(循环变量 IN LIST 列表)
COMMAND(ARGS...)
endforeach(循环变量)

set(list 1 2 3)
foreach(item IN LISTS list)
   message("item = ${item}")
endforeach(item)
自定义函数

function(name args1 args2 args3)
COMMAND()
endfunction(name)
name(实参列表)

function(func a b c)
   message("a = ${a}")
   message("b = ${b}")
   message("c = ${c}")
   # 参数个数
   message("ARGC = ${ARGC}")
   # 参数列表
   message("ARGV = ${ARGV}")
   message("ARGV0 = ${ARGV0}")
endfunction(func)
func(4 5 6)

自定义宏命令
macro(name args1 args2 arg3)
COMMAND()
endmacro(name)
name(实参列表)

macro(ma x y)
   message("x = ${x}")
   message("y = ${y}")
   endmacro()
ma("hello" "world")
变量的作用域

全局层:cache变量,在整个项目范围可见,一般在set定义变量时,指定CACHE参数就能定义为cache变量。
目录层:在当前目录CMakeLists.txt中定义,以及在该文件包含的其他cmake源文件中定义的变量。
函数层:在命令函数中定义的变量,属于函数作用域内的变量。

2. 在Android常用到的方法

#查找当前目录所有源文件,并将源文件名称列表保存到DIR_SRCS变量中
#不能查找子目录
aux_source_directory(.DIR_SRCS)
message(${DIR_SRCS})
添加一个常用库
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 soure2 .. sourceN)

name:添加一个库文件,名为<name>,会生成 lib<name>.so
指定库的类型:STATIC , SHARED , MODULE
STATIC:静态库
SHARED:动态库
MODULE:在使用dyld的系统有效,如不支持dyld,等同于dyld
EXCLUDE_FROM_ALL:表示该库不会被默认构建
source:指定库的源文件

导入预编译库
add_library(<name> <SHARE|STATIC|MODULE|UNKNOWN> IMPORTED)
<name> 添加一个已存在的预编译库,名为<name>

#一般配合set_target_properties使用
# 比如
add_library(test SHARED IMPORTED)
set_target_properties(
    test # 指定目标库名
    PROPERTIES IMPORTED_LOCATION # 指明要设置的参数
    库路径/${ANDROID_ABI}/libtest.so # 指明要导入的库路径
)
set常用命令
# 设置可执行文件的输出路径(EXCUTABLE_OUTPUT_PATH是全局变量)
set(EXCUTABLE_OUTPUT_PATH [output_path])
# 设置库文件的输出路径(LIBRARY_OUTPUT_PATH是全局变量)
set(LIBRARY_OUTPUT_PATH [output_path])
# 设置C++编译参数(CMAKE_CXX_FLAGS是全局变量)
set(CMAKE_CXX_FLAGS "-Wall std=c++11")
# 设置源文件集合(SOURCE_FILES是本地变量即自定义变量)
set(SOURCE_FILES main.cpp test.cpp ...)
设置头文件目录
include_directories(./include ${MY_INCLUDE})
添加可执行文件
add_executable(<name> #{SRC_LIST})
添加预编译库
# CMAKE_C_FLAGS c的参数,会传递给编译器
# 如果是C++文件,需要使用CMAKE_CXX_FLAGS
# -L:库的查找路径
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[SO所在的目录]")

3. Android中的默认脚本

# 添加一个库,根据native-lib.cpp 源文件编译一个native-lib的动态库
add_library(
    native-lib
    SHARED
    native-lib.cpp)
# 查找系统库,这里是查找了系统的日志库(liblog),并赋值给变量log-lib
# 这个库位于 Android/sdk/ndk-bundle/platforms/android-28/arch-arm64/usr/lib
find_library(
    log-lib
    log)
# 设置依赖库(第一个参数必须为目标模块,顺序不能替换)
target_link_libraries(
    native-lib
    ${log-lib})

补充

在Android Studio中调试命令时,一些高版本可能不会输出CMake指令,但是可以在其他地方查看,具体路径为

app/.externalNativeBuild/cmake/debug/armeabi-v7a/cmake_build_output.txt

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

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,310评论 0 5
  • Cmake 入门 前言 CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应...
    渝潼不肖生阅读 1,986评论 1 5
  • Written with StackEdit. CMake是什么 CMake是一个opensource的软件项目构...
    peterzen阅读 4,301评论 0 2
  • 文章翻译自:CMake Tutorial 第一步 | 第二步 | 第三步 | 第四步 | 第五步 | 第六步 | ...
    汪坤阅读 13,697评论 1 23
  • 什么是 CMake CMake是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不相依于某特定编译器。...
    苏州韭菜明阅读 22,551评论 6 75