最近一直在忙新需求,本来想记录一下自己学CMake的一些笔记,拖到了现在……
一、CMakeLists.txt文件
- 如果工程存在多个目录,需要确保每个要管理的目录都存在一个CMakeLists.txt文件,这是CMake的构建定义文件。
二、CMake的基本语法规则
- CMake的基本语法规则:指令(参数1 参数2 …),其中参数使用括号括起,参数之间使用空格或分号隔开。
- 指令与大小写无关的,参数和变量是大小写相关的。
三、CMake常用指令
project(projectname [CXX][C][Java])
用来定义工程名称,并指定工程支持的语言,支持的语言列表可忽略不写,默认支持所有语言。
例如://定义bzip2工程目录 project(bzip2)
set(var [value])
用来显示地定义变量,有多个变量用空格或分号隔开。
例如://定义变量FILE_PATH,用来储存两个文件路径 set(FILE_PATH C:\\cpp\\\main.c C:\\cpp\\bspatch.c)
注:
1.当我们需要用到这个变量FILE_PATH时,可以采用 var来引用变量,例如: {FILE_PATH}
2.在IF控制语句中是直接使用变量名的,无需${}cmake_minimun_required(VERSION 3.4.1)
用来指定CMake的最低版本为3.4.1aux_source_directory(dir variable)
将dir目录下的所有源代码文件的名字保存在变量variable中。
例如://将当前目录下的源代码名字保存在DIR_SRCS变量中 aux_source_directory(. DIR_SRCS)
target_link_libraries(target library1 library2 …)
指定target需要链接的library,这里的target必须已经被创建。
例如://指定main工程需要链接hello共享库或so文件 target_link_libraries(main hello) //或者: target_link_libraries(main libhello.so)
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
用于向当前工程添加一个需要进行构建的子目录,并且可以指定中间二进制文件和目标二进制文件存放的位置。
例如://当执行到该指令时,会进入到bzip2目录执行此目录的CMakeLists.txt文件 add_subdirectory(bzip2)
add_library(name [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
将一组源文件source1 source2 … sourceN编译出一个库文件,并且保存为libname.so文件(在此不需写全libname,只需填写name即可,CMake会自动为你生成libname.so)。
其中SHARED表示动态库,在代码中使用loadLibrary动态调用;STATIC表示静态库,集成到代码中会在编译时调用;MODULE只有在使用dyld的系统有效,如果不支持dyld,则被当作SHARED对待。
EXCLUDE_FROM_ALL表示这个库不被默认构建,除非有其他组件依赖或手工构建。
例如://将bspatch.c编译为一个名为libbspatch.so的共享库 add_library(bspatch SHARED bspatch.c)
add_library命令也可以用来创建导入的库目标。
add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED)
导入的库目标是引用了在工程外的一个库文件的目标。没有生成构建这个库的规则。这个目标名字的作用域在它被创建的路径及以下有效。它可以向任何在该工程内构建的目标一样被引用。导入库为类似于target_link_libraries命令中引用它提供了便利。关于导入库细节可以通过指定那些以IMPORTED_的属性设置来指定。其中最重要的属性是IMPORTED_LOCATION(以及它的具体配置版本,**IMPORTED_LOCATION**_),它指定了主库文件在磁盘上的位置。
find_library(variable name1 path1 path2 …)
查找库文件name1的全路径(包含库文件名),如果找到将路径保存在变量variable中,如果没有找到则结果为variable_NOT_FOUND。
例如://将log库文件路径保存在变量log_lib中,并将bspatch工程链接引入log库 find_library(log_lib log) target_link_libraries(bspatch ${log_lib})
set_target_properties(target1 target2 … PRORERTIES prop1 value1 prop2 value2 …)
用来设置输出的名称。
例如://导入libavutil-55.so库文件 add_library(avutil-55 SHARED IMPORTED) //设置需要引用的libavutil-55.so库文件路径,其中IMPORTED_LOCATION库文件在磁盘上的位置 set_target_properties(avutil-55 PROPERTIES IMPORTED_LOCATION ../libs/armeabi-v7a/libavutil-55.so)
四、CMake常用变量
一般来说,我们可以用set指令显示定义一个变量,但CMake系统已经帮我们隐式预定义了一些变量,可以采用${VAR}方式来调用这些变量,以下记录一些Android CMakeLists.txt文件中常用的变量。
PROJECT_SOURCE_DIR
当前工程的源码路径。PROJECT_BINARY_DIR
指向工程构建目录的全路径。CMAKE_VERSION
CMake的完整版本号;格式为major.minor.patch[.tweak[-id]]CMAKE_CURRENT_SOURCE_DIR
调用这个变量的CMakeLists.txt所在路径CMAKE_CURRENT_LIST_FILE
调用这个变量的CMakeLists.txt的完整路径CMAKE_CURRENT_LIST_LINE
这个变量所在的行数PROJECT_NAME
返回通过project指令定义的项目名称
- 以上只是最近学NDK总结出的小部分CMake知识点,对于真正使用CMake的人来说,犹如大海里的一根针般渺小,勿喷
真正想了解CMake构建工具的朋友,可以参看以下链接:
1.CMake手册详解:http://www.cnblogs.com/coderfenghc/tag/cmake/
2.CMake实践:http://pan.baidu.com/s/1jI2RWqE