install() 不是构建时执行的命令,它只在显式调用 cmake --install 或 make install 时才复制文件;必须明确指定 RUNTIME/LIBRARY/ARCHIVE 类型及 DESTINATION,否则静默失败或报错。

直接说结论:install() 不是构建时执行的命令,它只在你显式调用 cmake --install 或 make install 时才真正复制文件;写错目标类型或漏掉 DESTINATION 就会静默失败或报错。
install(TARGETS) 必须区分 RUNTIME / LIBRARY / ARCHIVE
可执行文件、动态库、静态库在不同系统上归类不同,CMake 要求你明确指定安装类别:
-
RUNTIME:用于 Windows 的.exe、Linux/macOS 的无后缀可执行文件(不是.so!) -
LIBRARY:用于共享库:.so(Linux)、.dylib(macOS)、.dll(Windows) -
ARCHIVE:用于静态库:.a(Linux/macOS)、.lib(Windows) - 如果只写
install(TARGETS myapp DESTINATION bin),Windows 下.dll可能被忽略,Linux 下.a不会被安装
install(FILES) 和 install(DIRECTORY) 的路径必须存在且可读
install(FILES) 不能自动创建父目录,也不能展开通配符;install(DIRECTORY) 默认递归但不带子目录结构:
-
install(FILES config.json DESTINATION etc):要求当前源码树中必须有config.json,否则构建不报错,但cmake --install时会失败并提示 “file not found” -
install(DIRECTORY include/ DESTINATION include):会把include/foo.h安装成${CMAKE_INSTALL_PREFIX}/include/foo.h,但不会保留include/subdir/的层级 —— 若需保留,加FILES_MATCHING PATTERN "*.h"和REGEX "/$" EXCLUDE - 绝对路径(如
${PROJECT_BINARY_DIR}/TutorialConfig.h)必须在 install 前已生成,否则安装阶段找不到
CMAKE_INSTALL_PREFIX 默认是 /usr/local,但普通用户没权限写
直接运行 cmake --install . 很可能因权限拒绝失败,尤其在 CI 或非 root 环境:
- 开发时推荐用
cmake --install . --prefix "${PWD}/install",把产物落到当前 build 目录下 - 若在
CMakeLists.txt中硬编码默认路径(比如想让make install默认进build/install),得用if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)判断后set(... CACHE STRING ... FORCE) -
DESTDIR是临时打包用的(如制作 deb 包),它不改CMAKE_INSTALL_PREFIX,而是把所有安装路径前缀再套一层 ——make install DESTDIR=/tmp/stage实际写入的是/tmp/stage/usr/local/bin/...
最容易被忽略的一点:install 规则本身不参与依赖图计算。即使你写了 install(FILES ${CMAKE_BINARY_DIR}/generated.h ...),CMake 也不会自动确保这个头文件在 install 前已生成 —— 你得手动加 add_custom_target 或 add_custom_command 来建立依赖。


















