CMakePresets.json的configurePresets仅驱动cmake配置流程,不执行conan install等外部命令;它只能通过cacheVariables(如CMAKE_TOOLCHAIN_FILE)消费Conan已生成的toolchain文件,且binaryDir必须与conan install的--install-folder严格一致。

为什么 CMakePresets.json 不能直接写 conan install 命令
CMakePresets.json 的 configurePresets 只负责调用 cmake,不执行任意 shell 命令。它不支持在 preset 内嵌入 conan install 或其他前置步骤——哪怕你加了 environmentVariables 或 cacheVariables,CMake 本身也不会帮你跑 Conan。
常见错误现象:把 conan install 命令塞进 command 字段,结果报错 Unknown field "command";或误以为 condition 能触发外部命令,其实它只做布尔判断。
- Presets 的职责边界很清晰:只管 CMake 配置阶段(即
cmake -S . -B build ...) - Conan 的
install是独立前置步骤,必须手动或脚本化执行 - 想“一键配置”,得靠 wrapper 脚本或 IDE 集成,不是靠 preset 自身
conan install 和 cmake 的执行顺序必须严格分开
Conan 2.x 生成的 conan_toolchain.cmake 和 *-deps.cmake 文件,是给 CMake 后续读取用的。这些文件必须在 cmake 执行前就存在于 build/ 目录下,否则 include() 会失败,find_package() 会找不到包。
典型出错路径:cmake -B build -G Xcode 先跑,再补 conan install .. → CMake 已缓存旧状态,即使后续生成了 toolchain,也不会自动重载。
- 正确顺序永远是:
conan install <src> -if <build> --profile:host=xxx→cmake -S <src> -B <build> --preset=xxx -
-if(--install-folder)必须和 preset 中的binaryDir完全一致,否则 CMake 找不到生成的 .cmake 文件 - 如果用了
CMAKE_PROJECT_TOP_LEVEL_INCLUDES(如 cmake-conan v2),该路径也必须指向<build>下已存在的conan_toolchain.cmake
如何让 configurePreset 正确加载 Conan 生成的 toolchain
CMakePresets.json 里不能“运行” Conan,但可以“消费” Conan 的输出。关键在于 cacheVariables 和 toolchainFile 的配合。
假设你在 build/ 下执行了 conan install .. -if build --profile:host=ios-arm64,它会生成 build/conan_toolchain.cmake。此时 preset 必须显式告诉 CMake 加载它:
{
"configurePresets": [{
"name": "ios-arm64",
"displayName": "iOS arm64 (Xcode)",
"description": "Build for iOS arm64 using Xcode",
"binaryDir": "${sourceDir}/build/ios-arm64",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{PWD}/build/ios-arm64/conan_toolchain.cmake"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
}
}]
}
-
CMAKE_TOOLCHAIN_FILE是唯一可靠方式,比include()更早介入 CMake 初始化 - 路径必须是绝对路径,
$env{PWD}在 Linux/macOS 可用,Windows 上建议用$env{CD}或硬编码(CI 环境推荐用${sourceDir}拼接) - 不要在
cacheVariables里重复设CMAKE_SYSTEM_NAME=IOS等——Conan 的 toolchain 已包含全部平台设置,重复会导致冲突
多 profile 场景下,conan install 命令怎么和 preset 对齐
一个 preset 对应一个构建目标(如 iOS arm64),但它不决定用哪个 Conan profile;profile 是 conan install 的输入,不是 CMake 的输入。两者靠目录约定对齐。
推荐做法:每个 preset 对应一个独立 build 子目录,并在该目录下执行对应 profile 的 conan install:
- 为 iOS arm64 创建
build/ios-arm64/,运行conan install .. -if build/ios-arm64 --profile:host=ios-arm64 - 为 Android aarch64 创建
build/android-aarch64/,运行conan install .. -if build/android-aarch64 --profile:host=android-aarch64 - 每个 preset 的
binaryDir和CMAKE_TOOLCHAIN_FILE都绑定到对应子目录,完全隔离
容易被忽略的一点:Conan profile 中的 [settings](如 os.version、compiler.version)必须与 CMake 实际使用的工具链能力匹配。比如 iOS profile 设了 os.version=15.0,但 Xcode command line tools 是 14.3,CMake 就可能因 CMAKE_OSX_DEPLOYMENT_TARGET 不兼容而静默降级或报错——这种问题不会出现在 preset 配置里,只能从 conan install 日志中排查。


















