conan 2.x 中 conanfile.py 必须继承首字母大写 f 的 conanfile 类,大小写敏感;错误写成 conanfile(小写 f)会导致 typeerror 或静默失败,且 ide 自动补全易误导。

conanfile.py 必须继承 ConanFile,不能写成 Conanfile
大小写敏感是第一个也是最容易翻车的点。IDE 自动补全常弹出 Conanfile(小写 f),但 Conan 2.x 只认 ConanFile(大写 F)。一旦写错,运行 conan create 会直接报 TypeError: class must inherit from ConanFile 或静默失败——因为 Python 把它当普通类,Conan 根本不识别。
验证方式很简单:
- 执行
python -c "from conan import ConanFile; print('OK')"确保模块可导入 - 在类定义行手动敲一遍:
class MyLib(ConanFile):,别依赖补全 - 检查 IDE 是否把
ConanFile标为未解析——那是警告信号
用 cmake_layout() 而不是手写 self.folders 路径逻辑
自己拼 self.folders.build、self.folders.generators 容易出错,且和 Conan 内部路径约定冲突。比如旧写法里把 generators 放到 build 下,新版 Conan 2.30+ 会报 Generator folder not found。
cmake_layout(self) 是官方推荐的“默认布局”,它自动按标准结构组织:
-
build/→ 构建输出目录(含 CMake 缓存、中间文件) -
generators/→CMakeToolchain.cmake、conan_deps.cmake等生成文件 -
source/→ 源码副本(由exports_sources复制而来) -
package/→ 最终打包内容(头文件、库、cmake config)
只需在 layout() 方法里写一行:cmake_layout(self),不用再算相对路径或硬编码 os.path.join。
头文件库要显式清空 libdirs 和 bindirs
像 rapidjson、fmt 这类纯头文件库,如果漏掉这步,下游 CMake 项目会错误地尝试链接不存在的 .a 或 .so,报 target not found 或 undefined reference。
必须在 package_info() 中明确设置:
def package_info(self):
self.cpp_info.bindirs = []
self.cpp_info.libdirs = []
self.cpp_info.includedirs = ["include"]
注意:不要只设 libdirs = None —— Conan 会把它当默认值处理;必须赋空列表 []。
依赖声明优先用 requires(),别混用 tool_requires() 和 build_requires()
Conan 2.x 已废弃 build_requires,统一用 tool_requires() 声明构建期工具(如 cmake、ninja)。但很多人仍习惯性写 self.build_requires("cmake/3.22.6"),结果工具根本没注入到环境里,generate() 阶段调用 cmake 就报 command not found。
正确写法分两层:
- 运行时/链接期依赖 →
self.requires("openssl/3.3.1") - 构建工具依赖 →
self.tool_requires("cmake/3.22.6")
还有一个隐藏坑:tool_requires 不会自动暴露给下游包,除非你在 generators 里显式启用 CMakeToolchain 并确保它被 generate() 调用。
最易被忽略的其实是 no_copy_source = True 的适用场景——它只对头文件库安全;一旦项目含 .cpp 文件却开了这个,build() 阶段就找不到源码,编译直接中断。这个布尔值不是“越快越好”,而是“非必要不加”。











