cmake命令

21 阅读6分钟

cmake-commands(7) — CMake 4.2.1 Documentation

脚本命令

file
Reading
  file(READ <filename> <out-var> [...])
  file(STRINGS <filename> <out-var> [...])
  file(<HASH> <filename> <out-var>)
  file(TIMESTAMP <filename> <out-var> [...])

Writing
  file({WRITE | APPEND} <filename> <content>...)
  file({TOUCH | TOUCH_NOCREATE} <file>...)
  file(GENERATE OUTPUT <output-file> [...])
  file(CONFIGURE OUTPUT <output-file> CONTENT <content> [...])

Filesystem
  file({GLOB | GLOB_RECURSE} <out-var> [...] <globbing-expr>...)
  递归查找所有头文件,usage: file(GLOB_RECURSE HEADER_FILES ./*.h)
  file(MAKE_DIRECTORY <directories>... [...])
  file({REMOVE | REMOVE_RECURSE } <files>...)
  file(RENAME <oldname> <newname> [...])
  file(COPY_FILE <oldname> <newname> [...])
  file({COPY | INSTALL} <file>... DESTINATION <dir> [...])
  file(SIZE <filename> <out-var>)
  file(READ_SYMLINK <linkname> <out-var>)
  file(CREATE_LINK <original> <linkname> [...])
  file(CHMOD <files>... <directories>... PERMISSIONS <permissions>... [...])
  file(CHMOD_RECURSE <files>... <directories>... PERMISSIONS <permissions>... [...])

Path Conversion
  file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])
  file(RELATIVE_PATH <out-var> <directory> <file>)
  file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)

Transfer
  file(DOWNLOAD <url> [<file>] [...])
  file(UPLOAD <file> <url> [...])

Locking
  file(LOCK <path> [...])

Archiving
  file(ARCHIVE_CREATE OUTPUT <archive> PATHS <paths>... [...])
  file(ARCHIVE_EXTRACT INPUT <archive> [...])

Handling Runtime Binaries
  file(GET_RUNTIME_DEPENDENCIES [...])
find_package

用于查找外部依赖包

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS] [components...]
             [NO_POLICY_SCOPE])
  • <PackageName> : 要查找的包名称(不区分大小写,但建议保持与文件一致)
  • [version] : 可选,指定所需的最低版本,如 2.8.0
  • EXACT: 要求版本必须精确匹配
  • QUIET: 静默模式,不输出查找信息
  • REQUIRED: 必需包,找不到会报错终止配置
两种查找模式
模块模式(Module Mode)

查找名为 Find<PackageName>.cmake 的文件,这是 CMake 的传统方式。

find_package(PackageName MODULE)

搜索路径(按顺序):

  1. CMAKE_MODULE_PATH 变量指定的路径
  2. CMake 安装目录中的模块目录(如 /usr/share/cmake-3.x/Modules/
 配置模式(Config Mode)

查找名为 <PackageName>Config.cmake 或 <PackageName>-config.cmake 的文件,这是现代 CMake 推荐的方式。

find_package(PackageName CONFIG)

搜索路径(按顺序):

  1. <PackageName>_DIR CMake 变量
  2. <PackageName>_DIR 环境变量
  3. CMake 预定义的搜索路径
查找结果设置变量

成功找到包后,会设置以下变量:

  • <PackageName>_FOUND: 布尔值,表示是否找到包
  • <PackageName>_INCLUDE_DIRS 或 <PackageName>_INCLUDES: 头文件目录
  • <PackageName>_LIBRARIES 或 <PackageName>_LIBS: 库文件列表
  • <PackageName>_DEFINITIONS: 编译定义
  • <PackageName>_VERSION: 包版本
  • <PackageName>_MAJOR_VERSION<PackageName>_MINOR_VERSION<PackageName>_PATCH_VERSION: 版本号各部分

项目命令

add_compile_definitions

新增于版本 3.12。 在源文件编译过程中添加预处理器定义。

add_compile_definitions(<definition> ...)

向编译器命令行添加预处理器定义。

这些预处理器定义会被添加到当前CMakeLists文件的COMPILE_DEFINITIONS目录属性中,同时也会添加到当前CMakeLists文件中每个目标的COMPILE_DEFINITIONS目标属性中。

定义采用 VAR 或 VAR=value 语法指定。不支持函数式定义。CMake 将自动为原生构建系统正确转义值(注意:CMake 语言语法可能需要转义符来指定某些值)。

add_definitions 弃用

在源文件编译时添加 -D 定义标志。

add_definitions(-DFOO -DBAR ...)

为当前目录中的目标(无论是在调用此命令之前还是之后添加的)以及子目录中之后添加的目标,向编译器命令行添加定义。此命令可用于添加任何标志,但其主要目的是添加预处理器定义。 注意:此命令已被替代方案取代

  • 使用 add_compile_definitions() 添加预处理器定义。
  • 使用 include_directories() 添加包含目录。
  • 使用 add_compile_options() 添加其他选项。

以 -D 或 /D 开头且类似预处理器定义的标志,会自动添加到当前目录的 COMPILE_DEFINITIONS 目录属性中。出于向后兼容性考虑,具有非平凡值的定义可能保留在标志集中而非被转换。有关向特定作用域和配置添加预处理器定义的详细信息,请参阅目录、目标、源文件 COMPILE_DEFINITIONS 属性的文档。

add_executable

使用指定的源文件将可执行文件添加到项目中。

add_executable(<name> <options>... <sources>...)

添加一个名为<name>的可执行目标(target),该目标将从命令调用中列出的源文件进行构建。

aux_source_directory

查找目录中的所有源文件。

aux_source_directory(<dir> <variable>)  
include_directories 弃用
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
usage:
include_directories(${PROJECT_SOURCE_DIR}/src/)

将指定的目录添加到编译器用于搜索包含文件的路径中。相对路径将被解释为相对于当前源代码目录的路径。

包含目录会被添加到当前 CMakeLists 文件的 INCLUDE_DIRECTORIES 目录属性中。它们也会被添加到当前 CMakeLists 文件中每个目标的 INCLUDE_DIRECTORIES 目标属性中。目标属性值是生成器所使用的值。

默认情况下,指定的目录会被追加到当前目录列表中。通过将CMAKE_INCLUDE_DIRECTORIES_BEFORE设置为ON可更改此默认行为。通过显式使用AFTER或BEFORE,可选择追加或前置操作,不受默认行为限制。

若指定SYSTEM选项,编译器将在某些平台上将这些目录视为系统包含目录。此设置可能导致编译器忽略警告,或使这些固定安装的系统文件不参与依赖关系计算——详见编译器文档。

注意:

  1. include_directories 影响当前CMakeLists.txt及所有子目录中的所有目标(target)。
  2. 建议使用 target_include_directories() 命令为单个目标添加包含目录,并可选地将其传播/导出至依赖项。
target_include_directories
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  

指定编译特定目标时使用的包含目录。所指的<target>必须通过add_executable()或add_library()等命令(之后调用)创建,且不能是ALIAS类型的目标。
通过显式使用AFTER或BEFORE,可选择在末尾追加或在开头添加,不受默认行为限制。

必须使用INTERFACE、PUBLIC和PRIVATE关键字来指定后续参数的作用域。PRIVATE和PUBLIC项将填充<target>的INCLUDE_DIRECTORIES属性。PUBLIC和INTERFACE项将填充<target>的INTERFACE_INCLUDE_DIRECTORIES属性。

  • PRIVATE(私有):头文件路径仅用于当前目标自身的编译。例如,一个库(mylib)的内部实现细节头文件应该使用 PRIVATE。依赖 mylib的其他目标(如一个可执行文件)在链接时不会“看到”这些路径
  • PUBLIC(公有):头文件路径既用于当前目标编译,也传递给任何链接此目标的其他目标。这通常用于库的API头文件(即提供给用户使用的头文件)
  • INTERFACE(接口):头文件路径不用于当前目标自身的编译,但会传递给任何链接此目标的其他目标。这适用于“头文件仅”的库(Header-only Library),即库本身没有编译单元,只有头文件

target_link_libraries

为指定目标(可执行文件或库)添加链接依赖

target_link_libraries(<target>
                      <PRIVATE|PUBLIC|INTERFACE> <item>...
                     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
  • <target> :由 add_executable() 或 add_library() 命令创建的目标名称。
  • <item> :要链接的库,可以是:
    • 由本项目 add_library() 创建的库目标名(如 MathFunctions)。
    • 由 find_package() 找到的导入目标名(如 Threads::ThreadsBoost::system)。
    • 系统或第三方库的完整库文件路径
    • 链接器可以识别的库名称(如 pthreadm 代表数学库)。此时,CMake 会尝试在系统路径中查找它。
  • PUBLIC: 库自身需要使用,并且任何链接该库的其他目标也需要,库的头文件中包含了所依赖库的类型或函数
  • PRIVATE: 库自身在源文件(.cpp)内部使用,但其头文件并未暴露该依赖。链接此库的其他目标无需知晓或链接此依赖
  • INTERFACE: 库自身不使用,但任何链接此库的目标都需要。常用于头文件库或为下游目标提供统一的依赖要求。