cmake基于语法和应用

简介: cmake基于语法和应用

CMake中的变量

  • 变量和含义
常用变量 含义
PROJECT_NAME 工程名变量
PROJECT_SOURCE_DIR 顶层的项目目录
PROJECT_BINARY_DIR 使用cmake的路径
CMAKE_ROOT CMAKE安装的根目录
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])
  • cache:set(<variable> <value>... CACHE <type> <docstring> [FORCE])
  • env:set(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);
  • 生成安装包需要利用CPack工具,也是CMake提供的工具。
  • 先在顶层CMakeLists.txt中末尾添加:
# 构建一个 CPack 安装包
    include(InstallRequiredSystemLibraries)
    set (CPACK_RESOURCE_FILE_LICENSE
        "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
    set (CPACK_PACKAGE_VERSION_MAJOR "${Project_VERSION_MAJOR}")
    set (CPACK_PACKAGE_VERSION_MINOR "${Project_VERSION_MINOR}")
    include (CPack)
  • 导入InstallRequiredSystemLibraries模块,以便之后导入CPack模块
  • 设置一些CPack相关变量,包括版权信息和版本信息,其中版本信息用了上一节定义的版本号
  • 导入CPack模块
  • 生成二进制安装包:cpack -C CPackConfig.cmake
  • or 生成源码安装包
  • 格式:cpack -C CPackSourceConfig.cmake
    在执行该命令的目录下得到:
# Demo8是项目名
    $ ls -l | grep Demo8
    -rwxrwxrwx 1 szz szz  8631 Dec 12 22:03 Demo8-1.0.1-Linux.sh
    -rw-rw-r-- 1 szz szz  3709 Dec 12 22:03 Demo8-1.0.1-Linux.tar.gz
    -rw-rw-r-- 1 szz szz  4982 Dec 12 22:03 Demo8-1.0.1-Linux.tar.Z
  • 安装:sh Demo8-1.0.1-Linux.sh。
    默认的安装路径:
By default the Demo8 will be installed in:
    "~/Study/SystemProgram/CMakeExe/Demo8/build/Demo8-1.0.1-Linux"
    
    Do you want to include the subdirectory Demo8-1.0.1-Linux?
    Saying no will install in: "~/Study/SystemProgram/CMakeExe/Demo8/build" [Yn]: 
  • 运行。安装后,就运行该程序
$ ./Demo8-1.0.1-Linux/bin/Demo 2 5
    Now we use our own Math library. 
    2 ^ 5 is 32
  • Demo8-1.0.1-Linux下的目录结果
Demo8-1.0.1-Linux
    ├── bin
    │   └── Demo        # 可执行程序
    ├── include         # 头文件
    │   ├── config.h
    │   └── MathFunctions.h
    └── lib             # 静态库
        └── libMathFunctions.a
  • target_compile_definitions
  • 格式
target_compile_definitions(<target>
                              <INTERFACE|PUBLIC|PRIVATE> [items1...]
                              [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • 作用:编译时定义的宏
  • string
  • REPLACE
string(REPLACE 
          <match_string> <replace_string> 
          <output_variable> <input> [<input>...])
  • 将所有input中出现的match_String替换为replace_string,并且将结果存在output_variable。
  • message
message([<mode>] "message to display" ...)
  • 显示信息给用户mode取决于信息的类型:
  • STATUS:以简洁的方式显示用户感兴趣的信息。
message(STATUS 
            "CXX_FLAGS = " 
            ${CMAKE_CXX_FLAGS} 
            " " 
            ${CMAKE_CXX_FLAGS_${BUILD_TYPE}}
            )
  • 可以理解为printf,把后面的几个信息以空格相间,然后打印出来。显示结果为(和上面对应分成三段):
CXX_FLAGS = 
    
    -g -D_FILE_OFFSET_BITS=64 -Wall -Wextra 
    -Werror -Wconversion -Wno-unused-parameter 
    -Wold-style-cast -Woverloaded-virtual 
    -Wpointer-arith -Wshadow -Wwrite-strings 
    -march=native -rdynamic 
    
    -O0
  • find_package
find_package(<PackageName> 
                [version] [EXACT] [QUIET] [MODULE]
                [REQUIRED] [[COMPONENTS] [components...]]
                [OPTIONAL_COMPONENTS components...]
                [NO_POLICY_SCOPE])
  • 主要是寻找和加载外部项目。如果PackageName找到了,PackageName-found会显出,当没有找到时,默认显示PackageName-not found。通过模式的选择,可以处理在没有找到包时的解决方案。
  • QUIET:不显示有用信息,
  • REQUIRED:报错
  • find_path
find_path (<VAR> name0|NAMES name1 [path1 path2 ...])
  • 用以寻找包含着name1文件的目录,如果找到了结果存储在VAR,没有找到结果结果是VAR-not found。成功时,变量被清除find_path再次搜索,没有成功,fin_path再次以相同的变量被调用时搜索。
  • find_library同上find_path
find_library (<VAR> name0|NAMES name1 [path1 path2 ...])
  • OPTIONS
  • NAMES
    为library指定一个或多个可能的名字。


相关文章
|
5月前
|
C语言 Windows
使用CMake调用Makefile 项目
使用CMake调用Makefile 项目
83 0
|
5月前
|
Unix C++
在VS2019中CMake生成出现报错
在VS2019中CMake生成出现报错
598 0
在VS2019中CMake生成出现报错
|
5月前
|
存储 自然语言处理 Linux
CMake基础(1)初识CMake
CMake基础(1)初识CMake
50 0
|
5月前
|
C语言
gcc的简易用法
【5月更文挑战第10天】gcc的简易用法。
64 8
|
5月前
CMake中FindPackageHandleStandardArgs.cmake文件的作用和用法
CMake中FindPackageHandleStandardArgs.cmake文件的作用和用法
124 2
|
5月前
|
iOS开发 MacOS
CMake基础:CMake中的常用变量的命令
CMake基础:CMake中的常用变量的命令
56 0
|
5月前
|
编译器 C语言
gcc/g++语法
gcc/g++语法
|
11月前
|
存储 Cloud Native Linux
CMake学习之注释
CMake学习之注释
|
11月前
|
存储 Cloud Native Linux
CMake学习之第一个cmake
CMake学习之第一个cmake
|
Shell
关于CMake中引号用法的说明
关于CMake中引号用法的说明
209 0