应使用conan export-pkg而非conan create来包装现有二进制,因后者会强制执行build()导致已有产物被覆盖、构建上下文丢失;export-pkg跳过构建,仅通过conanfile.py中的package()将指定路径文件拷贝至缓存,需确保settings匹配实际编译环境且显式声明requires依赖。

直接用 conan export-pkg,别走 conan create 流程——除非你真要从源码重编,否则 conan create 会清空已有构建产物、重复执行 build(),完全违背“适配已有工程”的初衷。
为什么不能用 conan create 包装现成二进制
你本地已经有编译好的 libmylib.a、头文件在 include/、DLL 在 bin/,这些是 IDE 或手动 make 产出的成果。conan create 默认会先调用 build()(哪怕你把它写成空函数),再调用 package();而 build() 阶段 Conan 会清理构建目录、重跑 CMake/Makefile,导致:
- 已有二进制被覆盖或丢失
- 编译器/flag/宏定义等上下文丢失(IDE 自动注入的那些)
- 无法复现——因为 build() 过程不可控、不透明
conan export-pkg 的正确姿势
它跳过构建,只做两件事:读取 conanfile.py 中的 package() 逻辑,把指定路径下的文件按约定结构拷进本地缓存。关键点:
- 必须提供一个最小可用的
conanfile.py,至少含name、version、settings和package() -
package()里用self.copy()显式声明要打包的文件,路径基于当前工作目录(不是源码根目录,也不是 build 目录) - 运行命令时,当前目录需包含该
conanfile.py,且所有待打包文件路径对它可访问
示例 conanfile.py:
from conan import ConanFile
<p>class MyLibConan(ConanFile):
name = "mylib"
version = "1.2.0"
settings = "os", "arch", "compiler", "build_type"</p><pre class="brush:php;toolbar:false;">def package(self):
# 假设头文件在 ../src/include,库文件在 ../build/lib
self.copy("*.h", dst="include", src="../src/include")
self.copy("*.a", dst="lib", src="../build/lib")
self.copy("*.so", dst="lib", src="../build/lib")
self.copy("*.dll", dst="bin", src="../build/bin")
然后执行:
conan export-pkg . myuser/testing -s os=Linux -s arch=x86_64 -s compiler=gcc -s compiler.version=11 -s compiler.libcxx=libstdc++11
注意:-s 参数必须和你的二进制实际构建环境一致,否则下游消费时会匹配失败。
常见路径错位和权限坑
最容易出错的是相对路径误判:
-
self.copy("*.h", src="include")—— 这个include/是相对于conanfile.py所在目录,不是项目根目录 - 如果二进制在
../build/Release/,但你在project/下运行命令,就得写src="../build/Release/lib" - Windows 下路径分隔符不用管,
self.copy内部自动处理;但路径不存在时不会报错,只会静默跳过——建议先ls ../build/lib确认 - macOS 上动态库后缀是
.dylib,别漏掉;Linux 是.so,Windows 是.dll,三者得分开copy
另外,conan export-pkg 不校验头文件是否能被 #include 正确解析,也不检查符号导出是否完整——它只管“搬文件”。所以务必在下游项目里实际 conan install + cmake + link 跑一遍,验证 find_package(mylib) 和 target_link_libraries(... mylib::mylib) 是否真正生效。
最常被忽略的一点:export-pkg 打出来的包,requires 字段是空的,也不会触发依赖解析。如果你的库内部依赖了 zlib 或 openssl,必须在 conanfile.py 里显式写 requires = "zlib/1.2.13", "openssl/3.1.3",否则下游链接时会报 undefined reference。











