CMake 从入门到精通:完整教程 / 第 11 章:安装与打包
第 11 章:安装与打包
11.1 install 命令概览
install() 是 CMake 中用于定义安装规则的命令。
# 执行安装
cmake --install build
cmake --install build --prefix /opt/myapp
cmake --install build --config Release
cmake --install build --component dev
11.2 安装目标
11.2.1 基本目标安装
add_executable(myapp main.cpp)
add_library(mylib STATIC src/mylib.cpp)
add_library(mylib_shared SHARED src/mylib.cpp)
# 安装目标
install(TARGETS myapp mylib mylib_shared
RUNTIME DESTINATION bin # 可执行文件 (.exe, .dll)
LIBRARY DESTINATION lib # 共享库 (.so, .dylib)
ARCHIVE DESTINATION lib # 静态库 (.a, .lib)
OBJECTS DESTINATION lib # 对象文件
INCLUDES DESTINATION include # 头文件目录
)
11.2.2 安装目录对照表
| 目标类型 |
目标关键字 |
默认安装目录 |
| 可执行文件 |
RUNTIME |
bin |
| 动态库(非 macOS) |
LIBRARY |
lib |
| 动态库(macOS) |
LIBRARY |
lib |
| Windows DLL |
RUNTIME(.dll)+ ARCHIVE(.lib) |
bin + lib |
| 静态库 |
ARCHIVE |
lib |
| 对象库 |
OBJECTS |
lib |
| 头文件集 |
FILE_SET HEADERS |
include |
11.2.3 完整的安装示例
install(TARGETS myapp mylib
EXPORT MyProjectTargets
# 可执行文件
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
# 共享库
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Runtime
NAMELINK_COMPONENT Development
# 静态库
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Development
# 头文件
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
💡 提示:CMAKE_INSTALL_BINDIR 等变量来自 GNUInstallDirs 模块。
11.3 安装文件和目录
11.3.1 安装头文件
# 安装特定文件
install(FILES
include/mylib/core.h
include/mylib/utils.h
include/mylib/types.h
DESTINATION include/mylib
COMPONENT Development
)
# 安装目录
install(DIRECTORY include/
DESTINATION include
COMPONENT Development
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "*.inc"
PATTERN ".git" EXCLUDE
)
11.3.2 安装程序和脚本
# 安装为可执行文件
install(PROGRAMS
scripts/deploy.sh
scripts/configure.py
DESTINATION bin
COMPONENT Runtime
)
# 安装任意文件
install(FILES
config/myapp.conf
config/logging.conf
DESTINATION etc/myapp
COMPONENT Configuration
)
11.3.3 安装目录内容
# 安装整个目录
install(DIRECTORY data/
DESTINATION share/myapp/data
USE_SOURCE_PERMISSIONS
PATTERN "*.txt"
PATTERN "internal" EXCLUDE
)
11.3.4 安装类型汇总
| 命令 |
安装内容 |
用途 |
install(TARGETS ...) |
构建目标 |
库和可执行文件 |
install(FILES ...) |
文件 |
头文件、配置文件 |
install(PROGRAMS ...) |
可执行脚本 |
脚本、工具 |
install(DIRECTORY ...) |
目录 |
数据目录、资源 |
install(EXPORT ...) |
导出集 |
CMake 包配置 |
install(IMPORTED_RUNTIME_ARTIFACTS ...) |
导入目标产物 |
外部二进制 |
11.4 GNUInstallDirs
include(GNUInstallDirs)
# 标准安装目录变量
message("可执行文件: ${CMAKE_INSTALL_BINDIR}") # bin
message("库文件: ${CMAKE_INSTALL_LIBDIR}") # lib 或 lib64
message("头文件: ${CMAKE_INSTALL_INCLUDEDIR}") # include
message("数据: ${CMAKE_INSTALL_DATADIR}") # share
message("配置: ${CMAKE_INSTALL_SYSCONFDIR}") # etc
message("手册: ${CMAKE_INSTALL_MANDIR}") # share/man
| 变量 |
默认值 |
说明 |
CMAKE_INSTALL_BINDIR |
bin |
用户可执行文件 |
CMAKE_INSTALL_SBINDIR |
sbin |
系统管理可执行文件 |
CMAKE_INSTALL_LIBDIR |
lib 或 lib64 |
库文件 |
CMAKE_INSTALL_INCLUDEDIR |
include |
头文件 |
CMAKE_INSTALL_DATADIR |
share |
架构无关数据 |
CMAKE_INSTALL_SYSCONFDIR |
etc |
配置文件 |
CMAKE_INSTALL_LOCALSTATEDIR |
var |
可变数据 |
11.5 导出与包配置
11.5.1 创建导出集
# 安装目标并导出
install(TARGETS mylib myapp
EXPORT MyProjectTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
# 安装导出文件
install(EXPORT MyProjectTargets
FILE MyProjectTargets.cmake
NAMESPACE MyProject::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProject
)
11.5.2 生成配置文件
include(CMakePackageConfigHelpers)
# 配置文件模板
configure_package_config_file(
cmake/MyProjectConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProject
)
# 版本文件
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
# 安装配置文件
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProject
)
11.5.3 配置模板文件
# cmake/MyProjectConfig.cmake.in
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
# 声明依赖
find_dependency(Threads)
if(@MYPROJECT_USE_OPENSSL@)
find_dependency(OpenSSL)
endif()
# 包含目标
include("${CMAKE_CURRENT_LIST_DIR}/MyProjectTargets.cmake")
check_required_components(MyProject)
11.5.4 安装后使用
# 下游项目
find_package(MyProject REQUIRED)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE MyProject::mylib)
11.6 组件安装
11.6.1 定义组件
install(TARGETS mylib
EXPORT MyProjectTargets
ARCHIVE DESTINATION lib
COMPONENT Development
LIBRARY DESTINATION lib
COMPONENT Runtime
NAMELINK_COMPONENT Development
)
install(DIRECTORY include/
DESTINATION include
COMPONENT Development
)
install(FILES config/default.conf
DESTINATION etc/myapp
COMPONENT Configuration
)
11.6.2 按组件安装
# 安装所有组件
cmake --install build
# 只安装特定组件
cmake --install build --component Runtime
cmake --install build --component Development
# 排除组件
cmake --install build --exclude-component Development
11.6.3 组件描述
# CMakeLists.txt
set(CPACK_COMPONENTS_ALL Runtime Development Configuration Docs)
set(CPACK_COMPONENT_Runtime_DISPLAY_NAME "运行时库")
set(CPACK_COMPONENT_Development_DISPLAY_NAME "开发文件")
set(CPACK_COMPONENT_Configuration_DISPLAY_NAME "配置文件")
set(CPACK_COMPONENT_Docs_DISPLAY_NAME "文档")
set(CPACK_COMPONENT_Development_DEPENDS Runtime)
set(CPACK_COMPONENT_Configuration_DEPENDS Runtime)
11.7 CPack 打包
11.7.1 基本配置
# 顶层 CMakeLists.txt 末尾
include(CPack)
# 通用设置
set(CPACK_PACKAGE_NAME "myproject")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My Project Description")
set(CPACK_PACKAGE_VENDOR "My Company")
set(CPACK_PACKAGE_CONTACT "[email protected]")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://example.com")
11.7.2 生成器选择
# 设置打包格式
set(CPACK_GENERATOR "TGZ") # tar.gz
# 多种格式
set(CPACK_GENERATOR "TGZ;DEB;RPM")
# 自动检测
if(WIN32)
set(CPACK_GENERATOR "NSIS;ZIP")
elseif(APPLE)
set(CPACK_GENERATOR "DragNDrop;TGZ")
else()
set(CPACK_GENERATOR "DEB;RPM;TGZ")
endif()
11.7.3 打包格式对照表
| 格式 |
生成器 |
平台 |
文件扩展名 |
| tar.gz |
TGZ |
Linux/macOS |
.tar.gz |
| tar.bz2 |
TBZ2 |
Linux/macOS |
.tar.bz2 |
| tar.xz |
TXZ |
Linux/macOS |
.tar.xz |
| ZIP |
ZIP |
全平台 |
.zip |
| DEB |
DEB |
Debian/Ubuntu |
.deb |
| RPM |
RPM |
RHEL/Fedora |
.rpm |
| NSIS |
NSIS |
Windows |
.exe |
| WiX |
WIX |
Windows |
.msi |
| DragNDrop |
DragNDrop |
macOS |
.dmg |
| productbuild |
productbuild |
macOS |
.pkg |
11.7.4 DEB 包配置
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Developer <[email protected]>")
set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17), libssl3")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://example.com")
set(CPACK_DEBIAN_FILENAMES DEBDEFAULT)
11.7.5 RPM 包配置
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
set(CPACK_RPM_PACKAGE_URL "https://example.com")
set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.1")
set(CPACK_RPM_PACKAGE_AUTOREQPROV "no")
11.7.6 NSIS 配置(Windows)
set(CPACK_NSIS_DISPLAY_NAME "My Project")
set(CPACK_NSIS_PACKAGE_NAME "MyProject")
set(CPACK_NSIS_INSTALLED_ICON_NAME "bin/myapp.exe")
set(CPACK_NSIS_URL_INFO_ABOUT "https://example.com")
set(CPACK_NSIS_HELP_LINK "https://example.com/docs")
set(CPACK_NSIS_MODIFY_PATH ON)
11.7.7 运行 CPack
# 构建项目
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
# 生成所有包
cd build
cpack
# 指定生成器
cpack -G TGZ
cpack -G DEB
# 指定配置
cpack -C Release
cpack --config CPackConfig.cmake
11.8 cpack_add_component
cpack_add_component(Runtime
DISPLAY_NAME "运行时库"
DESCRIPTION "运行应用程序所需的库文件"
REQUIRED
GROUP "Core"
)
cpack_add_component(Development
DISPLAY_NAME "开发文件"
DESCRIPTION "头文件和静态库,用于开发"
DEPENDS Runtime
GROUP "Development"
)
cpack_add_component_group(Core
DISPLAY_NAME "核心组件"
DESCRIPTION "应用程序核心文件"
EXPANDED
)
cpack_add_component_group(Development
DISPLAY_NAME "开发工具"
DESCRIPTION "开发所需的文件和工具"
EXPANDED
)
11.9 业务场景
场景:完整的安装与打包配置
cmake_minimum_required(VERSION 3.16)
project(MyApp VERSION 2.1.0 LANGUAGES CXX)
include(GNUInstallDirs)
# 构建
add_library(mylib src/core.cpp)
target_include_directories(mylib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE mylib)
# 安装
install(TARGETS mylib myapp
EXPORT MyAppTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT MyAppTargets
FILE MyAppTargets.cmake
NAMESPACE MyApp::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyApp
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
cmake/MyAppConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/MyAppConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyApp
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyAppConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MyAppConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MyAppConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyApp
)
# 打包
include(CPack)
set(CPACK_PACKAGE_NAME "myapp")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_GENERATOR "TGZ;DEB")
11.10 注意事项
| 问题 |
说明 |
| 安装前缀 |
CMAKE_INSTALL_PREFIX 控制安装根目录 |
| Windows DLL |
DLL 文件需要安装到 RUNTIME 目录 |
| RPATH |
设置 CMAKE_INSTALL_RPATH 确保运行时能找到库 |
DESTDIR |
用于打包时的临时安装根目录 |
| COMPONENT 安装 |
开发包和运行时包分开 |
11.11 扩展阅读
上一章:第 10 章 — 测试与 CTest | 下一章:第 12 章 — CMake 预设 →