【实用工具】CMake的使用和介绍

228 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

cmake

CMake中的变量

  • 变量和含义

    常用变量含义
    PROJECT_NAME工程名变量
    PROJECT_SOURCE_DIR顶层的项目目录
    PROJECT_BINARY_DIR使用cmake的路径
    CMAKE_ROOTCMAKE安装的根目录
    CMAKE_BUILD_TYPE编译类型:emptyDebugRelease...
    CMAKE_SOURCE_DIR顶层的CMakeLists.txt所在路径
    CMAKE_BINARY_DIR顶层的CMakeLists.txtbuild所在目录
    CMAKE_<LANG>_COMPILER设定某个语言LANG的编译器,比如g++
    CMAKE_INSTALL_PREFIX指令install的路径
    CMAKE_CURRENT_SOURCE_DIR当前CMakeLists.txt所在路径
    CMAKE_CURRENT_BINARY_DIR当前CMakeLists.txtbuild所在目录
    EXECUTABLE_OUTPUT_PATH可执行文件输出路径
    LIBRARY_OUTPUT_PATH库输出路径
  • 个别变量解释 源码目录结构

         jmudou   
         ├── build.sh
         ├── CMakeLists.txt
         └── muduo
            └── base
                ├── Atomic.h
                ├── CMakeLists.txt
                ├── copyable.h
                ├── tests
                │   ├── Atomic_unittest.cc
                │   ├── CMakeLists.txt
                │   └── Timestamp_unittest.cc
                ├── Timestamp.cc
                ├── Timestamp.h
                └── Types.h
    

    三个CMakeLists.txt输出

           jmuduo/CMakeLists.txt: 
               PROJECT_SOURCE_DIR= 11/jmuduo
               PROJECT_BINARY_DIR= 11/build/debug 
               CMAKE_SOURCE_DIR= 11/jmuduo            # 指定顶层的CMakeLists.txt的,因此所有的都相同
               CMAKE_BINARY_DIR= 11/build/debug
               # 上面四项都是与整个项目相关,因此都是一致的。
               CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo     # 指定当前层的CMakeLists.txt的,因此与层相关
               CMAKE_CURRENT_BINARY_DIR= 11/build/debug
     ​
           muduo/base/test/CMakeLists.txt: 
               PROJECT_SOURCE_DIR= 11/jmuduo
               PROJECT_BINARY_DIR= 11/build/debug
               CMAKE_SOURCE_DIR= 11/jmuduo
               CMAKE_BINARY_DIR= 11/build/debug
               CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo/muduo/base/tests
               CMAKE_CURRENT_BINARY_DIR= 11/build/debug/muduo/base/tests
     ​
           muduo/base/CMakeLists.txt: 
               PROJECT_SOURCE_DIR= 11/jmuduo
               PROJECT_BINARY_DIR= 11/build/debug
               CMAKE_SOURCE_DIR= 11/jmuduo
               CMAKE_BINARY_DIR= 11/build/debug
               CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo/muduo/base
               CMAKE_CURRENT_BINARY_DIR= 11/build/debug/muduo/base
    

函数

