conan 通过显式声明 settings(如 os、arch、compiler、build_type)区分 windows/linux/macos 构建配置,这些字段构成 package id 的核心键,决定二进制匹配与缓存行为;os 影响系统 api 宏、链接器输出(.dll/.so/.dylib)及头文件路径,且必须与远程包标签严格一致,不自动跨平台适配。

Conan 怎么用 settings 区分 Windows/Linux/macOS 构建配置
Conan 不是“写一次、到处编译”,而是靠 settings 显式声明平台差异点,让同一个 conanfile.py 或 conanfile.txt 能生成不同平台的二进制。它不猜、不默认、不妥协——你声明什么,它就按什么构建。
核心 settings 字段包括:os(Windows/Linux/macOS/FreeBSD)、arch(x86_64/armv8)、compiler(gcc/clang/msvc)、build_type(Release/Debug)。这些不是可选标签,而是 Conan 二进制缓存的 key 组成部分。
-
os影响头文件路径、系统 API 宏定义(如_WIN32或__linux__)和链接器行为(libvs.dllvs.dylib) -
compiler.version和compiler.libcxx(如libstdc++11vslibc++)决定 ABI 兼容性,混用会导致undefined symbol - Conan Center 上的预编译包名里就含
os和arch,比如fmt/10.2.1#r123@_/_:windows-x86_64-gcc-12-release
为什么 conan install 在 Linux 上能拉到 .so,在 Windows 上却只给 .lib?
这不是 Conan “做了什么”,而是它严格遵循你当前环境的 settings 并匹配远程包的可用二进制。当你在 Windows 上运行 conan install,它自动检测到 os=Windows,然后只查找标记为 os=Windows 的包;同理,Linux 下只查 os=Linux。
常见误解是“Conan 应该自动给我跨平台二进制”,但它不打包、不转换、不模拟——它只分发你明确构建或下载的产物。
- 如果某个库在 Conan Center 没有对应
os=Windows的预编译包,--build=missing会触发本地 MSVC 编译,生成.lib+.dll - 若你在 WSL 里执行
conan install,os检测为Linux,哪怕宿主是 Windows,也不会给你 Windows 二进制 - 交叉编译必须显式指定
-s os=Windows -s arch=x86_64 -s compiler=gcc,否则 Conan 不知道你要什么
profile 文件怎么避免手动传一堆 -s 参数
硬编码 -s os=... 在命令行里既易错又难复现。profile 就是把一组稳定、可复用的 settings(加 options 和 env)存成文件,比如 ~/.conan2/profiles/gcc12-debug:
include(default) [settings] os=Linux arch=x86_64 compiler=gcc compiler.version=12 compiler.libcxx=libstdc++11 build_type=Debug [options] *:shared=True [env] CC=/usr/bin/gcc-12 CXX=/usr/bin/g++-12
之后只需 conan install . -pr:b gcc12-debug -pr:h gcc12-debug(-pr:b 是 build 机 profile,-pr:h 是 host 机 profile),不用再拼参数。
- 推荐用
conan profile detect自动生成基础 profile,再手动微调compiler.version和libcxx - 不同平台应有独立 profile:比如
windows-msvc2022、macos-clang15,避免混用 - CI 中应固定 profile 文件内容,而不是依赖
detect—— CI 环境的编译器路径可能不稳定
交叉编译时 settings 和 toolchain 怎么协同
交叉编译本质是 build 机(你开发用的机器)和 host 机(目标运行机器)不一致。Conan 要求你同时提供两套 settings:-pr:b(build profile)和 -pr:h(host profile)。它据此生成 CMake toolchain 文件,确保 CMAKE_SYSTEM_NAME、CMAKE_C_COMPILER 等变量正确。
例如,从 x86_64 Linux 交叉编译到 aarch64 Android:
-
-pr:b linux-gcc12告诉 Conan:我在哪儿构建(用哪个编译器) -
-pr:h android-ndk-r25告诉 Conan:我要生成什么平台的二进制(影响os=Android、os.api_level=23等) -
CMakeToolchaingenerator 会读取-pr:h里的os和arch,自动填入android.toolchain.cmake所需字段 - 若漏掉
-pr:h,Conan 默认用-pr:b,结果就是“在 Linux 上编译出 Linux 二进制”,而非 Android
跨平台不是靠 magic 实现的,是靠每层(Conan settings → toolchain → CMake → 编译器)都对齐同一组语义明确的平台描述。一旦某一层没对齐,比如 profile 里写了 os=Windows 却在 Linux 上跑,conan install 会直接报错,而不是静默失败。











