conanfile.py 是 cmake 项目的推荐选择,因其支持条件依赖、动态生成配置、运行时调试及 ci 细粒度控制,而 conanfile.txt 仅支持静态声明,灵活性与确定性均不足。

conanfile.py 是 CMake 项目的推荐选择
对大多数 CMake 项目来说,conanfile.py 不只是“适合”,而是更可控、更可维护的默认方案。它比 conanfile.txt 多出的 Python 表达能力,在真实项目中几乎总是用得上。
什么时候 conanfile.py 能解决 conanfile.txt 搞不定的问题
你遇到以下任一情况时,conanfile.txt 就会明显力不从心:
-
conan install报错ConanException: No conanfile.py or conanfile.txt found,但文件明明存在——大概率是路径不对,而conanfile.py可通过self.settings.os == "Windows"主动适配不同平台的依赖逻辑,减少因路径/环境差异引发的误操作 - 需要为 Debug/Release 构建使用不同版本的工具依赖(比如只在 Release 下用
cmake/3.22.6,Debug 下用本地cmake)——conanfile.txt完全无法表达这种条件分支 - 依赖项要按编译器类型启用:例如
self.settings.compiler == "gcc"时加libbacktrace/1.0,Clang 下跳过——这只能靠requirements()方法里的 Python 判断实现 - 你想在
generate()中动态生成 toolchain 文件内容(比如注入自定义CMAKE_MODULE_PATH),或调用CMakeToolchain的variables字典做微调——conanfile.txt没有执行上下文
conanfile.py 和 CMake 集成的关键实操点
不是写完就完事;几个容易被忽略但直接影响构建成败的细节:
CMake 4.3.2 Windows x86_64 历史版本安装包,适合旧项目兼容、构建环境回退、CMakeLists.txt 迁移验证、Visual Studio/Ninja/Makefile 生成器测试和 C/C++ 项目维护。
-
generators声明必须显式写成generators = "CMakeDeps", "CMakeToolchain",不能漏掉任一;少一个,find_package(fmt CONFIG REQUIRED)就会失败 -
CMakeLists.txt中include()的路径必须和conan install --output-folder=build的输出位置严格匹配,常见错误是写成${CMAKE_BINARY_DIR}/conan_toolchain.cmake,但实际路径是${CMAKE_BINARY_DIR}/generators/conan_toolchain.cmake -
self.requires("fmt/10.2.1@")末尾的@不能省——它表示使用默认 channel(conancenter),否则 Conan 会尝试远程搜索模糊匹配,CI 环境下极易超时或拉错二进制 - 如果项目含子模块(如
libs/utils),不要在每个子目录放独立conanfile.py;整个项目应只有一个顶层conanfile.py,子模块的依赖由 CMake 的add_subdirectory()和target_link_libraries()统一承接
性能与可复现性差异其实很小,但行为确定性差很多
conanfile.py 启动时多一次 Python 解析,但耗时可忽略;真正影响构建稳定的是它的确定性:
-
conanfile.txt所有字段都是静态字符串,Conan 2.x 会把它内部转成等效的conanfile.py再执行——等于多绕一层,且无法干预转换逻辑 -
conanfile.py中的def requirements(self):是运行时调用,你可以加print()或日志,调试依赖解析过程;conanfile.txt出问题只能靠猜 - CI 流水线里,
conanfile.py支持if self.conf.get("tools.build:skip_deps", default=False):这类细粒度控制,而conanfile.txt完全没这个能力
复杂点不在语法,而在依赖决策是否暴露给开发者——conanfile.py 把控制权交还给你,而不是让 Conan 在背后替你做决定。










