必须显式传入-s编译器参数,conan不会自动读取cc/cxx或cmake编译器设置;否则易导致链接失败、abi不兼容等静默问题。

conan install 时必须显式传入 -s 编译器参数
Conan 不会自动从当前 shell 环境读取 CC/CXX 或 CMake 的 CMAKE_C_COMPILER 设置。如果你只运行 conan install . --output-folder=build,它默认用 host 环境的 GCC/Clang,和你后续 cmake .. 用的编译器很可能不一致——这会导致链接失败、ABI 不兼容、std::string 崩溃等静默问题。
正确做法是让 conan install 和 cmake 使用完全相同的编译器标识:
- 用
-s compiler=gcc -s compiler.version=11 -s compiler.libcxx=libstdc++11显式声明 - 或直接引用 profile:
conan install . --profile=my-gcc-11-aarch64 --output-folder=build - 确保 profile 中的
[settings]和你 CMake 调用时的-DCMAKE_CXX_COMPILER=...指向的工具链语义一致(比如都对应 aarch64-poky-linux-g++)
profile 的 [buildenv] 和 [conf] 必须协同生效
只配 [buildenv] CC=... 不够,CMakeToolchain 生成器不会自动把环境变量转成 CMake 变量;只配 [conf] tools.cmake.cmaketoolchain:user_toolchain=... 也不行,Conan 的依赖构建阶段仍可能用错编译器。
推荐组合方式(以交叉编译为例):
-
[buildenv]设置CC、CXX、PKG_CONFIG_EXECUTABLE、PKG_CONFIG_SYSROOT_DIR—— 控制 Conan 自身构建依赖时的工具链 -
[conf]设置tools.cmake.cmaketoolchain:user_toolchain=...或tools.build:sysroot=...—— 控制 CMakeToolchain 生成的conan_toolchain.cmake内容 - 二者缺一不可:前者管“Conan 怎么编依赖”,后者管“CMake 怎么编你的项目”
CMakeLists.txt 里不能漏掉 include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake)
很多用户以为只要 conan install 成功,CMake 就能自动识别配置。实际不是——CMake 完全不知道 conan_toolchain.cmake 的存在,除非你手动 include 它。
这个 include 必须放在 project() 之后、任何 find_package() 之前,否则 CMAKE_SYSTEM_NAME、CMAKE_CXX_COMPILER 等关键变量不会被覆盖:
cmake_minimum_required(VERSION 3.15)
project(MyApp LANGUAGES CXX)
include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake) # ← 这一行不能少,也不能放错位置
find_package(fmt REQUIRED CONFIG)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE fmt::fmt)
如果跳过这步,CMake 会回退到系统默认编译器,哪怕你 profile 里写了 aarch64 工具链也没用。
混用 CMakeDeps 和 find_package 时,generator 顺序有影响
CMakeDeps 生成的 *-config.cmake 文件,其内部硬编码了 set(CMAKE_FIND_ROOT_PATH "...") 和 set(CMAKE_SYSROOT "...")。这些值来自 profile 的 [conf] tools.build:sysroot 或 user_toolchain 中定义的路径。
但如果你在 conanfile.txt 里同时写了:
[generators] CMakeToolchain CMakeDeps
注意:CMakeDeps 的生成**依赖于 CMakeToolchain 已先确定 sysroot 和架构信息**。所以必须保证 CMakeToolchain 在前,否则 CMakeDeps 生成的 config 文件里 CMAKE_SYSROOT 可能为空或错位,导致 find_package 找不到库头文件。
容易被忽略的一点:CMakeDeps 不会重新读取 profile 的 [buildenv],它只信任 [conf] 和 toolchain 传递的上下文。











