2026 年了,XMake 用 Lua 写配置,三行代码拉依赖,跨平台一键构建,它真的很爽。
但我依然不敢在主力项目里用它全面替代 CMake。

不是因为我不懂新工具,而是因为我见过太多团队,为了一时的开发体验,埋下三年后无法维护的雷。大型 C++ 项目想活下来,靠的不是工具多酷,而是三年后实习生还能不能五分钟跑起来,CI 还能不能稳定复现,安全审计还能不能通过。
XMake 的一体化设计,在小项目中是利器;但在涉及多团队、对外交付、长期演进的场景下,它的高耦合、弱生态、难审计,反而成了风险源。
今天,我就从真实踩坑经历出发,说清楚:为什么 CMake 依然是 C++ 工业界的默认选项?XMake 的边界在哪里?以及,C++ 构建系统的未来,究竟在何方?
一、先分清,构建系统≠ 包管理

好多人都在争论 CMake 和 XMake 谁更好,但却混淆了两个根本问题:
-
构建系统
解决的是怎么编译、怎么链接、怎么生成工程文件、怎么跨平台配置。代表工具包括 CMake、XMake、Meson、Bazel。
-
包管理
解决依赖从哪来、用哪个版本、如何复现、有没有二进制缓存、供应链是否安全。代表工具包括 Conan、vcpkg、xrepo、系统包管理器。
XMake 的核心是一体化,用 Lua 写构建脚本,内建 xrepo 拉依赖。这种设计在小项目中体验极佳,但在大型项目中反而成为风险源:耦合度高、难以替换、审计困难、与现有工具链集成成本高。
真正的问题不是「XMake 好不好」,而是「你的工程体系是否撑得住它的耦合」。
二、甩不掉CMake 的主要原因不是技术,是生态枷锁

我承认 CMake 的语法反人类,但现实很残酷:
-
几乎所有工业级 C++ 库只提供 CMakeLists.txt
如 OpenSSL、Boost、Qt、OpenCV、CUDA、TensorRT、gRPC、Protobuf……无一例外。
-
主流 IDE 深度集成
Visual Studio、CLion、VS Code、Xcode 都内置 CMake 支持,一键生成工程文件。
-
CI/CD 生态默认适配
GitHub Actions、GitLab CI、Jenkins 的 C++ 模板均以 CMake 为基准。这不是技术选型,你可以讨厌 CMake,但你根本绕不过它。
三、XMake 好用,但有边界

XMake 用 Lua 写配置,确实比 CMake 直观。比如拉两个常用库:
add_requires("fmt 10.2.1", "zlib 1.2.13")
target("app")
set_kind("binary")
add_files("src/*.cpp")
add_packages("fmt", "zlib")
配合三条命令就能跨平台构建:
xmake repo --add internal https://your-nexus/xrepo
xmake f -p linux --arch=arm64
xmake
这种体验,在统一技术栈的小团队里非常有效,我曾经用三天就搭起了一个嵌入式日志采集系统,开发效率很快。
可一旦项目要对外交付、涉及到多团队协作,XMake的短板就会暴露。
最头疼的是关键库支持缺失。 前年我的系统要集成一个第三方的 SDK,这个 SDK 仅提供编译的 Android ARM64 二进制包,并依赖特定的 STL 实现。xrepo 官方仓库里根本没有这个库,社区也没有适配。没办法,我只能自己封装 recipe,手动处理各种问题,还额外搭了一套脚本定期校验上游哈希值,确保私有源不被篡改。原本指望 XMake 开箱即用,结果反而多维护了一套包管理逻辑,这完全背离了提效的初衷。
IDE 集成也不稳定。 生成的 VS 工程偶尔会丢掉些东西,导致编译失效;Xcode 项目在路径含空格时解析失败。这些问题在 CMake + VS/Xcode 的组合里基本不会出现。
错误诊断更是痛点。 有一次模板实例化失败,XMake 只打印了 clang 的底层错误,完全丢失了上层调用上下文。而同样问题在 CMake + Ninja 下,能清晰看到是哪个 target、哪个头文件触发的,问题定位非常方便。
四、依赖管理方案对比
1、FetchContent / CPM 看似简单,实则危险
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.2.1
)
我们在具体项目中就吃过亏,因为 fmt 作者临时重打了 tag,CI 全红,三天无法合代码。根源是没固定 commit hash,也没校验 checksum。
2、 ExternalProject 隔离性强,但集成体验差
你需要手动处理 include/lib 路径、传递编译选项,而且它在 configure 阶段之后才执行,无法参与 CMake 的依赖图分析,并行构建效率低。适合完全隔离的第三方组件,不适合主干依赖。
3、真正扛得住长期演进的,还是 Conan 或 vcpkg
以 Conan 为例:
[requires]
fmt/10.2.1@
[generators]
CMakeDeps
配合 conan lock create 生成 lockfile,确保全团队和 CI 使用完全一致的依赖树。二进制包缓存到 Artifactory,构建提速相当明显。更重要的是,可强制所有依赖来自内部镜像,禁止直连公网,满足安全合规。
XMake 的 xrepo 在体验上接近 Conan,但企业落地仍有差距。我们试过迁移,结果在 Linux + libc++ 环境下链接失败:xrepo 没区分 STL 实现,把 libstdc++ 编译的二进制当成通用包分发了。Conan 虽然 profile 配置麻烦,但至少能通过 compiler.libcxx=libstdc++11 精确控制 ABI 兼容性。此外,xrepo 目前不支持 SPDX SBOM 格式,安全团队审计时还得额外写解析脚本。
五、未来不在工具,在接口和能力

C++ 的构建生态是不会由一个工具统一的,未来的发展趋势是:
- 接口标准化 CMake Presets、compile_commands.json、工具链文件、远程执行 API 正成为事实标准。谁先拥抱,谁活下来。
- 包管理专业化 锁文件、SBOM、二进制缓存、漏洞扫描不再是加分项,是准入门槛。
- C++ Modules 重塑构建逻辑 模块依赖图比头文件精确得多,增量构建和 PCM 分发缓存价值巨大。
Bazel 和 Buck2 在此领先,但现实是:Clang 18 才初步支持模块依赖图输出,MSVC 的 .ifc 文件无法跨版本兼容。短期内,CMake 仍是生态入口。长期看,谁能率先实现「模块感知 + 远程缓存 + 供应链安全」三位一体,谁就可能成为下一代标准。
六、最后一句实在话
选 CMake 还是 XMake,不取决于谁语法更优雅,而取决于你的项目是否需要对外协作、是否要求可审计、是否承受得起构建不可复现的风险。我见过太多团队为开发体验牺牲工程稳健,最后花十倍代价回迁。
别为了今天的爽,赌上明天的命。毕竟,所有优雅的系统,都始于对“跑不起来”的恐惧。
你在项目中,有没有因为选错构建工具,吃过亏?欢迎在技术社区交流你的观点和经验,例如在 云栈社区 这样的开发者平台上,与其他同行探讨构建系统与CI/CD 实践,或许能帮你避开不少坑。