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.0EXACT: 要求版本必须精确匹配QUIET: 静默模式,不输出查找信息REQUIRED: 必需包,找不到会报错终止配置
两种查找模式
模块模式(Module Mode)
查找名为 Find<PackageName>.cmake 的文件,这是 CMake 的传统方式。
find_package(PackageName MODULE)
搜索路径(按顺序):
CMAKE_MODULE_PATH变量指定的路径- CMake 安装目录中的模块目录(如
/usr/share/cmake-3.x/Modules/)
配置模式(Config Mode)
查找名为 <PackageName>Config.cmake 或 <PackageName>-config.cmake 的文件,这是现代 CMake 推荐的方式。
find_package(PackageName CONFIG)
搜索路径(按顺序):
<PackageName>_DIRCMake 变量<PackageName>_DIR环境变量- 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选项,编译器将在某些平台上将这些目录视为系统包含目录。此设置可能导致编译器忽略警告,或使这些固定安装的系统文件不参与依赖关系计算——详见编译器文档。
注意:
- include_directories 影响当前CMakeLists.txt及所有子目录中的所有目标(target)。
- 建议使用 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::Threads,Boost::system)。 - 系统或第三方库的完整库文件路径。
- 链接器可以识别的库名称(如
pthread,m代表数学库)。此时,CMake 会尝试在系统路径中查找它。
- 由本项目
- PUBLIC: 库自身需要使用,并且任何链接该库的其他目标也需要,库的头文件中包含了所依赖库的类型或函数
- PRIVATE: 库自身在源文件(.cpp)内部使用,但其头文件并未暴露该依赖。链接此库的其他目标无需知晓或链接此依赖。
- INTERFACE: 库自身不使用,但任何链接此库的目标都需要。常用于头文件库或为下游目标提供统一的依赖要求。