# CMake命令install - CPack打包完全指南:跨平台安装包制作 你是否遇到过这样的困扰: - 编译好的程序不知道如何分发给用户 - 手动复制文件到系统目录,容易出错 - 不同平台需要不同的打包方式,维护成本高 - 用户安装后不知道如何卸载 - 缺少专业的安装包,影响项目形象 这些问题都可以通过CMake的**安装和打包**功能来解决。CMake提供了完整的安装配置和CPack打包工具,可以轻松制作专业的安装包。 ### 手动部署的痛点 文件分散 ```bash # 手动部署需要复制多个文件 cp myapp /usr/local/bin/ cp libmylib.so /usr/local/lib/ cp mylib.h /usr/local/include/ cp config.json /etc/myapp/ # 容易遗漏,路径不一致 ``` **平台差异** - • Windows需要NSIS或WiX安装包 - • Linux需要deb/rpm包 - • macOS需要dmg/pkg包 - • 手动制作耗时耗力 **卸载困难** - • 用户不知道安装了哪些文件 - • 手动删除容易遗漏 - • 无法完全清理 ### CMake安装和打包的价值 **自动化安装** ```bash # 一条命令完成安装 cmake --install build # 自动处理所有文件 # - 可执行文件到bin目录 # - 库文件到lib目录 # - 头文件到include目录 # - 配置文件到etc目录 ``` 跨平台打包 ```bash # 自动生成对应平台的安装包 cpack -G NSIS      # Windows cpack -G DEB       # Debian/Ubuntu cpack -G RPM       # RedHat/CentOS cpack -G DragNDrop # macOS ``` **核心优势**: - ✅ **自动化**:一条命令完成安装和打包 - ✅ **跨平台**:统一配置,自动适配不同平台 - ✅ **专业**:生成标准的安装包格式 - ✅ **可维护**:配置集中管理,易于更新 ## install命令基础(CPack的前置知识) CPack需要基于install命令定义的安装规则来打包,所以先简单了解install命令。 ### 基本用法 **安装可执行文件和库** ```cmake include(GNUInstallDirs) # 安装可执行文件到bin目录 install(TARGETS myapp     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) # 安装库文件 install(TARGETS mylib     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}      # 静态库     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}      # 动态库     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}      # Windows DLL ) # 同时安装多个目标 install(TARGETS myapp mylib     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) ``` **安装文件** ```cmake # 安装头文件 install(FILES include/mylib.h     DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject ) # 安装目录 install(DIRECTORY include/     DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject     FILES_MATCHING PATTERN "*.h" ) # 安装配置文件 install(FILES config/config.json     DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/myproject ) ``` **标准路径变量**(推荐使用): • `CMAKE_INSTALL_BINDIR`:bin目录 • `CMAKE_INSTALL_LIBDIR`:lib目录 • `CMAKE_INSTALL_INCLUDEDIR`:include目录 • `CMAKE_INSTALL_DATADIR`:share目录 • `CMAKE_INSTALL_SYSCONFDIR`:etc目录 完整示例 ```cmake cmake_minimum_required(VERSION 3.15) project(MyProject VERSION 1.0.0) add_executable(myapp src/main.cpp) add_library(mylib STATIC src/mylib.cpp) include(GNUInstallDirs) install(TARGETS myapp mylib     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES include/mylib.h     DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject ) ``` # CPack打包工具详解 ### CPack简介 CPack是CMake内置的打包工具,可以自动生成各种平台的安装包,无需手动编写打包脚本。 **核心特点**: - • 🎯 **跨平台**:支持Windows、Linux、macOS - • 📦 **多格式**:NSIS、DEB、RPM、DMG、ZIP等 - • 🔧 **易配置**:基于CMake配置,与构建流程集成 - • 📊 **自动化**:一条命令生成安装包 - • 🆓 **完全免费**:CMake内置,无需额外工具(部分生成器需要) ### 启用CPack **基础配置** ```cmake # 在CMakeLists.txt末尾添加 include(CPack) ``` 基本设置 ```cmake set(CPACK_PACKAGE_NAME "MyProject") set(CPACK_PACKAGE_VENDOR "MyCompany") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My Project Description") set(CPACK_PACKAGE_DESCRIPTION "Detailed description of the project") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") set(CPACK_GENERATOR "ZIP")  # 默认生成器 # 设置安装包文件名格式(可选) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}") include(CPack) ``` **重要提示**: - `include(CPack)`必须在所有CPack配置之后 - 版本信息建议使用`PROJECT_VERSION`变量,保持一致性 - 包名建议使用小写,符合Linux包管理规范 ### 多生成器配置 **同时支持多个平台** ```cmake # 检测平台并设置生成器 if(WIN32)     set(CPACK_GENERATOR "NSIS;ZIP") elseif(APPLE)     set(CPACK_GENERATOR "DragNDrop;TGZ") elseif(UNIX)     set(CPACK_GENERATOR "DEB;RPM;TGZ") endif() include(CPack) ``` 生成所有格式 ```cmake cpack -G "NSIS;ZIP"  # Windows cpack -G "DEB;RPM;TGZ"  # Linux ``` # 常见问题 Q:CPack找不到生成器怎么办? A: • **NSIS**:Windows上需要安装NSIS(https://nsis.sourceforge.io/) • **DEB**:Linux上需要安装`dpkg-dev`:`sudo apt-get install dpkg-dev` • **RPM**:Linux上需要安装`rpmbuild`:`sudo yum install rpm-build` Q:如何为不同平台生成不同的安装包? A: ```cmake if(WIN32)     set(CPACK_GENERATOR "NSIS;ZIP") elseif(APPLE)     set(CPACK_GENERATOR "DragNDrop") elseif(UNIX)     set(CPACK_GENERATOR "DEB;RPM") endif() ``` ### 核心要点回顾 **CPack的核心价值**: - • ✅ **自动化打包**:一条命令生成安装包 - • ✅ **跨平台支持**:Windows/Linux/macOS统一配置 - • ✅ **专业格式**:生成标准安装包格式 - • ✅ **易于集成**:与CMake构建流程无缝集成 **使用建议**: - • **基础项目**:使用install命令 + CPack基本配置即可 - • **复杂项目**:添加依赖声明、图标、许可证等 - • **CI/CD**:集成到自动化流程,自动生成安装包 **最佳实践**: - • 使用标准安装路径(GNUInstallDirs) - • 明确声明运行时依赖 - • 提供清晰的包描述信息 - • 集成到CI/CD流程实现自动化 ### 推荐资源 **官方文档**: - • CMake install命令 - • CPack文档 - • GNUInstallDirs # 附录 install命令常用模式 ```cmake # 安装可执行文件 install(TARGETS myapp RUNTIME DESTINATION bin) # 安装库文件 install(TARGETS mylib      ARCHIVE DESTINATION lib     LIBRARY DESTINATION lib ) # 安装头文件 install(FILES mylib.h DESTINATION include) # 安装目录 install(DIRECTORY include/ DESTINATION include) ``` CPack常用配置 ```cmake set(CPACK_PACKAGE_NAME "MyProject") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") set(CPACK_GENERATOR "NSIS;DEB;RPM") include(CPack) ``` 标准安装路径 ```cmake include(GNUInstallDirs) # ${CMAKE_INSTALL_BINDIR}      # bin # ${CMAKE_INSTALL_LIBDIR}      # lib # ${CMAKE_INSTALL_INCLUDEDIR}  # include # ${CMAKE_INSTALL_DATADIR}     # share ```