ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

CMake 打包工具 cpack(1) 完全指南:命令选项、工作流程与源码级解析

CMake 打包工具 cpack(1) 完全指南:命令选项、工作流程与源码级解析 构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载导读cpack 是 CMake 自带的打包程序负责把已经构建好的项目产物生成多种格式的安装程序与源码包。本文基于 cpack(1) 手册 展开完整讲解 cpack 的每一条命令行选项-G、-C、-D、-P、-R、-B、preset 系列等结合仓库内 cpack 主程序源码 说明各选项在底层的真实处理逻辑并给出从include(CPack)到最终产出安装包的完整实战流程。读完本文你将掌握 cpack 的调用方式、配置文件的驱动机制、generator 的选取规则以及 package preset 的进阶用法。一、cpack 是什么CMake 的打包驱动器cpack 是 CMake 生态中的独立可执行程序用于生成二进制安装程序与源码包支持多种格式。其命令行概要Synopsis非常简单cpack [options]与cmake相比cpack 只负责打包这一件事它不负责编译只负责把已经安装到临时目录中的文件收集起来交给对应的打包后端处理。在 cpack 主程序源码 中程序自身的定位描述就是cpack - Packaging driver provided by CMake.从源码结构看cpack 的顶层逻辑可以概括为三步见 cpack.cxx解析命令行参数参数表定义在 cpack.cxx 的 arguments 数组读取并执行 CPack 配置文件默认是当前目录下的CPackConfig.cmake遍历CPACK_GENERATOR指定的 generator 列表逐个实例化生成器并调用DoPackage()产出包对应代码段。1.1 Generator打包格式的后端对于每一种安装包格式cpack 都有一个专门的后端称之为generator生成器。一个 generator 负责生成打包工具所需的输入文件并调用具体的打包工具如 NSIS、RPM、dpkg-deb 等完成封装。需要特别注意这里的package generator与 cmake 命令的makefile generator如 Unix Makefiles、Ninja完全是两回事不要混淆。前者决定产出什么格式的安装包后者决定用什么构建系统来编译。仓库中支持的全部 generator 清单见 cpack-generators(7) 手册包括归档类archive含 TGZ、ZIP 等变体Debian / RedHat 系列deb、rpm、freebsd、cygwinmacOSdmg、bundle、productbuild、packagemakerWindowsnsis、wix、innosetup、nuget移动端apkAndroid通用 AppImageappimage外部扩展点external详见 external generator 文档运行cpack --help会打印当前目标平台上可用的 generator 列表该列表在源码中由 makeGeneratorDocs 函数 从cmCPackGeneratorFactory动态收集生成。1.2 配置文件驱动机制cpack 由一份用 CMake 语言编写的配置文件驱动。默认情况下它读取当前工作目录下的CPackConfig.cmake也可以使用--config选项指定其他文件。在标准 CMake 工作流中只要项目的CMakeLists.txt中include(CPack)cmake 配置阶段就会自动生成CPackConfig.cmake与CPackSourceConfig.cmake两份文件见 CPack 模块文档文件实际写入位置在 CPack.cmake 源码末尾include(CPack)这两份文件分别用于CPackConfig.cmake驱动二进制安装包的生成CPackSourceConfig.cmake驱动源码包的生成配合cpack -G TGZ --config CPackSourceConfig.cmake使用。cpack 的配置读取逻辑在源码中有明确体现cpack.cxx 对应代码若未显式指定--config程序会把配置文件路径拼接为当前工作目录/CPackConfig.cmake如果该文件存在则通过ReadListFile执行若显式指定了路径但文件不存在则直接报错退出。1.3 关于配置文件中的必填项在执行DoPackage()之前cpack 会对配置做一系列完整性校验cpack.cxx 中的校验逻辑CPACK_PACKAGE_NAME必须已定义否则报CPack project name not specified版本信息必须齐全要么定义CPACK_PACKAGE_VERSION要么同时定义CPACK_PACKAGE_VERSION_MAJOR、CPACK_PACKAGE_VERSION_MINOR、CPACK_PACKAGE_VERSION_PATCH必须通过CPACK_INSTALL_CMAKE_PROJECTS、CPACK_INSTALL_COMMANDS、CPACK_INSTALL_SCRIPT或CPACK_INSTALLED_DIRECTORIES之一告诉 cpack 从哪里收集要打包的文件否则报Please specify build tree of the project...。若版本只给了 MAJOR/MINOR/PATCH 三段cpack 会在源码中自动拼接出CPACK_PACKAGE_VERSION见 cpack.cxx 的版本合成代码。二、选项总览与逐项详解cpack 的选项分为两类打包控制选项决定打包行为与帮助/版本选项用于查阅文档。下表先给出打包控制选项的完整清单选项作用对应 CMake 变量-G generators指定要使用的 generator 列表CPACK_GENERATOR-C configurations指定要打包的构建配置如 Debug/ReleaseCPACK_BUILD_CONFIG-D varvalue覆盖/定义任意 CPack 变量任意变量--config configFile指定配置文件—默认CPackConfig.cmake-V, --verbose详细输出—--debug调试输出面向 cpack 自身开发者—--trace/--trace-expand底层脚本跟踪模式—-P packageName覆盖包名CPACK_PACKAGE_NAME-R packageVersion覆盖版本号CPACK_PACKAGE_VERSION-B packageDirectory指定打包工作目录CPACK_PACKAGE_DIRECTORY--vendor vendorName覆盖厂商名CPACK_PACKAGE_VENDOR--preset preset使用 package preset—--presets-file file从指定文件读取 presets—--list-presets[defined]列出可用 package presets—该选项清单与 cpack 主程序源码中的 cmDocumentationOptions 数组 一一对应。下面逐项深入。2.1-G generators选择打包格式generators是一个分号分隔的 generator 名称列表。cpack 会按顺序遍历该列表根据CPackConfig.cmake中的配置为每个 generator 分别产出一个安装包。# 同时产出 TGZ 归档和 DEB 包 cpack -G TGZ;DEB如果命令行没有给出-G则回退使用CPackConfig.cmake中CPACK_GENERATOR变量指定的列表。从源码看命令行-G的值最终通过AddDefinition(CPACK_GENERATOR, ...)覆盖配置值cpack.cxx 对应代码。一个重要的执行细节源自 CPack 模块文档在CMakeLists.txt中CPACK_GENERATOR是一个列表但在CPACK_PROJECT_CONFIG_FILE中它被重置为当前正在打包的那一个 generator 名称的字符串。cpack 的迭代流程是执行CPackConfig.cmake读取-G或CPACK_GENERATOR得到 generator 列表对每个 generator将CPACK_GENERATOR重置为当前这一个的名称若配置了CPACK_PROJECT_CONFIG_FILE则按生成器逐次 include 它可用于编写仅针对某个 generator的特化逻辑调用该 generator 的DoPackage()产出包。# 单生成器用法示例只打一个 DEB cpack -G DEB2.2-C configurations指定要打包的构建配置configurations同样是分号分隔的列表例如Debug、Release。当项目使用多配置生成器multi-configuration generator如 Xcode 或 Visual Studio 系列时构建目录里会同时存在多个配置的输出。此时必须用-C告诉 cpack 把哪个配置的产物打进包里# Visual Studio 多配置构建后只打包 Release 产物 cpack -C Release # 同时打包 Debug 与 Release cpack -C Debug;Release注意-C只负责选取哪些配置的产物用户有责任确保这些配置在此之前已经构建完成手册原文明确提示The user is responsible for ensuring that the configuration(s) listed have already been built before invoking cpack。底层实现中该选项被写入CPACK_BUILD_CONFIG变量cpack.cxx 对应代码供配置文件与生成器读取。2.3-D varvalue直接定义 CPack 变量-D可以在命令行直接设置任意 CPack 变量且会覆盖配置文件中同名变量的值cpack -D CPACK_PACKAGE_CONTACTdevexample.com -G TGZ自 CMake 4.0 起还支持不带空格的单参数形式-Dvarvaluecpack -DCPACK_PACKAGE_CONTACTdevexample.com -G TGZ在源码中-D的解析逻辑非常直白cpack.cxx 的 -D 解析代码它会在参数中查找第一个把左侧作为键、右侧作为值存入definitions映射若找不到则直接报错提示必须以KEYVALUE形式书写。所有-D收集完毕后会在配置文件执行之后统一通过AddDefinition写回对应代码因此能覆盖配置文件中设定的同名变量。2.4--config configFile指定配置文件默认情况下 cpack 使用当前目录下的CPackConfig.cmake。当需要打源码包、或想复用另一套打包配置时可用--config显式指定# 使用 CMake 生成的源码包配置 cpack -G TGZ --config CPackSourceConfig.cmakeCPackSourceConfig.cmake正是由include(CPack)生成的第二份配置文件见 CPack 模块文档。2.5-V, --verbose详细输出开启详细输出便于展示打包工具如 NSIS、rpmbuild 等执行时的更多细节适合项目开发者排查打包问题cpack -V源码中-V与--verbose共用同一个回调效果是设置日志对象的 verbose 标志并打印Enable Verbosecpack.cxx 对应代码。cpack 的日志系统还定义了统一的前缀日志前缀设置CPack Error:、CPack Warning:、CPack:、CPack Verbose:方便在终端中快速定位不同级别的输出。2.6--debug调试模式--debug提供更底层的调试输出手册明确指出它主要面向 cpack 自身的开发者普通项目开发者一般用不到。其底层行为是打开日志对象的 debug 开关cpack.cxx 对应代码例如-D解析时会打印Set CPack variable: key to value这类调试信息cpack.cxx 的调试日志。2.7--trace/--trace-expand脚本跟踪这两个选项把 cpack 执行配置文件时底层运行的 CMake 脚本置于跟踪模式--trace普通跟踪--trace-expand展开式跟踪会同时打印变量展开后的结果对排查配置脚本中的变量求值问题非常有用。源码中二者都会调用state-SetTrace(true)后者额外设置SetTraceExpand(true)cpack.cxx 对应代码并且该状态会传递给实例化的 generatorcpack.cxx 中的传递逻辑。2.8-P packageName覆盖包名覆盖/定义CPACK_PACKAGE_NAME变量配置文件中对该变量的任何设置都会被忽略cpack -P myapp -G TGZ底层通过AddDefinition(CPACK_PACKAGE_NAME, ...)覆盖cpack.cxx 对应代码。2.9-R packageVersion覆盖版本号覆盖/定义CPACK_PACKAGE_VERSION。它会覆盖配置文件中的设置也会覆盖由CPACK_PACKAGE_VERSION_MAJOR/MINOR/PATCH自动拼接出的版本号cpack -R 1.2.3 -G TGZ底层同样以AddDefinition覆盖实现cpack.cxx 对应代码。2.10-B packageDirectory指定打包输出目录覆盖/定义CPACK_PACKAGE_DIRECTORY控制 cpack 进行打包工作的目录。最终安装包默认产出在该目录下同时 cpack 会在此目录内创建_CPack_Packages子目录作为打包过程的工作区cpack -B /tmp/pkgout -G TGZ # 产出/tmp/pkgout/myapp-1.2.3-Linux.tar.gz # 工作区/tmp/pkgout/_CPack_Packages/值得注意的优先级规则来自 CPack 模块文档 与 cpack.cxx 源码命令行-B优先级最高其次看配置文件中是否设置CPACK_PACKAGE_DIRECTORY源码会调用CollapseFullPath把它转为绝对路径两者都未设置时默认使用当前工作目录。2.11--vendor vendorName覆盖厂商名覆盖/定义CPACK_PACKAGE_VENDORcpack --vendor Example Corp -G TGZ底层通过AddDefinition(CPACK_PACKAGE_VENDOR, ...)实现cpack.cxx 对应代码。三、package preset用 JSON 声明打包参数从 CMake 3.23 引入packagePresets开始参见 cmake-presets(7) 手册中的版本记录cpack 也支持通过 preset 声明打包选项将配置、构建、测试、打包统一到一份 JSON 文件中。3.1--preset preset/--presetpreset按名称使用某个 package preset。项目二进制目录会从该 preset 的configurePreset键对应的 configure preset自动推断因此打包会在与配置/构建相同的binaryDir下执行cpack --preset package-release版本行为变更CMake 4.4如果同时指定了--presets-file则CMakePresets.json与CMakeUserPresets.json都不再要求必须存在否则它们必须存在于源码树顶层。旧版本中这是严格强制的要求。3.2--presets-file file/--presets-filefileCMake 4.4 新增从指定的文件读取 presets路径可以是绝对路径或相对于当前工作目录的路径。一旦指定--presets-fileCMakePresets.json与CMakeUserPresets.json中定义的 presets 将被忽略cpack --presets-file ./my-presets.json --preset release源码中该选项会把文件路径归一化后存入 preset 参数对象cpack.cxx 的 presetFileLambda随后预设读取逻辑cpack.cxx 的预设读取代码会根据该路径加载预设图。3.3--list-presets[defined]列出可用的 package presets不带参数列出当前可用的availablepackage presets带defined列出所有非隐藏的已定义 package presets包括当前不可用的预设及其不可用原因。# 列出可用预设 cpack --list-presets # 列出全部已定义预设含不可用者及原因 cpack --list-presetsdefined版本说明defined值支持为 CMake 4.5 新增CMake 4.4 起若指定了--presets-file则只列出该文件中的预设。源码中该选项由 presetsArgs.SetListPresets 处理非法值会提示 The only supported value is defined。3.4 package preset 的字段详解packagePresets数组中的每个元素是一个 JSON 对象核心字段如下完整定义见 packagePresets-properties.rst字段类型说明namestring必填机器可读名称用于cpack --preset name同一目录下不得与 CMakePresets.json/CMakeUserPresets.json 中其他 package preset 重名hiddenbool隐藏预设不能直接通过--preset使用且允许不指定合法的configurePreset通常作为被inherits引用的基类inheritsstring / string[]继承自其他预设除name、hidden、inherits、description、displayName外全部字段默认继承并可覆盖多个来源冲突时靠前的预设优先conditionobject条件表达式满足条件才可使用该预设vendormap厂商扩展信息CMake 只校验其是否为 map不解释内容displayName/descriptionstring人类可读名称与描述environmentmap设置环境变量支持宏展开$env{NAME}、$penv{NAME}等可相互引用但不能形成环configurePresetstring关联的 configure preset 名称二进制目录由它推断inheritConfigureEnvironmentbool默认 true为 true 时继承关联 configure preset 的环境变量generatorsstring[]cpack 要使用的 generator 列表等价于-Gconfigurationsstring[]要打包的构建配置列表等价于-Cvariablesmap传给 cpack 的变量等价于-D参数configFilestring使用的配置文件等价于--configoutputobject输出选项含outputName、packageDirectory等键packageNamestring包名注意因实现问题该字段目前不影响最终包文件名文档建议暂不使用packageVersionstring包版本同样因实现问题暂不影响最终包文件名文档建议暂不使用packageDirectorystring放置包文件的目录vendorNamestring厂商名称一个典型的CMakePresets.json示例{ version: 6, configurePresets: [ { name: dev, binaryDir: ${sourceDir}/build/dev, generator: Ninja } ], packagePresets: [ { name: package-deb, displayName: Build Debian package, configurePreset: dev, generators: [DEB], configurations: [Release], variables: { CPACK_PACKAGE_CONTACT: devexample.com } }, { name: package-tgz, inherits: package-deb, generators: [TGZ] } ] }对应命令cpack --preset package-deb cpack --preset package-tgz在源码层面preset 的处理流程cpack.cxx 的预设处理段依次完成读取预设文件 → 列出/解析目标预设 → 校验预设中的 generator 是否在当前平台可用 → 查找关联的 configure preset 并切换到其binaryDir→ 注入预设环境变量 → 把预设中的generators、configurations、variables、configFile、packageName、packageVersion、packageDirectory、vendorName等逐一合并到对应命令行参数命令行显式给出的参数优先预设只在不冲突时生效。四、帮助与版本选项cpack 沿用了 CMake 家族统一的文档查询体系这些选项定义在 OPTIONS_HELP.rst由 cpack(1) 手册通过 include 引入。4.1 版本信息cpack -version[json-v1] [file] cpack --version[json-v1] [file]打印程序名与版本横幅后退出。若指定json-v1则输出 JSON 格式的扩展版本信息包含 CMake 及其依赖组件的版本JSON 输出格式有机器可读的 schema 描述见 version-schema.json。可选参数file可将输出写入指定文件。4.2 帮助信息选项作用-h, -H, --help, -help, -usage, /?打印基本用法与选项说明后退出--help keyword [file]打印某个 CMake 关键字property、variable、command、policy、generator 或 module的手册条目CMake 3.28 起不再局限于命令名--help-full [file]打印全部帮助手册--help-manual man [file]打印指定手册如cpack --help-manual cpack-generators--help-manual-list [file]列出所有可查询的手册名称--help-command cmd [file]打印单个命令的帮助如cpack --help-command install--help-command-list/--help-commands列出命令 / 打印 cmake-commands 手册--help-module mod/--help-module-list/--help-modules模块级帮助--help-policy cmp/--help-policy-list/--help-policies策略级帮助--help-property prop/--help-property-list/--help-properties属性级帮助--help-variable var/--help-variable-list/--help-variables变量级帮助这些选项中的file均可选用于把输出重定向到文件。在源码中帮助模式通过doc.CheckOptions(argc, argv, -G)判定cpack.cxx 对应代码并且零参数直接运行与零参数打印帮助被刻意区分直接运行cpack不带任何参数会尝试读取当前目录的CPackConfig.cmake执行打包而不是打印帮助源码注释明确指出这一设计见 cpack.cxx 注释。五、标准打包工作流从 CMakeLists.txt 到安装包综合 CPack 模块文档 与 cpack(1) 手册一个完整的打包流程如下步骤 1在项目中启用 CPack# CMakeLists.txt项目根目录 cmake_minimum_required(VERSION 3.16) project(MyApp VERSION 1.2.3) # ... 定义目标、install() 规则 ... include(CPack)install()命令的DESTINATION必须是相对路径否则安装文件会被 CPack 忽略CPack 模块文档明确说明。步骤 2配置项目cmake -S . -B build配置结束后构建目录中会生成CPackConfig.cmake与CPackSourceConfig.cmake。步骤 3构建cmake --build build步骤 4打包# 方式一直接调用 cpack cpack --config build/CPackConfig.cmake # 方式二利用 include(CPack) 生成的 package 目标 cmake --build build --target package对于 Makefile / Ninja / Xcode 生成器include(CPack)会额外生成名为package的构建目标因此也可以直接make package或ninja packageVisual Studio 生成器则生成大写目标PACKAGECPack 模块文档。Makefile 与 Ninja 生成器还会生成package_source目标用于打源码包CPack 模块文档。步骤 5一次产出多种格式# 同时产出 TGZ 与 DEB在 Linux 上 cpack --config build/CPackConfig.cmake -G TGZ;DEB # 或通过 -D 覆盖配置 cpack -D CPACK_GENERATORTGZ;DEB --config build/CPackConfig.cmake源码包cpack -G TGZ --config build/CPackSourceConfig.cmake源码包会包含项目目录中的全部源文件除非通过CPACK_SOURCE_IGNORE_FILES排除CPack 模块文档。六、常见变量速查与 -D / -P / -R / -B 的对应关系命令行选项本质上都是对 CPack 变量的快捷覆盖CPack 模块文档的通用变量章节命令行选项对应变量默认值说明-PCPACK_PACKAGE_NAME未指定时取项目名--vendorCPACK_PACKAGE_VENDOR默认Humanity-BCPACK_PACKAGE_DIRECTORY默认当前工作目录-RCPACK_PACKAGE_VERSION可由 MAJOR/MINOR/PATCH 三段拼接—CPACK_PACKAGE_FILE_NAME默认${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}—CPACK_PACKAGE_DESCRIPTION_SUMMARY默认取CMAKE_PROJECT_DESCRIPTION—CPACK_PACKAGE_HOMEPAGE_URL默认取project()中的主页 URL—CPACK_PACKAGE_CHECKSUMCMake 3.7 起支持生成校验和文件4.2 起支持算法列表因此-D CPACK_PACKAGE_VENDORxxx与--vendor xxx在效果上是等价的-D是最通用的万能覆盖口。七、源码视角cpack 主程序是如何工作的cpack 的入口位于 Source/CPack/cpack.cxx 的main函数其关键链路可归纳为初始化处理命令行编码、初始化 libuv、定位 CMake 资源、创建日志对象并设置CPack Error:等输出前缀cpack.cxx 初始化段参数解析将所有命令行参数与预定义的arguments表逐一匹配未知的-开头参数会报Unknown argument:并给出最接近的候选建议Did you mean: ...?见 cpack.cxx 参数匹配逻辑preset 处理若出现--preset/--presets-file/--list-presets则读取、解析并合并预设cpack.cxx 预设处理段配置文件加载确定配置文件路径默认当前目录CPackConfig.cmake并执行之同时加载CMakeDetermineSystem.cmake等系统探测脚本使配置文件中可正常使用FIND_XXX()命令cpack.cxx 配置加载段变量覆盖依次把-G、-P、-R、--vendor、-B、-D收集到的值写回全局 Makefile 定义cpack.cxx 变量写入段迭代生成遍历 generator 列表逐一校验包名/版本/安装信息实例化生成器并调用DoPackage()任一环节失败即返回非零退出码cpack.cxx 生成段。仓库还提供了对应的回归测试例如 Tests/RunCMake/CPack/ 通过set(CPACK_GENERATOR ${GENERATOR_TYPE})驱动不同生成器类型的打包测试其中的PRE_POST_SCRIPTS测试pre.cmake、post.cmake验证了打包前后脚本在执行时能正确读取CPACK_GENERATOR上下文可作为研究 cpack 行为的参考起点。八、使用建议与注意事项多配置项目必须用-CXcode / Visual Studio 生成的构建目录含多个配置的产物缺了-C可能导致包内缺少可执行文件-D是万能覆盖任何 CPack 变量都可-D覆盖但注意-D的键值必须带否则报错优先用 preset 固化流程把 generator、配置、变量写进CMakePresets.json的packagePresets配合--preset一键打包可避免命令行越写越长-B与_CPack_Packages打包中间文件会留在-B指定的目录下CI 中注意清理或复用该工作区CPACK_PROJECT_CONFIG_FILE是按 generator 逐个 include 的若某个设置只想作用于 DEB 而不作用于 RPM应放在该文件中并判断CPACK_GENERATOR的当前值CPack 模块文档。参考资料cpack(1) 命令行手册本文的主体依据cpack-generators(7) 生成器手册全部生成器清单CPack 模块文档include(CPack)的用法、目标与通用变量cmake-presets(7) 手册 与 packagePresets 属性定义package preset 完整字段cpack 主程序源码命令行解析与打包主流程cpack 回归测试生成器级打包行为验证赞分享构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载相关推荐CMake打包工具CPack完全指南生成DEB/RPM/MSI安装包全流程CMake打包工具CPack完全指南生成DEB/RPM/MSI安装包全流程 你是否还在为跨平台软件打包而烦恼从Linux的DEB/RPM到Windows的M构建工具开发工具CLICMake CPack 生成器全景指南17 大打包后端选型、配置与源码剖析CMake CPack 生成器全景指南17 大打包后端选型、配置与源码剖析 CPack 是 CMake 的打包工具它把 install 命令收集到的安装产物构建工具开发工具CLICPack Archive 生成器完全指南用 CMake 打遍 7z/tar/zip 全格式安装包与源码包CPack Archive 生成器完全指南用 CMake 打遍 7z/tar/zip 全格式安装包与源码包 CPack 的 Archive 生成器Archi构建工具开发工具CLI上一篇gh_mirrors/gumr/gumroad性能监控NewRelic与APM工具应用下一篇NocoBase部署实战指南三套企业级安装方案详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表