CMake语法学习笔记

版权声明:技术源于分享 https://blog.csdn.net/hyq912/article/details/53073736

最近一直在忙新需求,本来想记录一下自己学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.1

  • aux_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


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页