zoukankan      html  css  js  c++  java
  • cmake 常用指令入门指南


    本博客记录:在使用cmake进行构建工程时,写CMakeLists.txt 文件时,常使用到的命令与变量, 不断补充更新中。

    相关链接

    官方地址: https://cmake.org/cmake/help/
    git上很好实践教程: https://github.com/ttroy50/cmake-examples

    CMKAE中脚本相关的命令

    cmake_minimum_required 命令

    语法与参数介绍

    语法: cmake_minimum_required(VERSION min[...policy_max] [FATAL_ERROR])

    • min 指定了编译当前的cmake需要的最old的版本号,如果cmake版本号小于指定的版本号时,运行cmake 就报错。

      举例:当前有cmake版本号为3.10.2, 运行如下的CMakeLists.txt 文件时, 就会报错:

      cmake_minimum_required(VERSION 3.12)
      

      运行cmake命令,报错如下:提示运行版本小于要求的最小版本。

      CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
      CMake 3.10.3 or higher is required.  You are running version 3.10.2
      
      
      -- Configuring incomplete, errors occurred!
      
    • ... 表示min或max版本号之间的连接符。

    • policy_max 参数与cmake的policy setting相关,当指定了【policy_max】参数(要大于等于min版本号)时, 所有【小于等于 policy_max版本 或者 小于等于当前运行版本(谁小取谁)】中的已经的policy都设置为NEW.

      policy 可以理解为版本之间的变更,例如语法新增加、约束变严等, policy使用CMPXXXX格式的编号,例如:CMP0000表示cmake文件中必须指定要求的最低版本号,CMP0002表示....等。
      在新的版本中,如果要指定policy的新的规定, 语法为: cmake_policy(SET CMPXXXX NEW), 有时候为了新版本兼容之前写的CMakeLists.txt文件, 则可以使用原来的policy, 语法为:cmake_policy(SET CMPXXXX OLD).
      可以使用cmake_policy(VERSION min[...max])指定policy的要求min与max版本号:
      - 当不指定max版本号时,cmake会把min版本以及之前的版本引入的所有policy设置为NEW, 大于min版本号引入的policy默认不设置。
      - 当指定max版本号时, cmake会把 【max版本或者当前运行的版本号(谁小取谁)】以及之前的版本号引入的的所有polixy设置为NEW, 超过的版本引入的policy默认不设置。
      当使用cmake_minimum_required(VERSION)命令时,会隐式地调用cmake_policy(VERSION)命令用于设置policy相关的版本要求。

    举例: 下面的cmake命令:

    cmake_mini_mum_required(VERSION 3.12...3.15)
    
    # 上面命令会隐示地调用下面这条命令
    cmake_policy(VERSION 3.12...3.15)
    
    • FATAL_ERROR
      该选项在2.6涉及2.6版本以下有用, 当指定该选项时,如果当前支行的版本号小于要求的版本号,就会报错;如果不指定该选项时,只会报warning. 2.6版本之后,都是报错了,所以用不着该选项了。

    引入的变量

    • CMAKE_MINIMUM_REQUIRED_VERSION : 设置该变量的值为 min.

    file 命令

    file 命令专门用于访问文件系统对文件与路径进行操作的。

    读相关

    写相关

    文件系统相关

    file(GLOB variable 通配符表达式)

    语法与参数

    使用语法为: file(GLOB <variable> [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS] [<globbing-expressions>...])
    含义: GLOB, 就是globbing的缩写, 该命令查找所有在当前目录(CMakeLists.txt所在目录,即CMAKE_CURRENT_SOURCE_DIR变量)下所有满足匹配通配符表达式的文件,并保存到给定的变量中。

    • GLOB: 是关键字。
    • variable: 保存文件名的变量
    • LIST_DIRECTORIES true| false : 表示是否要保存文件的路径,默认保存。 (试了一下,置为false为什么不管用呢?)
    • RELATIVE path: 给定该参数时,保存的路径中是相对于给定path的路径名。
    • globbing-expressions: 通配符表达式。

    使用举例

    file(GLOB source_list "src/*.cpp")
    

    注意事项

    不建议使用该命令搜索源文件名,原因是:如果CMakeLists.txt文件没有变化,但是你增加了源文件, 此时给的结果不一样正确。(我试了一下,ubuntu下可以给出正确结果)

    路径转换相关

    set命令

    设置普通的命令

    使用语法:set(<variable> <value>... [PARENT_SCOPE]), 设置一个变量的值。 如果不给定值,就表示取消该变量的设置。

    • PARENT_SCOPE: 表示在上层作用域内设置变量的值。

    使用举例

    set(SOURCE_LIST 1.c 2.c 3.c)
    

    设置cache 变量

    使用语法与参数含义

    语法:set(<variable> <value>... CACHE <type> <docstring> [FORCE]), 该命令会设置的cache变量会被保存到CMakeCache.txt 文档中, 可以打开看看的。

    • CACHE 是关键字。
    • type 表示变量的类型, 包含: BOOL、FILEPATH、PATH、STRING、INTERNAL。
    • docstring: 类型注释,表明该参数的含义。
    • FORCE: 默认情况下,如果该cache 变量已经设置过了,再次执行该变量就不会被写入,如果使用了FORCE关键字的话,只要命令被执行,就会对变量进行写入的。

    使用举例

    set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
    

    set_property 命令

    使用语法与参数含义

    该命令用于设置一个对象的属性信息, 它的使用语法如下所示:

    set_property(<GLOBAL                      |
                  DIRECTORY [<dir>]           |
                  TARGET    [<target1> ...]   |
                  SOURCE    [<src1> ...]
                            [DIRECTORY <dirs> ...] |
                            [TARGET_DIRECTORY <targets> ...]
                  INSTALL   [<file1> ...]     |
                  TEST      [<test1> ...]     |
                  CACHE     [<entry1> ...]    >
                 [APPEND] [APPEND_STRING]
                 PROPERTY <name> [<value1> ...])
    
    • [对象类型] [对象名称]: 指定了对象的类型以及要设置的对象名称, 包含: GLOBAL, DIRECTORY, TARGET, SOURCE 等。例如TARGET hello_main.
    • PROPERTY 属性名: 指定了要设置的属性名以及属性值。

    使用举例

    cmake_minimum_required(VERSION 3.10.2)
    project(hello_main)
    add_executable(hello_main main.cpp)
    set_property(TARGET hello_main PROPERTY CXX_STANDARD 11)
    

    include 命令

    ** 语法与参数说明**

    该命令用于导入文件或模块中的CMAKE代码, 类似于c语言中的include 功能。 使用语法为:

    include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                          [NO_POLICY_SCOPE])
    
    • file | module: 指定的包含CMKE指定的文件 或者 模块名。模块名其实就是安装cmake时已经提供的***.cmake文件(例如/usr/share/cmake-3.10/Modules/目录下好多模块)
    • OPTIONAL: 如果指定了该选项,当cmake查找不到指定文件时,不会报错, 因为它是可选的嘛。
    • RESULT_VARIABLE var: 用于保存查找到的文件路径(查找成功时) 或者保存失败结果NOTFOUND(失败时)

    举例说明

    cmake_minimum_required(VERSION 2.8)
    project (hello_cpp11)
    
    #这里导入CheckCXXCompilerFlag模块, 并运行该模块内的CHECK_CXX_COMPILER_FLAG命令。
    include(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
    CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
    

    message 命令

    该命令是用于记录log消息的,使用语法为:message([<mode>] "message text" ...)。 其中,mode 关键字用于表示要记录的log的类型,常用的有:

    • FATAL_ERROR: cmake errer, 遇到该错误,cmake 直接停止处理。
    • WARNING: 警告信息, 但是cmake会继续执行下去的。
    • STATUS: 用于记录一些cmake 运行过程中的有用的信息。

    例如:

    message(STATUS "hello, world.")
    set(NAME xiaoming)
    messaeg(STATUS "hello, ${NAME}")
    

    CMAKE中project相关命令

    project 命令

    语法与参数

    使用语法为:project(项目名字, [VERSION 版本号] [DESCRIPTION 描述字符串] ), 例如:

    project(myproject, VERSION 1.0.0 DESCRIPTION "my first project" )
    
    • 项目名字, 即指定一个项目名字
    • VERSION, 指定项目的版本号, 可选字段, 一般不用不着它,不学习,不介绍
    • DESCRIPTION, 项目的描述, 可选字段,一般也不需要用它,不学习,不介绍
    • 还有其它的可选参数,例如HOMEPAGE_URL, LANGUAGES, 用不着,不介绍

    隐式引入的变量

    • PROJECT_NAME: 它的值为 最近调用的project()命令设置的项目名, 例如你的子目录中调用了project()命令,那么该变量名在子目录中的值就是新设置的项目名。
    • CMAKE_PROJECT_NAME: 它的值为 最top 层的 project 设置的项目名
    • PROJECT_SOURCE_DIR: 最近 调用project() 命令定义的项目所在的源文件的绝对路径。
      例如:在根目录中定义的CMakeLists.txt文件中调用了project()命令, 在该作用域内, 该变量的值就是定义该CMakeLists.txt的绝对路径。
      如果在子目录中定义的CMakeLists.txt文件中也调用了project()命令, 在子目录中CMakeLists.txt的作用域内,该变量的值就是子目录的绝对路径。
    • PROJECT_BINARY_DIR: 最近调用project()命令定义的项目的binary的绝对路径。 与调用cmake命令的位置有关, 通常会在build 目录下调用cmake, 所以该binary目录都在build 目录内。
    • <PROJECT-NAME>_SOURCE_DIR: 首先不推荐使用它,如果你修改的项目名字,该变量名也需要适配。 它的值与PROJECT_SOURCE_DIR变量的值相同。
    • <PROJECT-NAME>_BINARY_DIR: 不推荐使用, 与PROJECT_BINARY_DIR的值相同。

    add _executable 命令

    普通的可执行文件

    语法与参数说明

    使用语法为:add_executable(name [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [source1] [source2] ...). 例如:

    cmake_minimum_required(VERSION 3.12)
    add_executable(myMain 1.c 2.c)
    
    • name : 即可执行文件的名字。windows平台下实际产生的可执行文件名为name.exe, linux平台下产生的可执行文件名就是name.

    • WIN32关键字: 用不着,不学习,跳过。

    • MACOSX_BUNDLE: 用不着,不学习,跳过。

    • source1: 源文件列表, 多个源文件使用空格分开,说明如下:

      1. 从3.1版本开始, 可以使用“generator expressions"语法表示($<...>)依赖的源文件列表。
      2. 在该命令中可以暂时不写依赖的源文件列表, 后续由target_sources() 再添加源文件列表。
    • EXCLUDE_FROM_ALL:当指定该参数时,要构建的target 就会被排除在all target 列表之外, 这样当执行makemake all时, 该target 不会被编译。

    相关变量

    • CMAKE_RUNTIME_OUTPUT_DIRECTORY: 该变量指定了生成的可执行文件的保存路径.

    import可执行文件

    用到的时候补。

    alias可执行文件

    使用语法:add_library(<name> ALIAS <target>), 为给定的target添加一个别名name. 例如:

    add_library(other_name ALIAS mylib)
    

    add_library 命令

    Normal Libraries

    语法与参数说明

    使用语法:add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [<source>...]) , 该命令用于添加一个库文件的target, 包含静态库、动态库等。

    • name: target的名字。
    • [STATIC | SHARED | MODULE]: STATIC 表示静态库,SHARED 表示动态库,MODULE表示模块库,可以在运行时使用 dlopen 之类的命令动态加载的插件。
    • EXCLUDE_FROM_ALL: 与add_executable命令中的参数相同,当指定该参数时,要构建的target 就会被排除在all target 列表之外。
    • source: 源文件列表。

    例如举例

    add_library(hello_library STATIC src/Hello.cpp)
    

    相关变量

    • ARCHIVE_OUTPUT_DIRECTORY: 修改静态库的输出路径。
    • LIBRARY_OUTPUT_DIRECTORY: 修改动态库的输出路径。
    • ARCHIVE_OUTPUT_NAME: 修改静态库的输出路径。
    • LIBRARY_OUTPUT_NAME: 修改动态库的输出路径。

    target_include_directories 命令

    语法与参数说明

    语法:target_include_directories(<target> [SYSTEM] [AFTER|BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

    当编译给定target时,该命令用于指令要包含的路径名。 当使用 gcc 编译器编译目标时,就会使用-I选项指定该命令添加的路径, 使用-I directory/include.

    • target: 要编译的目标文件
    • SYSTEM: 感觉用不到,跳过。
    • AFTER 或 BEFORE: 控制把需要添加的路径append 还是 prepend 到已有的路径列表中。
    • INTERFACE/PUBLIC/PRIVATE: 这几个关键字很有用。
      • 从内部实现上讲: 当使用PRIVATEPUBLIC 指定路径名时, 会把路径名添加到target的INCLUDE_DIRECTORIES属性中; 当使用PUBLICINTERFACE指定路径名时, 会把路径名添加到target的INTERFACE_INCLUDE_DIRECTORIES的属性中。
      • 从外部表现上讲:使用PRIVATE关键字时,添加的路径只会在编译当前target时使用到。 当使用INTERFACE关键字时,添加的路径只会在编译任何链接到当前target的目标文件时使用到。 使用PUBLIC关键字时,会包含以两种使用。 因此,通常情况下,如果target是可执行文件,建议使用PRIVATE, 如果target是动态或静态库, 建议使用PUBLIC,比较方便。

    命令举例

    target_include_directories(mylib PUBLIC include/1.h PUBLIC ${PROJECT_SOURCE_DIR}/include)
    target_include_directories(mytarget PRIVATE ${PROJECT_SOURCE_DIR}/include)
    
    

    语法及参数含义

    使用语法: target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <item>...[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
    该命令的用于指定一个target的链接阶段的依赖库。 它还可以 propagate any include directories with PUBLIC or INTERFACE scope from the linked library target.

    PRIVATE|PUBLIC|INTERFACE的作用

    暂时不太明白。

    使用举例

    target_link_libraries( hello_binary PRIVATE hello_library)
    

    install 命令

    Installing Target

    语法与参数

    该命令用于安装指定的target到指定目录内。 全量的使用语法为:

    install(TARGETS targets ... [EXPORT <export-name>]
            [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET <set-name>]
            [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
              PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
             [DESTINATION <dir>]
             [PERMISSIONS permissions...]
             [CONFIGURATIONS [Debug|Release|...]]
             [COMPONENT <component>]
             [NAMELINK_COMPONENT <component>]
             [OPTIONAL] [EXCLUDE_FROM_ALL]
             [NAMELINK_ONLY|NAMELINK_SKIP]
            ] [...]
            [INCLUDES DESTINATION [<dir> ...]]
            )
    
    • TARGET targets: 指明了要安装的target.
    • ARCHIVE|LIBRARY|RUNTIME等: 指明了target的类型。
    • DESTINATION dir: 指明了要安装到的路径。当使用相对路径时,是相对于变量CMAKE_INSTALL_PREFIX的, 该变量默认为/usr/local/, 也可以在CMakeLists.txt文件中指定,也可以在运行CMAKE命令时指定,例如:cmake .. -DCMAKE_INSTALL_PREFIX=/install/location

    使用举例

    install(TARGETS mylib LIBRARY DESTINATION lib)
    install(TARGETS mybin RUNTIME DESTINATION bin)
    

    Installing Directories

    该命令用于安装指定的目录(包含目录内的文件)到指定目录。

    使用语法与参数说明

    install(DIRECTORY dirs...
            TYPE <type> | DESTINATION <dir>
            [FILE_PERMISSIONS permissions...]
            [DIRECTORY_PERMISSIONS permissions...]
            [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
            [CONFIGURATIONS [Debug|Release|...]]
            [COMPONENT <component>] [EXCLUDE_FROM_ALL]
            [FILES_MATCHING]
            [[PATTERN <pattern> | REGEX <regex>]
             [EXCLUDE] [PERMISSIONS permissions...]] [...])
    
    • DIRECTORY dirs: 要安装的头文件的目录路径,默认为相对于当前的路径。 注意:如果路径以/结尾时, 会把路径里面的内容复制到给定路径,如果没有以/结尾,则也会复制该层目录的。
    • DESTINATION: 要安装到的目录路径。

    使用举例

    install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)
    

    Installing Files

    使用语法与参数介绍

    该命令用于安装指定的文件到指定目录:

    install(<FILES|PROGRAMS> files...
            TYPE <type> | DESTINATION <dir>
            [PERMISSIONS permissions...]
            [CONFIGURATIONS [Debug|Release|...]]
            [COMPONENT <component>]
            [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
    
    • FILES files: 指定要安装的文件。
    • DESTINATION dir: 指定要安装的路径。

    使用举例

    install(FILES cmake.config DESTINATION etc)
    

    target_compile_definitions

    使用语法与参数定义

    该命令用于指定指定编译给定的target时,要定义的宏名称:

    target_compile_definitions(<target>
      <INTERFACE|PUBLIC|PRIVATE> [items1...]
      [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
    
    
    • target: 要指定编译的target。
    • INTERFACE/PUBLIC/PRIVATE: 与之前介绍的类似, 从内部实现是讲: 当使用INTERFACEPUBLIC时,会把宏定义指定赋值给INTERFACE_COMPILE_DEFINITIONS变量, 当使用PUBLICPRIVATE时,会把宏定义内容赋值给COMPILE_DEFINITIONS变量。从外部表现上讲, 当使用INTERFACEPUBLIC时,表示编译任何链接到该target(当target是一个库时)的目标文件时,都增加了该宏定义。当使用PUBLICPRIVATE时,表示编译当前target时,才使用该宏定义。
    • items1: 表示要定义的宏名字。

    其它方法:1. 修改变量CMAKE_CXX_FLAGS(c++) 或者CMAKE_C_FLAGS(C代码),也可以实现该效果,但是建议使用target_compile_definitions命令。
    2. 在执行cmake 命令时,也可以通过参数指定,例如:cmake .. -DCMAKE_CXX_FLAGS="-DCHINA", 它就会定义一个CHINA的宏定义。

    使用举例

    main函数定义如下:

    #include <iostream>
    int main() {
    #ifdef CHINA
    	std::cout << "I Love CHINA" << std::endl;
    #endif
    	return 0;
    }
    
    cmake_minimum_required(VERSION 3.10.2)
    add_executable(myTarget main.c)
    target_compile_definations(myTarget PRIVATE CHINA)
    

    add_subdirectory 命令

    该命令用于增加一个构建的子目录。 注意执行的数据流: cmake 命令会执行完子目录中的CmakeLists.txt文件之后,再执行后面的命令。

    使用语法与参数说明

    使用语法为: add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

    • source_dir: 要添加的子目录, 建议使用相对路径啊(相对于当前位置)。
    • binary_dir: 用于保存输出文件位置。 一般都不写。
    • EXCLUDE_FROM_ALL: 该参数很熟悉了,就是编译的时候(make 或 make all),默认不被编译。如果想要编译它,显示自己执行。

    举例

    cmake_minimum_required(VERSION 3.10.2)
    project(example)
    add_subdirectory(subdir1)
    add_subdirectory(subdir2)
    

    set_target_properties 命令

    该命令用于设置给定target的一些属性值,类似于类对象的成员变量的值。 它们会影响到该target如何被构建的。

    使用语法与参数说明

    使用语法为:

    set_target_properties(target1 target2 ...
                          PROPERTIES prop1 value1
                          prop2 value2 ...)
    
    • target1... : 要设置的target的名字。
    • PROPERTIES: 后面跟要设置的属性的名字以及它们的值。

    使用举例

    cmake_minimum_required(VERSION 3.10.2)
    project(hello_main)
    add_executable(hello_main main.cpp)
    set_target_properties(hello_main PROPERTIES CXX_STANDARD 11)
    

    target_compile_features 命令

    该命令用于 Specifies compiler features required when compiling a given target.

    使用语法与参数说明

    使用语法为:target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...]).

    • target: 要编译的目标文件的名称。
    • PRIVATE | PUBLIC | INTERFACE : 这个关键字已经介绍过N次了,它指明了什么场景下生效该设置。
    • feature: 就是支持的一些feature了,例如:cxx_std_98cxx_std_11cxx_rvalue_references等。

    使用举例

    cmake_minimum_required(VERSION 3.10.2)
    project(hello_main)
    add_executable(hello_main main.cpp)
    target_compile_features(hello_main PRIVATE cxx_std_11)
    

    cmake中的常用变量

    CMAKE_SOURCE_DIR

    表示:源码的根目录,也就是最top层 CMakeLists.txt文件存在的目录。

    CMAKE_BINARY_DIR

    表示:为编译的binary的根目录,也就是运行CMake时的目录,一般就是build目录。

    CMAKE_CURRENT_SOURCE_DIR

    表示:当前正在运行的CMakeLists.txt文件的目录

    CMAKE_CURRENT_BINARY_DIR

    表示:当前正处于的编译目录,例如如果正在运行src目录下的CMakeLists.txt, 该变量通常为build/src目录。

    CMAKE_CXX_FLAGS 和 CMAKE_C_FLAGS

    表示:当使用g++(或gcc)编译文件时,用于设置compiler flags, 也就是宏定义。

    CMAKE_CXX_STANDARD

    表示:该变量用于编译target时,使用的c++标准,支持98, 11, 14, 17, 20, 23. 该变量的作用原理是:用于初始化target的CXX_STANDARD属性。

    C++编译器相关的宏命令

    check_cxx_compiler_flag 命令

    该宏定义在CheckCXXCompilerFlag.cmake模块中, 可以打开该文件看它的实现的。 它的功能是用于检测c++编译器是否支持给定的编译选项,并把检测结果写的给定变量中。

    使用语法为:check_cxx_compiler_flag(<flag> <var>),

    • flag: 要检测的c++编译选项
    • var: 保存检测结果的cache 变量。

    使用举例

  • 相关阅读:
    Atitit.Java exe bat  作为windows系统服务程序运行
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结
  • 原文地址:https://www.cnblogs.com/yinheyi/p/14968494.html
Copyright © 2011-2022 走看看