cmake安装问题核心在于install()的destination路径错误、cmake_install_prefix被忽略及make install权限/路径缺失;linux应优先用包管理器安装,构建前需指定cmake_install_prefix、创建目标目录并正确使用runtime/library/archive关键词声明安装规则。

CMake 不需要“从安装到实战”的完整教程——它最常出问题的地方,就卡在 install() 的 DESTINATION 路径写错、CMAKE_INSTALL_PREFIX 被忽略、或者 make install 时权限/路径根本不存在。
Linux 下装 CMake 别用源码编译,优先走包管理器
CentOS/RHEL 7/8/9、Ubuntu/Debian 等主流发行版都自带较新版本的 CMake(2026 年多数已预装 3.22+),直接用系统包管理器最稳:
-
yum install -y cmake(CentOS 7)或dnf install -y cmake(CentOS 8+ / Fedora) -
apt update && apt install -y cmake(Ubuntu/Debian) - 除非你要用
cmake 3.28+的新特性(比如find_package(... CONFIG REQUIRED)的 strict mode),否则真没必要下载 tar.gz 自己./configure && make && sudo make install—— 容易和系统原有版本冲突,且后续卸载困难 - 验证是否可用:
cmake --version,输出类似cmake version 3.22.1即可
cmake . + make + make install 这三步里,make install 才是真正要命的环节
很多人跑通了 cmake . 和 make,一执行 make install 就报错,常见现象包括:
-
Permission denied: /usr/local/bin—— 默认CMAKE_INSTALL_PREFIX是/usr/local,普通用户没写权限 -
Cannot create directory "/usr/local/bin": No such file or directory—— 目标路径父目录不存在(CMake 不会自动创建多级目录) - 安装后找不到文件,比如
myapp没进bin/,libmylib.so没进lib/——install(TARGETS ...)没写对类型关键词(RUNTIME/LIBRARY/ARCHIVE)
正确做法是:
- 构建前指定安装前缀:
cmake -DCMAKE_INSTALL_PREFIX=$HOME/local .(推荐用绝对路径,避免相对路径歧义) - 确保目标目录可写:
mkdir -p $HOME/local/bin $HOME/local/lib -
CMakeLists.txt中必须显式声明安装规则,例如:
add_executable(myapp main.cpp) install(TARGETS myapp RUNTIME DESTINATION bin)
注意:RUNTIME DESTINATION bin 表示把可执行文件装到 $HOME/local/bin,不是 ./bin;DESTINATION 总是相对于 CMAKE_INSTALL_PREFIX 的值。
install(TARGETS ...) 必须按目标类型配关键词,不能只写 DESTINATION
这是新手掉坑最多的地方:以为 install(TARGETS myapp DESTINATION bin) 就够了,结果安装失败或静默跳过。CMake 要求你明确告诉它「这个目标属于哪一类」:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 可执行文件 → 用
RUNTIME DESTINATION(Windows 下还涉及NAMELINK,Linux 可忽略) - 动态库(
.so)→ 用LIBRARY DESTINATION - 静态库(
.a)→ 用ARCHIVE DESTINATION - 如果一个 target 同时生成多种产物(比如 SHARED 库也会生成 import lib),得把关键词都列全
错误写法:install(TARGETS mylib DESTINATION lib)(缺类型关键词,CMake 会警告并跳过)
正确写法:install(TARGETS mylib LIBRARY DESTINATION lib)
别硬背 GNUInstallDirs,但至少知道 GNUInstallDirs 是干啥的
include(GNUInstallDirs) 不是语法糖,它是帮你把 bin、lib、include 这些路径映射成符合 Linux FHS 规范的变量,比如:
-
CMAKE_INSTALL_BINDIR→ 默认是bin,但若你设-DCMAKE_INSTALL_PREFIX=/opt/myapp,它会自动变成/opt/myapp/bin -
CMAKE_INSTALL_LIBDIR→ 在某些发行版上可能是lib64而非lib,GNUInstallDirs会自动适配
所以推荐这样写:
include(GNUInstallDirs)
add_executable(myapp main.cpp)
install(TARGETS myapp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
而不是死写 DESTINATION bin —— 后者在交叉编译或某些定制系统里会翻车。
最容易被忽略的一点:CMake 不检查 DESTINATION 路径是否存在,也不自动创建;make install 失败时,错误信息往往藏在最后几行,而不是开头。动手前先 ls -l $(cmake -L | grep INSTALL_PREFIX | cut -d= -f2) 看一眼前缀是否可达,比反复重试高效得多。










