conan create . 不自动触发 cmake 构建,仅当 conanfile.py 中 build() 方法显式调用 cmake.configure() 和 cmake.build()(或 self.run("cmake ..."))时才执行;flipper zero 的 nanopb 和 tdengine 的 fast-lzma2 均属此类实现。

conan create 怎么触发 CMake 构建流程
执行 conan create . 时,Conan 不会自动调用 CMake;它只会在 conanfile.py 中定义了 build() 方法、且该方法里显式调用了 cmake.configure() 和 cmake.build() 的前提下,才真正启动 CMake 构建。这是最常被误解的一点:Conan 本身不绑定构建系统,CMake 只是 recipe 作者选的工具。
Flipper Zero 的 nanopb 示例和 TDengine 的 fast-lzma2 都属于这类——conanfile.py 继承自 ConanFile,并在 build() 中手动初始化 CMake 对象、传入 source_folder 和 build_folder,再执行构建。
- 必须在
build()内调用self.run("cmake ...")或使用conan.tools.cmake.CMake类封装 -
configure()前需确保source()已把源码解压/拉取到指定路径 - 若依赖外部构建产物(如
protoc插件),得在build_requires中声明,否则cmake.configure()会因找不到命令失败
CMakeLists.txt 如何消费 Conan 生成的依赖信息
Conan 不修改你的 CMakeLists.txt,它只生成辅助文件(如 conan_toolchain.cmake 和 fmt-config.cmake)。你必须主动在 CMake 脚本中加载它们,否则 find_package(fmt) 会报错 “Could not find a package configuration file”。
典型写法是两步导入:
- 先
include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake),统一编译器、标准、架构等设置 - 再
find_package(fmt CONFIG REQUIRED),这里CONFIG表示走 Conan 生成的xxx-config.cmake路径,不是 CMake 自带的 FindXXX 模块 - 链接时用
target_link_libraries(myapp PRIVATE fmt::fmt),注意命名空间::是 Conan 自动生成的
为什么 conan install 后 CMake 还找不到头文件
常见错误现象:conan install .. --build=missing 成功,但 cmake .. 报 fatal error: fmt/core.h: No such file or directory。根本原因不是 Conan 没装包,而是 CMake 没被告知去哪里找头文件。
这通常由三个疏漏导致:
- 忘记在
CMakeLists.txt开头加include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake) - 执行
conan install时没指定--generator CMakeDeps(或[generators]段没写CMakeDeps),导致没生成fmt-config.cmake -
find_package(fmt)写在include()之前,顺序错乱使 toolchain 未生效
shared 选项对 CMake 链接方式的影响
像 fast-lzma2 这类包支持 shared=True/False 选项,它会直接影响 CMake 的 find_package() 行为和链接结果:
- 当
shared=False(默认),Conan 提供的是静态库,target_link_libraries()实际做归档链接,无运行时依赖 - 当
shared=True,Conan 安装的是.so/.dll/.dylib,CMake 会自动处理RPATH或DLLPATH,但你得确保目标机器有对应共享库,或打包进安装目录 - 在
conanfile.py中,options = {"shared": [True, False]}必须与 CMake 的add_library(... SHARED)或STATIC逻辑一致,否则构建会失败
最容易被忽略的是:同一个包的不同 shared 变体在 Conan 缓存中是完全隔离的,conan list "fast-lzma2/*" 会显示两个不同 package_id 条目——切勿混用。











