文章目录
一、前言二、CMake 基础命令三、目标管理命令四、文件与目录操作命令4.1、include_directories4.2、aux_source_directory4.3、file4.4、find_package
五、条件与循环控制命令六、构建选项与配置命令6.1、option6.2、add_definitions6.3、*_property系列6.4、configure_file
七、自定义命令与目标7.1、add_custom_command7.2、add_custom_target
八、安装与打包命令8.1、install8.2、cpack
九、总结
一、前言
CMake 是一个跨平台的开源构建系统生成器。它本身并不直接构建软件,而是根据 CMakeLists.txt 文件中的描述,生成特定平台的构建系统。
CMake 的作用是将构建过程与编译器、操作系统和 IDE 解耦,从而实现“一次编写,到处构建”的目标。
学习 CMake 命令的优势在于:
CMake 能够生成适用于各种平台的构建系统,使项目能够轻松地在不同操作系统上编译和运行。CMake 可以自动化构建过程,简化编译、链接、安装等步骤。CMake 提供了丰富的配置选项,允许根据需要自定义构建过程。CMake 对现代 C++ 标准提供了良好的支持,可以轻松地使用最新的语言特性。CMake 可以自定义命令和目标,以满足特定的构建需求。
传统构建方式依赖于 Makefile 等特定于平台的构建脚本。CMake 则使用一个平台无关的 CMakeLists.txt 作为输入,由 CMake 生成特定平台的构建脚本,从而解耦了构建过程。比如,同样的项目,使用 CMake 可以方便地生成在 Windows 上使用的 Visual Studio 工程,以及在 Linux 上使用的 Makefile,而无需手动维护两套不同的构建脚本。
CMake 的工作流程分为以下几个步骤:
使用 CMake 命令编写 CMakeLists.txt 文件,描述项目的源文件、依赖项、构建选项等信息。这个文件相当于项目的“构建蓝图”。
在命令行中运行 cmake <源目录>,其中 <源目录> 是包含 CMakeLists.txt 文件的目录。
CMake 根据 CMakeLists.txt 的内容和用户指定的生成器 (generator),生成特定平台的构建系统。 常用的生成器包括:Unix Makefiles、Ninja、Visual Studio、Xcode。
使用生成的构建系统构建项目。
(可选)根据 CMakeLists.txt 中定义的安装规则,将构建好的程序、库、头文件等安装到指定目录。
再次强调 CMake 只是生成构建系统,真正的编译工作是由构建系统(例如 make, ninja, Visual Studio)来完成的。
本文旨在为 C/C++ 开发者提供一个常用 CMake 命令的快速参考和实用示例。专注于 CMake 在实际项目构建中常用的功能和命令,并通过清晰的示例代码展示其用法。本文【CMake轻松学】系列的一部分,并非 CMake 的完整教程,而是帮助快速上手,解决常见构建问题,并为更深入的学习打下基础。
目标读者:
CMake 初学者,具有一定 C/C++ 基础。需要快速查找和使用 CMake 命令的开发者。
二、CMake 基础命令
本章节介绍 CMake 中最基础的命令:cmake_minimum_required, project, set, 和 message。它们是构建 CMakeLists.txt 文件的基石。理解这些命令的作用和用法,能够更好地掌握 CMake 的基本原理。
(1)cmake_minimum_required: 指定 CMake 的最低版本要求。确保使用的 CMake 版本满足项目需求。必须放在 CMakeLists.txt 的最开头;如果 CMake 版本低于指定的版本,会报错并停止构建。
语法:
cmake_minimum_required(VERSION <版本号>)
为什么需要指定最低版本?
CMake 在不断更新和改进,新的版本会引入新的特性、命令和语法。 为了确保项目能够使用特定的 CMake 功能,需要在 cmake_minimum_required 中指定一个满足这些要求的最低版本。 这样可以防止低版本的 CMake 解释 CMakeLists.txt 时发生错误,从而保证构建过程的顺利进行。
(2)project: 声明项目名称和支持的语言。
语法:
project(<项目名称> [LANGUAGES <语言列表>] [VERSION <版本号>] [DESCRIPTION <描述>])
示例:
project(MyProject LANGUAGES CXX VERSION 1.0 DESCRIPTION "My awesome project")
推荐指定项目语言,常用的语言包括 C, CXX, Fortran, ASM 等。 如果项目主要使用 C++,则指定 CXX。
VERSION 和 DESCRIPTION 是可选的,但添加它们可以更好地描述项目。
补充:项目名称会影响一些 CMake 变量的命名。CMake 会根据你指定的项目名称创建一些预定义的变量,这些变量在构建过程中非常有用。
(3)set: 设置变量。CMake 使用变量来存储各种信息,例如源文件列表、编译选项等。
语法:
set(<变量名> <值> [CACHE <类型> <描述> [FORCE]])`
CACHE 选项:缓存变量在配置构建系统后仍然存在,可以被用户修改。常见的类型包括 STRING, PATH, FILEPATH, BOOL, INT, FLOAT 等。
FORCE:如果变量已经存在,使用 FORCE 可以强制覆盖它的值。
说明:CMake 变量可以使用 ${变量名} 的方式引用。set 命令也可以用来设置环境变量: set(ENV{PATH} "$ENV{PATH}:/new/path")
(4)message: 显示消息,用于调试和显示构建信息。
语法:
message([STATUS|WARNING|AUTHOR_WARNING|ERROR|FATAL_ERROR] <消息内容>)
示例:
message(STATUS "Building project...")
用途:
STATUS:显示普通信息。WARNING:显示警告信息,构建过程会继续。AUTHOR_WARNING:显示作者警告信息,通常用于提示库的使用者。ERROR:显示错误信息,但构建过程会继续,但通常会导致后续构建失败。FATAL_ERROR:显示致命错误信息,并立即停止构建过程。
可以使用 ${变量名} 在消息中显示变量的值。例如: message(STATUS "Source files: ${SOURCE_FILES}")
这些命令是编写 CMakeLists.txt 文件的基础。
三、目标管理命令
(1)add_executable: 创建可执行文件目标。
语法:
add_executable(<目标名称> <源文件列表>)
示例:
add_executable(my_app main.cpp helper.cpp)
(2)add_library: 创建库目标 (静态库、动态库、模块库)。
语法:
add_library(<目标名称> [STATIC|SHARED|MODULE] <源文件列表>)
示例:
add_library(my_static_lib STATIC helper.cpp)
add_library(my_shared_lib SHARED helper.cpp)
STATIC、SHARED、MODULE 的区别:
STATIC: 创建一个静态库(.a 或 .lib)。 静态库在链接时会被完整地复制到可执行文件中。 优点是运行时不需要依赖库文件,缺点是可执行文件体积较大。SHARED: 创建一个动态库(.so 或 .dll)。 动态库在运行时才会被加载到内存中。 优点是可执行文件体积较小,并且多个程序可以共享同一个动态库,缺点是运行时需要依赖库文件。MODULE: 创建一个模块库(.so 或 .dll),通常用于插件系统。 模块库在运行时动态加载和卸载。 它们不直接被链接到主程序,而是通过特定的接口进行交互。
(3)target_link_libraries: 链接库到目标。语法:
target_link_libraries(<目标名称> <库列表>)
公有、私有、接口链接的概念 (PUBLIC, PRIVATE, INTERFACE):
PUBLIC: 库及其链接信息(例如头文件路径、依赖库)会传递给链接当前目标 以及 链接到当前目标的 其他目标。 适用于库是公共接口的一部分,其他目标需要使用其头文件和依赖库的情况。PRIVATE: 库只会被链接到当前目标。 库的链接信息不会传递给链接到当前目标的 其他目标。 适用于库的实现细节不需要暴露给其他目标的情况。INTERFACE: 当前目标不会直接链接到这个库,但是会将链接信息(例如头文件路径、依赖库)传递给链接到当前目标的 其他目标。 通常用于头文件库,或者那些只提供接口的库,本身不包含代码。
(4)target_include_directories: 添加头文件搜索路径。语法:
target_include_directories(<目标名称> [SYSTEM] [BEFORE] <目录列表> [PUBLIC|PRIVATE|INTERFACE])
SYSTEM: 表示指定的目录是系统目录,编译器在搜索用户目录之前搜索系统目录。这通常用于标准库的头文件。BEFORE: 将指定的目录添加到搜索路径的前面。 默认情况下,include 目录会被添加到搜索路径的末尾
PUBLIC、PRIVATE、INTERFACE 的区别:与 target_link_libraries 类似。
(5)target_compile_definitions: 向目标添加编译定义 (例如 #define 宏)。语法:
target_compile_definitions(<目标名称> [PUBLIC|PRIVATE|INTERFACE]
示例:target_compile_definitions(my_app PUBLIC -DDEBUG)。定义一个名为 DEBUG 的宏,并将其添加到 my_app 目标的编译选项中。 等价于在代码中使用 #define DEBUG。 -D 是 GCC/Clang 中定义宏的选项。
PUBLIC、PRIVATE、INTERFACE 的区别:与 target_link_libraries 和 target_include_directories。
四、文件与目录操作命令
4.1、include_directories
include_directories:全局添加头文件搜索路径(不推荐,建议使用 target_include_directories)。
语法
include_directories([SYSTEM] [BEFORE] <目录1> [<目录2> ...])
SYSTEM:将目录当作系统路径,抑制该目录下头文件的警告。BEFORE:将目录插入到搜索列表前端,优先级更高。
示例:
include_directories(include)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/foo/include)
缺点: 全局生效,容易造成命名冲突。
推荐改用:
target_include_directories(my_target
PUBLIC ${CMAKE_SOURCE_DIR}/include
SYSTEM ${CMAKE_SOURCE_DIR}/third_party/foo/include
)
4.2、aux_source_directory
查找指定目录下的所有源文件,并将结果存入变量。
语法:
aux_source_directory(<目录> <变量名>)
示例:
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC_FILES)
add_executable(my_app ${SRC_FILES})
缺点 :变动源文件后,CMake 不会自动重新扫描,需要手动 cmake .
替代方案:
file(GLOB SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
4.3、file
提供对文件、目录的多种操作:查找、创建、读写、复制、重命名、删除等。
语法
file(
常用操作:
操作说明示例GLOB查找符合模式的文件file(GLOB SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")GLOB_RECURSE递归查找文件file(GLOB_RECURSE ALL_HEADERS "${CMAKE_SOURCE_DIR}/include/*.h")MAKE_DIRECTORY创建目录file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/output)WRITE / APPEND写入或追加文件file(WRITE ${CMAKE_BINARY_DIR}/version.txt "v1.2.3")file(APPEND ${CMAKE_BINARY_DIR}/version.txt "\nBuilt on ${CMAKE_SYSTEM_NAME}")COPY复制文件file(COPY data/config.json DESTINATION ${CMAKE_BINARY_DIR}/config)RENAME重命名文件/目录file(RENAME old_name.txt new_name.txt)REMOVE删除文件/目录file(REMOVE ${CMAKE_BINARY_DIR}/temp.txt)
4.4、find_package
查找并加载外部库或 CMake 模块,设置相关变量以供后续使用。 语法:
find_package(<包名> [版本号] [REQUIRED] [COMPONENTS <组件1> <组件2> ...])
工作原理:
在 CMAKE_MODULE_PATH 中查找 Find<包名>.cmake。若找到,执行该脚本:搜索库文件、头文件等,并设置一系列 <包名>_XXX 变量。若未找到模块文件,CMake 可尝试通过 pkg-config 或 <包名>Config.cmake(现代方式)来定位。若使用 REQUIRED 且未找到,CMake 配置阶段会报错并终止。
常见输出变量(以 OpenCV 为例):
OpenCV_FOUND:是否找到OpenCV_VERSION:版本号OpenCV_INCLUDE_DIRS:头文件路径列表OpenCV_LIBRARIES:库文件列表OpenCV_COMPONENTS:实际加载的组件列表
提示:
可通过 -DCMAKE_PREFIX_PATH=/path/to/opencv 指定 OpenCV 安装前缀。阅读 Find<包名>.cmake 脚本或 <包名>Config.cmake 文件,了解更多可用变量和选项。
五、条件与循环控制命令
if / elseif / else / endif:条件判断。
语法:
if(<条件>)
# ...
elseif(<条件>)
# ...
else()
# ...
endif()
常用条件表达式:字符串比较、数字比较、变量存在性判断等。
foreach / endforeach:循环迭代。
语法:
foreach(<变量名> IN LISTS <列表>)
# ...
endforeach()
六、构建选项与配置命令
在 CMake 构建过程中配置各种选项,并影响最终生成的可执行文件或库的行为。
6.1、option
定义构建选项,允许用户在构建时自定义配置。 这些选项会显示在 CMake GUI (cmake-gui) 或 cmake 工具中,或者可以通过命令行参数 -D
语法:
option(<选项名称> "<描述>" <默认值>)
使用 if(ENABLE_DEBUG) 来控制构建行为:
if(ENABLE_DEBUG)
message(STATUS "Debug mode is enabled.") # 在构建时显示信息
add_definitions(-DDEBUG) # 不推荐,建议用target_compile_definitions
# 或者更好地使用 target_compile_definitions:
target_compile_definitions(my_target PUBLIC -DDEBUG)
endif()
if(BUILD_SHARED_LIBS)
message(STATUS "Building shared libraries.")
set(CMAKE_BUILD_TYPE "Release") # 确保Release模式,如果不想被Debug选项影响,应强制覆盖
set(BUILD_SHARED_LIBS ON)
else()
message(STATUS "Building static libraries.")
set(BUILD_SHARED_LIBS OFF)
endif()
6.2、add_definitions
全局添加编译定义(不推荐,建议使用 target_compile_definitions)。 此命令会将编译定义添加到所有目标的编译命令行中,影响范围过大。
语法:
add_definitions(<定义列表>)
<定义列表>: 一个或多个编译定义的列表,以空格分隔。 每个定义通常以 -D 开头。
add_definitions 的一个主要缺点是它会影响 所有 目标。 更推荐使用 target_compile_definitions 来精确控制哪些目标会受到影响。 例如:
target_compile_definitions(my_target PUBLIC -DDEBUG) # 所有链接到 my_target 的目标都会继承 DEBUG 定义
target_compile_definitions(my_target PRIVATE -D_CRT_SECURE_NO_WARNINGS) # 只有 my_target 本身会受到影响
PUBLIC表示接口属性,会传递给依赖当前库或者可执行文件的其他target。PRIVATE表示私有属性,只用于当前target。INTERFACE表示接口属性,只用于传递给依赖当前库或者可执行文件的其他target,当前target不使用。
6.3、*_property系列
设置和获取目标、源文件、目录等的属性。 可以用来配置编译选项、链接选项、源文件特性等。
语法:
set_property(<范围> <名称> PROPERTY <属性名称> <属性值>...)
get_property(<变量名> <范围> <名称> PROPERTY <属性名称>)
<范围>: TARGET、SOURCE、DIRECTORY、GLOBAL 等。<名称>: 范围内的对象的名称,例如目标名称、源文件名。<属性名称>: 要设置或获取的属性的名称,例如 CXX_STANDARD、COMPILE_FLAGS、INCLUDE_DIRECTORIES。<属性值>: 要设置的属性的值。<变量名>: 用于存储获取到的属性值的变量名。
示例:
# 设置目标的 C++ 标准
set_property(TARGET my_target PROPERTY CXX_STANDARD 17)
set_property(TARGET my_target PROPERTY CXX_STANDARD_REQUIRED ON) # 强制要求编译器支持 C++17
# 添加编译标志
set_property(TARGET my_target APPEND_STRING PROPERTY COMPILE_FLAGS " -Wall -Wextra") # 添加编译器警告
# 设置源文件属性(例如,将其标记为头文件)
set_property(SOURCE my_source.cpp PROPERTY HEADER_FILE_ONLY TRUE)
# 获取目标的 CXX_STANDARD 属性
get_property(cpp_standard TARGET my_target PROPERTY CXX_STANDARD)
message(STATUS "C++ Standard: ${cpp_standard}")
6.4、configure_file
将输入文件复制到另一个位置并替换变量值。 常用于生成配置文件(例如,config.h)或其他需要根据构建环境进行定制的文件。
语法:
configure_file(
: 输入文件的路径。 通常是一个模板文件,包含需要替换的变量。
七、自定义命令与目标
在 CMake 构建过程中执行自定义脚本或操作,扩展构建系统的功能。
7.1、add_custom_command
添加自定义构建命令。 这个命令允许在构建过程中执行任意命令,例如代码生成、数据转换、文件处理等。 它可以与特定的构建目标关联,也可以独立执行。
语法:
add_custom_command(
OUTPUT <输出文件1> [<输出文件2> ...]
COMMAND <命令1> [<参数1> ...]
[COMMAND <命令2> [<参数2> ...]]
[DEPENDS <依赖文件1> [<依赖文件2> ...]]
[WORKING_DIRECTORY <工作目录>]
[COMMENT "<描述>"]
[VERBATIM]
[BYPRODUCTS <生成物1> [<生成物2> ...]]
[IMPLICIT_DEPENDS <语言> <依赖文件1> [<依赖文件2> ...]]
[MAIN_DEPENDENCY <主要依赖文件>]
[DEPFILE <依赖关系文件>]
[COMMAND_EXPAND_LISTS]
[JOB_POOL <池名称>]
[SOURCES <源文件1> [<源文件2> ...]]
[SYMBOLIC]
[APPEND]
[STARTING_OUTPUT_SCRIPT <脚本文件>]
)
常用参数:
参数名称描述OUTPUT指定命令生成的输出文件。如果没有输出文件,可以忽略,但建议至少有一个输出来触发执行。COMMAND指定要执行的命令。可以指定多个 COMMAND,它们会按顺序执行。DEPENDS指定命令所依赖的文件。如果任何依赖文件发生更改,该命令将重新执行。WORKING_DIRECTORY指定命令的工作目录。如果未指定,则使用当前源目录。COMMENT在构建过程中显示的描述信息。VERBATIM防止 CMake 对命令参数进行转义。在传递包含特殊字符的参数时很有用。BYPRODUCTS指定命令生成的其他非输出文件,例如临时文件。
示例:
# 1. 运行代码格式化工具 (clang-format)
find_program(CLANG_FORMAT clang-format)
if(CLANG_FORMAT)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/formatted_file.cpp" # 输出的文件名
COMMAND ${CLANG_FORMAT} -i "${CMAKE_CURRENT_SOURCE_DIR}/my_file.cpp" # -i 表示原地修改
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/my_file.cpp"
COMMENT "Formatting my_file.cpp with clang-format"
VERBATIM #如果clang-format命令比较复杂,需要VERBATIM
)
else()
message(WARNING "clang-format not found. Code formatting will be skipped.")
endif()
# 2. 代码生成:使用自定义脚本生成源文件
add_custom_command(
OUTPUT generated_source.cpp
COMMAND ${CMAKE_COMMAND} -E echo "int main() { return 0; }" > generated_source.cpp
COMMENT "Generating source file"
)
#3. 将自定义命令的输出与目标文件进行关联
add_executable(MyApp main.cpp generated_source.cpp)
add_dependencies(MyApp generated_source.cpp) # 确保在编译 MyApp 之前先生成 generated_source.cpp
# 4. 数据转换: 将数据文件转换为另一种格式
add_custom_command(
OUTPUT data.bin
COMMAND ${CMAKE_COMMAND} -E copy_if_different data.txt data.bin #简单复制,实际可能更复杂
DEPENDS data.txt
COMMENT "Converting data file to binary format"
)
重点:
add_custom_command 定义了一个 命令,它不会自动执行。 需要将其与一个目标关联(例如,使用 add_dependencies)或使其成为另一个自定义命令的依赖项,才能触发它的执行。指定 DEPENDS 可以确保只有在依赖文件发生更改时才重新运行命令,避免不必要的构建。
7.2、add_custom_target
添加自定义构建目标。 与 add_custom_command 不同,add_custom_target 创建一个可以被显式构建的目标。 这个目标可以执行一系列命令,并且可以有依赖项。 用户可以使用 make <目标名称> 或在 IDE 中选择构建该目标来触发其执行。
语法:
add_custom_target(
<目标名称>
[ALL]
[COMMAND <命令1> [<参数1> ...]]
[COMMAND <命令2> [<参数2> ...]]
[DEPENDS <依赖文件1> [<依赖文件2> ...]]
[WORKING_DIRECTORY <工作目录>]
[COMMENT "<描述>"]
[VERBATIM]
[BYPRODUCTS <生成物1> [<生成物2> ...]]
[IMPLICIT_DEPENDS <语言> <依赖文件1> [<依赖文件2> ...]]
[JOB_POOL <池名称>]
[SOURCES <源文件1> [<源文件2> ...]]
)
常用参数:
参数名称描述<目标名称>自定义目标的名称。ALL如果指定此选项,则该目标将成为 all 目标的依赖项,这意味着每次构建项目时都会执行该目标。(不常用,通常只在确实需要每次构建都执行的场景下使用)COMMAND指定要执行的命令。可以指定多个 COMMAND,它们会按顺序执行。DEPENDS指定目标所依赖的文件或其他目标。如果任何依赖项发生更改,该目标将重新构建。WORKING_DIRECTORY指定命令的工作目录。如果未指定,则使用当前源目录。COMMENT在构建过程中显示的描述信息。VERBATIM防止 CMake 对命令参数进行转义。在传递包含特殊字符的参数时很有用。
区别于 add_custom_command:
add_custom_target 定义一个可以被 显式 构建的目标。 用户可以选择构建该目标,从而触发其执行。add_custom_command 定义一个 命令,它需要通过其他方式触发,例如作为另一个目标的依赖项。
八、安装与打包命令
8.1、install
指定安装规则,将文件、目录、目标安装到指定位置。 install 命令定义了在执行安装步骤时应该如何处理文件、目录和目标。
语法:
install(<类型> DESTINATION <目录> <参数...>)
常用参数:
参数名称描述DESTINATION <目录>指定安装目标位置。这通常是一个相对于安装前缀(CMAKE_INSTALL_PREFIX 变量)的路径。CONFIGURATIONS <配置类型...>指定仅在特定构建配置(例如 Debug、Release)下才安装。COMPONENT <组件名称>将安装项分配给一个组件。用户可以选择只安装特定的组件。RENAME <新名称>在安装时重命名文件或目标。PERMISSIONS <权限...>设置安装文件的权限(例如 OWNER_READ, OWNER_WRITE, GROUP_READ, WORLD_READ, EXECUTE)。USE_SOURCE_PERMISSIONS使用源文件的权限。FILE_PERMISSIONS <权限...>设置文件的权限,覆盖默认权限。DIRECTORY_PERMISSIONS <权限...>设置目录的权限,覆盖默认权限。PATTERN <模式> EXCLUDE在目录安装中,排除与指定模式匹配的文件或目录。OPTIONAL如果文件或目标不存在,则忽略安装错误。EXCLUDE_FROM_ALL从 all 目标中排除此安装规则。
CMAKE_INSTALL_PREFIX 变量:
这是一个 CMake 变量,用于指定安装前缀。 默认情况下,通常是 /usr/local(在 Linux/macOS 上)或 C:/Program Files(在 Windows 上)。可以使用 -DCMAKE_INSTALL_PREFIX=<路径> 选项在配置时更改它。DESTINATION 中的路径是相对于 CMAKE_INSTALL_PREFIX 的。 因此,DESTINATION bin 实际上会将文件安装到 ${CMAKE_INSTALL_PREFIX}/bin。
8.2、cpack
打包项目,生成安装包。 cpack 是 CMake 提供的一个工具,用于创建各种格式的安装包,例如:
ZIPTGZ (gzip 压缩的 tar 文件)TBZ2 (bzip2 压缩的 tar 文件)DEB (Debian 包)RPM (Red Hat 包)NSIS (Windows 安装程序)DMG (macOS 磁盘镜像)
需要单独配置 CPackConfig.cmake 文件。 CPackConfig.cmake 文件定义了打包过程的各种选项,例如:
安装包名称版本号作者描述许可证依赖关系包含的文件安装程序选项
**配置 CPackConfig.cmake:**创建一个名为 CPackConfig.cmake 的文件,并将其放在项目的根目录下。
常见的 CPack 变量:
变量名称描述CPACK_GENERATOR指定打包格式 (例如 “TGZ”, “ZIP”, “DEB”, “RPM”, “NSIS”, “DMG”)CPACK_PACKAGE_NAME安装包的名称CPACK_PACKAGE_VERSION安装包的版本号CPACK_PACKAGE_DESCRIPTION安装包的描述CPACK_PACKAGE_VENDOR安装包的作者或供应商CPACK_PACKAGE_INSTALL_DIRECTORY安装目录 (相对于安装前缀)CPACK_DEBIAN_PACKAGE_DEPENDS(DEB 包) 依赖的其他软件包CPACK_NSIS_PACKAGE_NAME(NSIS 包) 安装程序的名称CPACK_RESOURCE_FILES_LICENSE许可证文件CPACK_COMPONENTS_ALL包含所有组件CPACK_COMPONENTS_GROUPING是否分组组件。用于创建组件列表CPACK_PACKAGE_FILE_NAME输出的包的文件名,包含版本等信息。如果未指定,CPack 会自动生成文件名。
九、总结
CMake 是一个跨平台构建系统生成器,通过 CMakeLists.txt 文件描述项目构建过程,实现“一次编写,到处构建”。本文精炼了 C/C++ 开发者常用的 CMake 命令,涵盖基础命令、目标管理、文件操作、条件控制、构建选项、自定义命令、安装打包等方面,为更深入学习打下基础。