尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

CMake install(DIRECTORY) 命令详解:从基础到精通,实现项目结构化部署

CMake install(DIRECTORY) 命令详解:从基础到精通,实现项目结构化部署 如果你在 CMake 项目中只是简单地使用install(TARGETS ...)来安装可执行文件或库那么你的项目部署很可能还停留在“能用”的阶段距离“好用”和“专业”还差关键一步。一个典型的场景是你的项目除了二进制文件还有配置文件、资源文件、文档、头文件等它们需要被安装到系统不同的标准目录下如/usr/bin、/usr/lib、/etc、/usr/share/doc。手动复制那不仅繁琐更破坏了 CMake 跨平台和自动化部署的核心价值。网络上充斥着大量关于cmake install基础用法的教程但当你搜索“如何安装整个目录”、“配置文件放哪里”时得到的往往是零散的代码片段或者直接指向install(DIRECTORY ...)命令却很少解释其背后的设计哲学、权限问题、以及如何与CPack打包工具无缝衔接。这正是许多开发者从 CMake 入门到进阶的卡点知道单个文件的安装却不知道如何优雅、规范地部署一个完整的软件包。本文将深入 CMake 的install命令特别是其DIRECTORY模式解决的就是这个“最后一公里”的问题。我们将不只告诉你命令怎么写更要厘清为什么install(DIRECTORY)比循环调用install(FILES)更优如何精准控制安装目录的结构、文件权限和过滤条件怎样避免常见的“文件已存在”、“权限不足”、“目录创建失败”等陷阱如何将目录安装与生成分发包如 DEB、RPM的流程统一起来通过本文你将掌握构建真正可交付、符合 Linux FHS 标准或 Windows 程序惯例的 CMake 项目的关键技能。文章包含从核心概念、详细语法到完整项目示例、常见问题排查的全套内容建议收藏备用。1. 这篇文章真正要解决的问题在软件开发中“构建”和“安装”是两个截然不同的阶段。构建Build是在开发环境中生成二进制制品如.exe,.so,.a文件而安装Install则是将这些制品及其相关资源部署到目标系统可以是本地开发机、测试服务器或用户环境的预定位置使其能够被系统发现和运行。许多 CMake 初学者止步于install(TARGETS myapp)这只能解决最基础的二进制部署。一个成熟的软件包通常包含可执行文件安装到bin目录。库文件安装到lib或lib64目录。头文件供其他开发人员使用安装到include目录。配置文件应用程序启动时读取通常安装到etc目录。资源文件如图标、UI 文件、翻译文件、默认数据等安装到share目录。文档手册页man pages、许可证、README安装到share/doc或share/man。其他如 systemd 服务文件、桌面入口文件等。核心痛点如何将项目源代码树中结构复杂的资源目录例如assets/、configs/、docs/整体地、保持原有子目录结构地复制到安装目标中并且确保这个过程是跨平台的、可配置的、且能集成到打包流程中的。这就是install(DIRECTORY ...)命令大显身手的地方。它解决的正是批量、结构化文件部署的难题避免了写一堆重复的install(FILES ...)命令的窘境。本文将带你从“知道这个命令”升级到“精通运用这个命令”构建出生产级别的安装逻辑。2. 基础概念与核心原理在深入install(DIRECTORY)之前必须理解 CMake 安装阶段的基础。2.1 CMake 安装阶段简述当你运行cmake --build . --target install或make install在 Makefile 生成器中时CMake 执行的是在CMakeLists.txt中通过install()命令定义的所有规则。这些规则不会在编译时执行只在这个特定的“安装”阶段执行。安装的核心是定义“源”和“目标”的映射关系。2.2install()命令家族install()命令有多种签名用于处理不同类型的安装需求install(TARGETS ...): 安装由add_executable()或add_library()定义的目标。install(FILES ...): 安装单个或多个明确列出的文件。install(PROGRAMS ...): 类似FILES但安装后会默认给文件添加可执行权限在 Unix 系统上。install(DIRECTORY ...):本文重点安装整个目录及其内容。install(EXPORT ...): 生成并安装 CMake 包配置文件供其他 CMake 项目使用find_package()查找。install(SCRIPT/CODE ...): 在安装过程中执行自定义 CMake 脚本或代码。2.3install(DIRECTORY)的核心设计思想install(DIRECTORY)的设计哲学是声明式和模式匹配。你不需要枚举目录下的每一个文件只需要描述目录本身以及你对其中内容的处理规则过滤、权限、目标路径等。CMake 会在安装时动态地遍历目录应用这些规则。它与循环调用install(FILES)的本质区别在于效率与简洁性一条命令处理整个目录树CMakeLists.txt 更清晰。结构保持自动保持源目录的子目录结构到目标位置。模式过滤支持使用PATTERN和REGEX在文件复制时进行包含或排除功能强大。权限控制可以统一或差异化地设置安装后文件的权限。2.4 关键术语DESTINATION与CMAKE_INSTALL_PREFIXDESTINATION: 在install()命令中指定的相对或绝对目标路径。如果是相对路径它通常是相对于CMAKE_INSTALL_PREFIX的。CMAKE_INSTALL_PREFIX: 一个 CMake 变量定义了安装的根目录。在 Linux 上默认通常是/usr/local在 Windows 上可能是C:\Program Files\ProjectName。用户可以在运行cmake时通过-DCMAKE_INSTALL_PREFIX/your/path来覆盖。例如install(DIRECTORY assets DESTINATION share/myapp)结合-DCMAKE_INSTALL_PREFIX/usr最终文件会被安装到/usr/share/myapp/assets/...。理解这些概念后我们开始准备实践环境。3. 环境准备与前置条件本文的示例和命令在以下环境中测试但核心概念适用于所有支持 CMake 的平台。操作系统Ubuntu 22.04 LTS / Windows 10/11 with WSL2 / macOS Monterey。核心命令是跨平台的。CMake 版本3.16.3 或更高版本。install(DIRECTORY)的大部分功能在较早版本中已存在但某些细粒度控制如FILE_PERMISSIONS在较新版本中更完善。如果你的版本较低可以参考文末的降级指南。构建工具MakeLinux/macOS或 Ninja推荐更快。在 Windows 上可以是 Visual Studio 的 MSBuild。基础技能了解基本的 CMake 语法会使用add_executable、target_link_libraries和基础的install(TARGETS ...)。你可以通过以下命令检查你的 CMake 版本cmake --version如果版本低于 3.16可以考虑升级。在 Ubuntu 上可以使用官方 Kitware 仓库或从源码编译。网络热词中提到的“如何将ubuntu中cmake降到3.16.3”是一个特殊需求场景通常是为了兼容旧项目。对于学习本文3.16 即可。4.install(DIRECTORY)核心语法与参数精讲install(DIRECTORY)的语法看似复杂但分解后非常清晰。4.1 基本语法格式install(DIRECTORY dir... TYPE type | DESTINATION dir [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [USE_SOURCE_PERMISSIONS] # 注意与上面两个权限设置互斥 [FILES_MATCHING] [[PATTERN pattern | REGEX regex] [EXCLUDE] [PERMISSIONS permissions...]] ... [EXCLUDE_FROM_ALL] [COMPONENT component] [FILES_EXCLUDE_PATTERNS patterns...] # 3.24 新增 [CONFIGURATIONS [Debug|Release|...]] [OPTIONAL] [MESSAGE_NEVER] # 3.24 新增 )重要说明TYPE和DESTINATION是互斥的必须二选一。TYPE是更高级、更语义化的选项它基于GNUInstallDirs标准变量。4.2DESTINATION与TYPE的抉择使用DESTINATION直接指定相对或绝对路径。简单直接但需要你清楚目标平台的标准目录结构。# 将项目内的 resources 目录安装到 ${CMAKE_INSTALL_PREFIX}/share/myapp/ install(DIRECTORY resources/ DESTINATION share/myapp)注意DIRECTORY后的路径如果以/结尾表示安装该目录的内容。如果不以/结尾表示安装该目录本身。这是一个关键细节install(DIRECTORY resources DESTINATION share/myapp) # 安装后路径为 /share/myapp/resources/... install(DIRECTORY resources/ DESTINATION share/myapp) # 安装后路径为 /share/myapp/... (resources目录名被省略)使用TYPE更推荐的方式可移植性更好。CMake 内置了一些类型如BIN,LIB,INCLUDE,DATA,SHARE等它们会映射到GNUInstallDirs定义的变量上。# 包含 GNUInstallDirs 模块它定义了 CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_DATADIR 等变量 include(GNUInstallDirs) # 将 docs 目录安装到 “文档” 类型的标准位置例如 /usr/local/share/doc/myapp install(DIRECTORY docs/ TYPE DOC) # 将运行时数据安装到 DATA 类型位置例如 /usr/local/share/myapp install(DIRECTORY data/ TYPE DATA)常用 TYPE 映射关系具体路径由GNUInstallDirs和平台决定TYPE典型映射变量典型安装路径 (Linux, prefix/usr/local)BIN${CMAKE_INSTALL_BINDIR}binLIB${CMAKE_INSTALL_LIBDIR}liborlib64INCLUDE${CMAKE_INSTALL_INCLUDEDIR}includeDATA${CMAKE_INSTALL_DATADIR}shareSHARE${CMAKE_INSTALL_DATAROOTDIR}share4.3 权限控制FILE_PERMISSIONS、DIRECTORY_PERMISSIONS与USE_SOURCE_PERMISSIONS控制安装后文件的权限对于生成分发包至关重要。FILE_PERMISSIONS/DIRECTORY_PERMISSIONS: 分别为文件和目录设置权限。参数如OWNER_READ,GROUP_WRITE,WORLD_EXECUTE等。install(DIRECTORY scripts/ TYPE BIN FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # 例如 755 DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)USE_SOURCE_PERMISSIONS: 保留源文件的权限。这是默认行为如果未指定任何权限选项。注意一旦显式指定了FILE_PERMISSIONS或DIRECTORY_PERMISSIONSUSE_SOURCE_PERMISSIONS将被忽略。4.4 模式过滤PATTERN与REGEX这是install(DIRECTORY)最强大的功能之一允许你精细控制哪些文件被安装或排除并可以对其设置不同的权限。PATTERN: 使用类 Shell 的通配符模式如*.py,test_*。REGEX: 使用正则表达式进行更复杂的匹配。EXCLUDE: 与PATTERN或REGEX连用表示匹配到的文件/目录不被安装。PERMISSIONS: 与PATTERN或REGEX连用为匹配到的文件设置特定权限。install(DIRECTORY myproject/ DESTINATION share/myapp # 排除所有 .git 目录和 .tmp 文件 PATTERN .git EXCLUDE PATTERN *.tmp EXCLUDE # 为所有 .sh 脚本文件添加可执行权限 PATTERN *.sh PERMISSIONS OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE # 使用正则表达式排除备份文件 REGEX \\.bak$ EXCLUDE )4.5FILES_MATCHING选项此选项通常与PATTERN连用。它的含义是只安装那些至少匹配一个非EXCLUDE的PATTERN或REGEX的文件。如果不使用FILES_MATCHING目录下的所有文件除了被EXCLUDE的都会被安装PATTERN ... PERMISSIONS仅用于修改匹配文件的权限。# 示例只安装 .h 和 .hpp 头文件 install(DIRECTORY include/ DESTINATION include/myapp FILES_MATCHING PATTERN *.h PATTERN *.hpp)4.6 其他实用选项COMPONENT: 用于组件化安装。你可以将安装项分组如Runtime,Development,Documentation然后用户可以选择性地安装特定组件如cmake --install . --component Development。这对于生成复杂的分发包如 Debian 的-dev包非常有用。CONFIGURATIONS: 指定该安装规则仅对特定的构建配置生效如Debug,Release,RelWithDebInfo。例如你可能只想在Debug配置下安装调试符号文件。OPTIONAL: 如果源目录不存在不报错静默跳过。EXCLUDE_FROM_ALL: 如果使用默认的install目标不指定组件则跳过此规则。通常与COMPONENT一起使用。5. 完整项目示例部署一个模拟应用程序让我们通过一个完整的、虚构的MyApp项目来演示如何综合运用上述知识。项目结构如下myapp-project/ ├── CMakeLists.txt # 主 CMake 文件 ├── src/ │ ├── main.cpp │ └── CMakeLists.txt ├── include/ │ └── myapp/ │ ├── core.h │ └── utils.h ├── resources/ │ ├── icons/ │ │ ├── app.png │ │ └── logo.svg │ ├── config/ │ │ └── default.json │ └── translations/ │ ├── en_US.qm │ └── zh_CN.qm ├── docs/ │ ├── README.md │ └── manual.pdf ├── scripts/ │ ├── setup.sh │ └── cleanup.py └── cmake/ └── MyAppConfig.cmake.in # 用于生成包配置文件5.1 主CMakeLists.txt配置# myapp-project/CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(MyApp VERSION 1.0.0 LANGUAGES CXX) # 设置 C 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 包含 GNU 安装目录定义 include(GNUInstallDirs) # 添加子目录 add_subdirectory(src) # 假设我们有一个库目标 myapp_lib 和一个可执行文件目标 myapp 在 src/CMakeLists.txt 中定义 # # 安装目标 (可执行文件和库) # install(TARGETS myapp myapp_lib EXPORT MyAppTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development # 静态库 INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) # # 安装头文件 (使用 DIRECTORY) # install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Development FILES_MATCHING # 只安装匹配的文件 PATTERN *.h PATTERN *.hpp ) # # 安装资源文件 (使用 DIRECTORY保持目录结构) # install(DIRECTORY resources/ DESTINATION ${CMAKE_INSTALL_DATADIR}/myapp COMPONENT Runtime # 排除可能存在的临时文件 PATTERN *.tmp EXCLUDE PATTERN .gitkeep EXCLUDE # 确保脚本有可执行权限 (如果资源目录里有脚本) PATTERN *.sh PERMISSIONS OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE PATTERN *.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE ) # # 安装文档 (使用 TYPE DOC) # install(DIRECTORY docs/ TYPE DOC COMPONENT Documentation # 可选只安装特定文件类型 FILES_MATCHING PATTERN *.md PATTERN *.pdf ) # # 安装脚本 (到 bin 目录并确保可执行) # install(DIRECTORY scripts/ DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE # 排除非脚本文件 FILES_MATCHING PATTERN *.sh PATTERN *.py ) # # 生成并安装 CMake 包配置文件 (供 find_package 使用) # install(EXPORT MyAppTargets FILE MyAppTargets.cmake NAMESPACE MyApp:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyApp COMPONENT Development ) configure_file(cmake/MyAppConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/MyAppConfig.cmake ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/MyAppConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyApp COMPONENT Development )5.2 构建与安装模拟在项目根目录下执行标准的 CMake 构建流程# 1. 配置项目指定安装前缀例如一个本地测试目录 mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX$HOME/myapp_install -DCMAKE_BUILD_TYPERelease # 2. 编译 cmake --build . --parallel 4 # 3. 安装安装所有组件 cmake --install . # 4. 或者仅安装运行时组件 cmake --install . --component Runtime # 5. 查看安装结果 tree $HOME/myapp_install预期的安装目录结构将类似于/home/yourname/myapp_install/ ├── bin/ │ ├── myapp # 可执行文件 │ ├── setup.sh # 安装的脚本 (来自 scripts/) │ └── cleanup.py ├── include/ │ └── myapp/ │ ├── core.h │ └── utils.h ├── lib/ │ ├── libmyapp_lib.so # 动态库 (Linux示例) │ ├── MyAppTargets.cmake # CMake 导出文件 │ └── cmake/ │ └── MyApp/ │ ├── MyAppConfig.cmake │ └── MyAppTargets.cmake └── share/ ├── myapp/ # 来自 resources/ │ ├── icons/ │ ├── config/ │ └── translations/ └── doc/ └── MyApp/ # 来自 docs/ ├── README.md └── manual.pdf这个结构清晰、标准完全符合 Linux 的 FHS文件系统层次结构标准并且为打包工具如 CPack做好了准备。6. 运行结果与效果验证安装完成后验证工作至关重要。6.1 验证安装路径首先检查文件是否安装到了预期位置。使用tree或find命令。# 查看整体结构 tree -L 3 $HOME/myapp_install # 查找特定类型的文件 find $HOME/myapp_install -name *.sh -type f find $HOME/myapp_install -name *.h -type f6.2 验证可执行文件测试安装的可执行文件能否运行并能否找到其依赖的资源。# 临时将安装目录的库路径加入动态链接器搜索路径 (Linux) export LD_LIBRARY_PATH$HOME/myapp_install/lib:$LD_LIBRARY_PATH # 运行程序并观察其是否能正确读取 resources/ 下的配置 $HOME/myapp_install/bin/myapp --config $HOME/myapp_install/share/myapp/config/default.json如果程序正常运行并输出了预期结果或从指定配置中读取了值说明二进制文件、库文件和资源文件的安装位置和权限都是正确的。6.3 验证开发文件供其他 CMake 项目使用创建一个简单的测试项目test_project/CMakeLists.txt验证find_package(MyApp)是否能工作。# test_project/CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(TestMyApp) # 告诉 CMake 在哪里寻找我们的包 list(APPEND CMAKE_PREFIX_PATH $ENV{HOME}/myapp_install) find_package(MyApp REQUIRED) add_executable(test_app test.cpp) target_link_libraries(test_app PRIVATE MyApp::myapp_lib) # 使用导出目标// test_project/test.cpp #include myapp/core.h // 应该能正确找到安装的头文件 int main() { myapp::core_function(); return 0; }配置这个测试项目如果 CMake 能成功找到MyApp包并且编译链接通过则证明头文件和MyAppConfig.cmake的安装完全正确。7. 常见问题与排查思路在使用install(DIRECTORY)时你可能会遇到以下问题。下表列出了常见现象、原因及解决方案。问题现象可能原因排查方式解决方案CMake Error: install DIRECTORY given no DESTINATION!install(DIRECTORY)命令缺少DESTINATION或TYPE参数。检查命令语法确保DESTINATION path或TYPE type存在且正确拼写。添加DESTINATION或TYPE参数。安装后目录结构不对多了一层或少了一层目录DIRECTORY参数路径末尾是否带/理解有误。对比install(DIRECTORY dir_name ...)和install(DIRECTORY dir_name/ ...)的效果。明确意图带/安装内容不带/安装目录本身。在目标路径DESTINATION中调整。某些文件如.gitignore,*.tmp被意外安装未使用PATTERN或REGEX进行排除过滤。检查源目录列出所有文件。确认是否需要全局排除某些模式。在install(DIRECTORY)命令中添加PATTERN .git* EXCLUDE和PATTERN *.tmp EXCLUDE。安装的文件没有可执行权限脚本无法运行未设置文件权限。USE_SOURCE_PERMISSIONS可能未生效或者源文件本身无执行权限。使用ls -l查看源文件和安装后文件的权限。使用FILE_PERMISSIONS显式设置权限或使用PATTERN *.sh PERMISSIONS ...为特定模式设置。确保源文件在版本控制中有正确权限Git 需git update-index --chmodx script.sh。cmake --install失败提示Permission denied尝试安装到系统目录如/usr,/usr/local而没有sudo权限。检查CMAKE_INSTALL_PREFIX的路径。1. 使用sudo cmake --install .。2. 或安装到用户目录-DCMAKE_INSTALL_PREFIX$HOME/.local。3. 或使用DESTDIR环境变量进行分段安装常用于打包DESTDIR/tmp/stage cmake --install .。安装过程太慢或者卡住安装的目录非常大如node_modules, 构建目录build/被意外包含。检查install(DIRECTORY)指定的源路径是否包含了不必要的庞大目录。使用PATTERN或REGEX排除大型子目录或者更精确地指定源目录。确保构建目录build/不在源目录列表中。PATTERN或REGEX过滤似乎没生效对FILES_MATCHING选项的理解有误。PATTERN仅用于权限修改而非过滤。确认你的意图是想只安装匹配的文件还是想安装所有文件但修改部分文件的权限如果只想安装匹配的文件添加FILES_MATCHING选项。如果想安装所有文件但调整权限则不要加FILES_MATCHING。错误could not create directory ‘...‘ (no such file or directory)目标路径的父目录不存在且 CMake 没有权限或无法创建它。检查DESTINATION的完整路径。确认CMAKE_INSTALL_PREFIX存在且有写入权限。确保目标目录的路径是有效的。对于绝对路径确保上级目录存在。CMake 通常会创建目标目录但如果前缀路径不存在且无权限则会失败。先手动创建前缀目录或检查权限。8. 最佳实践与工程建议掌握了基本用法和排错后遵循以下最佳实践能让你的项目更专业、更易维护。8.1 明确区分安装组件使用COMPONENT参数将安装内容分组。这对于生成复杂的系统包如 Debian 的myapp,myapp-dev,myapp-doc至关重要。install(TARGETS myapp RUNTIME DESTINATION bin COMPONENT Runtime) install(DIRECTORY include/ DESTINATION include COMPONENT Development) install(DIRECTORY docs/ TYPE DOC COMPONENT Documentation)用户随后可以按需安装cmake --install . --component Runtime cmake --install . --component Development8.2 善用GNUInstallDirs提升可移植性始终include(GNUInstallDirs)并使用${CMAKE_INSTALL_*DIR}变量而不是硬编码bin,lib等路径。这确保了你的项目在不同 Linux 发行版如 Fedora 的lib64和不同平台上的行为一致。8.3 为install(DIRECTORY)编写测试在 CI/CD 流水线中添加一个安装测试步骤。在一个临时目录中执行安装然后验证关键文件是否存在、权限是否正确、以及可执行文件是否能运行。#!/bin/bash # 简易安装测试脚本示例 BUILD_DIRbuild INSTALL_DIR$PWD/test_install rm -rf ${BUILD_DIR} ${INSTALL_DIR} mkdir ${BUILD_DIR} cd ${BUILD_DIR} cmake .. -DCMAKE_INSTALL_PREFIX${INSTALL_DIR} cmake --build . --target install # 验证 if [[ -f ${INSTALL_DIR}/bin/myapp ]]; then echo SUCCESS: Binary installed. else echo ERROR: Binary missing. exit 1 fi # 检查头文件 find ${INSTALL_DIR}/include -name *.h | head -58.4 与 CPack 集成实现一键打包install(DIRECTORY)的配置是 CPack 生成分发包如.deb,.rpm,.zip的基础。确保你的安装规则干净、完整CPack 就能直接利用它们。在你的主CMakeLists.txt末尾添加# 包含 CPack 模块 include(CPack) # 设置一些 CPack 变量 set(CPACK_PACKAGE_VENDOR My Company) set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md) # 定义组件与 install() 中的 COMPONENT 对应 set(CPACK_COMPONENTS_ALL Runtime Development Documentation) # 为不同组件设置显示名称 set(CPACK_COMPONENT_RUNTIME_DISPLAY_NAME MyApp Runtime) set(CPACK_COMPONENT_DEVELOPMENT_DISPLAY_NAME Development Files) set(CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME Documentation)然后在构建后运行cd build cpack -G DEB # 生成 Debian 包 # 或 cpack -G RPM # 或 cpack -G ZIP生成的包将包含所有已安装的文件并保持你在install()命令中定义的目录结构和权限。8.5 处理版本化安装对于库项目有时需要并行安装多个主版本。一种常见模式是将库安装到带版本的子目录。# 将库文件安装到 lib/myapp-1.0/ install(TARGETS myapp_lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/myapp-${PROJECT_VERSION} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/myapp-${PROJECT_VERSION} )相应地在导出的MyAppConfig.cmake文件中需要正确指引链接路径。8.6 保持源目录清洁确保你的install(DIRECTORY)命令只引用版本控制中存在的、需要分发的源目录。避免意外包含构建产物如build/、IDE 配置文件如.vscode/,.idea/或临时文件。在.gitignore中做好配置并在 CMake 命令中通过PATTERN进行排除。通过遵循这些实践你的 CMake 项目将具备工业级的部署能力无论是用于内部开发、交付客户还是上传到系统包管理器都能从容应对。install(DIRECTORY)不再是黑盒而是你构建流程中一个强大、可控的利器。
返回列表