host profile决定二进制运行环境(如arch、os、compiler),build profile描述构建机工具链;二者必须显式成对指定,共同固化于conan.lock中确保构建可重现。

host profile 决定最终产物跑在哪
它描述的是你最终要部署的目标环境:CPU 架构、操作系统、编译器版本、C++ 标准、是否启用 shared、fPIC 等——这些直接决定生成的二进制能否在目标机器上运行或链接。比如交叉编译到嵌入式 ARM 设备,arch=armv8、os=Linux、compiler=gcc 就必须写在 host profile 里。
常见错误现象:
- 本地能编译通过,但板子上
./app: cannot execute binary file: Exec format error—— 很可能是 host profile 的arch或os没对齐 - 链接时报
undefined reference to `std::string::...'—— 往往是compiler.libcxx(如libstdc++vslibc++)不匹配
build profile 描述构建机本身的工具链
它只管“怎么编”:你在哪台机器上跑 conan install,用什么编译器去编译那些构建时依赖(比如 cmake、pkgconf、autoconf),要不要用 clang 而不是系统默认 gcc 来生成构建脚本。它不参与最终产物 ABI 的生成,只影响构建过程本身。
使用场景:
- 你在 macOS 上交叉编译 Linux ARM64 二进制,build profile 就该是
os=Macos、compiler=apple-clang - CI 流水线中,构建机是 Ubuntu 22.04 + GCC 11,但你要产出 Windows x64 + MSVC 二进制,build profile 就得明确设为 GCC 11,host profile 才是
os=Windows+compiler=msvc - 漏配 build profile 时,Conan 默认 fallback 到
defaultprofile,容易导致构建工具(如meson)被错误地用目标平台编译器去编译,直接失败
--profile:host 和 --profile:build 必须成对出现
Conan 2.x 强制双 profile 模式。命令里不显式指定,就会隐式复用同一个 profile,这在交叉场景下几乎必然出错。
实操建议:
- 永远显式写全:
conan install . --profile:host=profiles/arm64-release --profile:build=profiles/macos-clang - 不要混用
-pr简写:它只接受一个 profile,无法区分 host/build,容易误用 - build profile 通常可复用(比如所有交叉任务都用同一台 macOS CI 机),host profile 则需按目标环境拆分(
arm64-release、x86_64-debug、win64-msvc) - profile 文件里别硬编码路径,尤其
tools.build:sysroot或tools.cmake.cmaketoolchain:generator,这些值在不同机器上可能不一致
锁文件(conan.lock)会记录两个 profile 的完整快照
当你加 --lockfile 或生成锁文件后,conan.lock 里不仅存了依赖版本,还固化了 host 和 build 两套 settings 的完整哈希。这意味着:同一份 lock 文件,在不同机器上执行 conan install --lockfile,只要 profile 名字能 resolve 到相同内容,就能复现完全一致的二进制构建结果。
容易踩的坑:
- 团队共用 lock 文件,但某人本地
defaultprofile 被改过,--profile:build=default实际指向了非预期配置 - profile 文件用了相对路径或环境变量(如
${HOME}/toolchains/gcc12-arm64),换机器就失效 - 没把 profile 文件纳入版本控制,仅靠文档说明,时间一长谁也说不清
linux-gcc12到底指哪一套设置
真正关键的不是 profile 名字,而是它展开后的 settings 完整性。名字只是入口,内容才是契约。











