conanfile.py中requires必须写全版本和channel以确保可复现性:zlib/1.2.13@表示默认conancenter通道,避免远程搜索导致不兼容二进制或构建卡住;package()中self.copy须严格按include/lib/bin路径放置文件;cmakelists.txt需设cmake_find_package_prefer_config on并禁用系统findxxx.cmake;依赖库须通过exports_sources和cmake_layout导出cmake配置,否则下游find_package失败。

conanfile.py 中的 requires 必须写全版本和 channel
不写 channel(比如 @conancenter)或只写模糊版本(如 zlib/1.2.13 而不是 zlib/1.2.13@),Conan 会尝试远程搜索,可能匹配到不兼容的二进制,甚至卡在“找不到包”状态。尤其在 CI 环境下,缓存或索引变化会导致构建漂移。
稳妥写法是:
-
zlib/1.2.13@:末尾@显式表示使用默认 channel(conancenter),避免隐式行为 -
openssl/3.1.3@:同上,固定版本 + 默认通道 - 若依赖私有库,必须写全:
myutils/1.0.0@team/stable
package() 方法里 self.copy 必须按 Conan 约定路径放文件
Conan 包结构是硬编码识别的:include/ 放头文件,lib/ 放静态库,bin/ 放动态库或可执行文件。如果 self.copy 拷错位置(比如把头文件放进 src/ 或 share/),下游项目 find_package() 就找不到 xxxConfig.cmake,链接时直接报 undefined reference 或 Unable to find 'xxx.h'。
典型正确写法:
def package(self):
self.copy("*.h", dst="include", src="include")
self.copy("*.a", dst="lib", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
CMakeLists.txt 里不能用系统自带的 FindXXX.cmake
Conan 生成的 CMakeDeps 输出的是 xxxConfig.cmake,它和系统 /usr/share/cmake/Modules/FindXXX.cmake 是两套机制。如果 CMake 找到系统版,就会跳过 Conan 版,导致链接错误或头文件路径错乱。
必须禁用系统模块:
- 在
CMakeLists.txt开头加:set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) - 确保
find_package(fmt CONFIG REQUIRED)显式要求 Config 模式 - 不要写
find_package(fmt REQUIRED)—— 这会触发 Module 模式 fallback
依赖本身也要导出 CMake 配置(exports_sources 和 cmake_layout)
如果你的依赖库(比如你自己写的 mylib)也用 Conan 管理,但下游 find_package(mylib REQUIRED) 报错,大概率是它没导出 CMake 配置文件。Conan 不会自动帮你生成 mylibConfig.cmake,得靠你提供。
关键点:
-
exports_sources = "CMakeLists.txt", "cmake/*.cmake":把 CMake 配置文件打包进去 - 用
cmake_layout(或手动设置cpp.package.includedirs)确保头文件路径被正确注册 - 在
package_info()里显式声明:self.cpp_info.set_property("cmake_file_name", "mylib")
漏掉任意一项,下游就只能看到库文件,但找不到 find_package() 接口。