所有的函数列表中,<>表示的参数必须要有,[]表示的参数为可选。

  • set 可以设置三个类型的变量值:正常变量,cache variable、环境变量。

    • Normal Variable:set(<variable> <value>... [PARENT_SCOPE])
    • cacheset(<variable> <value>... CACHE <type> <docstring> [FORCE])
    • envset(ENV{<variable>} [<value>])
  • OPTION:提供用户可以选择的选项

    • 格式:option(<variable> "description" [initial value])

    • 比如:

           option(
               USE_MYPATH
               "user path"
               ON
           )
      
  • aux_source_directory

    • 语法:aux_source_directory(<dir> <variable>)
    • 查找目录dir下的所有源文件(即.c, .cpp, .cc等文件),并将名称保存到 variable 变量
  • add_subdirectory

    • add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
    • 添加一个将被编译的子目录。指明CMakeLists.txt所在目录下包含了一个子目录source_dir。这样source_dir下的源文件和CMakeLists.txt等也会被处理。
  • target_link_libraries

    • target_link_libraries(exec libs)
    • 表示可执行程序exec需要链接到一个名为libs的链接库。
  • add_library

    • add_library (name dir)
    • 用在目录dir下的源文件生成一个名为name的静态链接库:libname.a
  • configure_file

    • 加入一个配置头文件,用于处理 CMake 对源码的设置

           configure_file (
               "${PROJECT_SOURCE_DIR}/config.h.in" # config.h.in文件目录
               "${PROJECT_BINARY_DIR}/config.h"    # config.h 生成的头文件目录
           )
      

      在配置文件config.h中,配置相关项,比如options中的USE_MYPATH

           #cmakedefine USE_MYMATH
      
  • include

    • include(file [optional]):读取CMake的相关文件。
    • include(moudle [optional]) the file with name .cmake is searched in the CMAKE_MODULE_PATH
  • include_directories

         include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
    

    添加指定目录到编译器搜索路径。

  • install 使用:cmake之后,sudo make install就可以执行相应的库和头文件的安装。

    • TARGET格式

       install(TARGETS targets...
               [[ARCHIVE|LIBRARY|RUNTIME]
               [DESTINATION <dir>]
               [PERMISSIONS permissions...]
               [CONFIGURATIONS [Debug|Release|...]]
               [COMPONENT <component>]  
               [OPTIONAL]
               ] [...])
      
    • targets的类型 可以安装的库有[ARCHIVE|LIBRARY|RUNTIME]三种:   1) 可执行程序视为runtime   2) 静态库视为archieve   3) Module Library视为library   4) 共享库和平台有关

    • 参数

      • DESTINATION: 指定一个文件将要被安装的目录。如果给的是一个全路径,那么就直接使用;如果是相对路径,默认是相对CMAKE_INSTALL_PREFIX,其值默认是/usr/local/。   1) 头文件:inclide   2) 可执行文件:bin   3) 库:lib
      • PERMISSIONS: 指定安装文件的权限:   1) user : OWNER_READ, OWNER_WRITE, OWNER_EXECUTE   2) group:GROUP_READ, GROUP_WRITE, GROUP_EXECUTE   3) other:WORLD_READ, WORLD_WRITE, WORLD_EXECUTE   4) uid :SETUID, and SETGID
      • CONFIGURATIONS:为安装规则建立一个配置文件列表。
  • install

    • FILES格式

       INSTALL(FILES files... 
               DESTINATION <dir>
               [PERMISSIONS permissions...]
               [CONFIGURATIONS [Debug|Release|...]]
               [COMPONENT <component>]
               [RENAME <name>] [OPTIONAL])
      
      • files:即文件名
  • 测试

    • *enanle_testing() *:启动测试

    • *add_test(testname Exename arg1 arg2 ...) *:

      • 需要先运行测试程序enanle_testing(),这个指令才有效。
      • Exename是可执行程序名,参数arg1, arg2
    • set_tests_properties(...)

      • 括号内格式:(Exename [Exename2...] PROPERTIES prop1 value1 prop2 value2),其中PROPERTIES是固定的单词不能改
      • Exename设置属性,如果没有这个属性,就报错,有如下属性:   1) WILL_FAIL:如果设置为true,那么会反转测试结果的pass/fail标志。   2) PASS_REGULAR_EXPRESSION: 匹配正则表达式,只少有一个匹配,则pass   2) FAIL_REGULAR_EXPRESSION: 匹配正则表达式,则fail
    • 宏测试

           macro(<name> [arg1 [arg2 [arg3 ...]]])
               COMMAND1(ARGS ...)
               COMMAND2(ARGS ...)
               ...
           endmacro(<name>)
      

      就类似于写一个函数,用宏实现,调用:name(arg1,arg2,...)

  • 设置项目的版本号

    • 在顶层的CMakeLists.txt中:

           # 加入版本号是 1.0
           set (Project_VERSION_MAJOR 1) # 主版本号
           set (Project_VERSION_MINOR 0) # 副版本号
      
    • 在配置文件config.h.in中设置:

           #define Project_VERSION_MAJOR @Project_VERSION_MAJOR@
           #define Project_VERSION_MINOR @Project_VERSION_MINOR@
      
    • main函数中就可以直接使用这两个宏,代表版本号:

           printf("Version %d.%d\n",
                   Project_VERSION_MAJOR,
                   Project_VERSION_MINOR);