应直接使用conan export-pkg封装现有二进制,因其专为预编译文件设计,避免conan create触发冗余构建流程导致失败或缓存污染;需配对conanfile.py(含准确settings和package()中相对路径的self.copy())与二进制目录结构,并确保-s参数与实际编译环境完全一致。

直接用 conan export-pkg,别写 build() 也别跑 conan create —— 那些是为从源码构建设计的,你手头已经有二进制,走那条路纯属绕远、易出错、还污染缓存。
为什么不用 conan create
因为 conan create 会强制触发 source() → build() → package() 全流程。你本地已有 .lib、.so、.h,再让它去 clone、cmake、build 一遍,既没必要,又大概率失败(比如 CMakeLists.txt 缺失或编译器不匹配)。更关键的是:build() 阶段若被调用,Conan 会清空 build/ 目录——你辛苦编好的工件就没了。
-
conan create适合“有源码、要统一构建”的场景 - 你的情况属于“有现成二进制、要快速封装”,对应官方术语叫 Packaging Existing Binaries
- 强行套用
create会导致self.copy()在错误上下文中执行,self.build_folder可能为空,路径全错
conan export-pkg 怎么用
核心就一条命令,但必须配对使用:一个 conanfile.py 描述元信息 + 一个已知路径存放你的二进制文件。
- 先确保目录结构清晰,例如:
mylib/ ├── conanfile.py └── artifacts/ ├── include/ │ └── mylib.h ├── lib/ │ └── libmylib.a └── bin/ └── mylib.dll -
conanfile.py里只留必要字段,build()方法删掉或留空,重点写package():from conans import ConanFile <p>class MyLibConan(ConanFile): name = "mylib" version = "2.1.0" settings = "os", "arch", "compiler", "build_type"</p><h1>不要写 options/shared,除非你真要区分多配置包</h1><pre class="brush:php;toolbar:false;">def package(self): self.copy("*.h", dst="include", src="artifacts/include") self.copy("*.lib", dst="lib", src="artifacts/lib", keep_path=False) self.copy("*.a", dst="lib", src="artifacts/lib", keep_path=False) self.copy("*.dll", dst="bin", src="artifacts/bin", keep_path=False) self.copy("*.so", dst="lib", src="artifacts/lib", keep_path=False) - 在
mylib/目录下运行:conan export-pkg . myuser/testing -s os=Windows -s arch=x86_64 -s compiler=msvc -s compiler.version=193 -s compiler.runtime=dynamic -s build_type=Release
注意:
-s参数必须和你本地二进制实际编译环境完全一致,否则下游conan install时会找不到包。
容易踩的坑:路径、设置、缓存三连击
这三个点出错,export-pkg 表面成功,实际包不可用。
-
路径写错:不要用
os.path.join(self.source_folder, ...)——export-pkg不走source(),self.source_folder是空的;所有src=必须是相对于conanfile.py的相对路径(如"artifacts/include") -
settings 漏项或错配:比如 Windows 下漏掉
compiler.runtime,Linux 下漏掉os.distro(某些旧 profile 会要求),会导致生成的 package ID 和下游请求的不一致,conan install找不到包 -
没清理旧缓存就重试:Conan 不会自动覆盖同名同配置包。改完
conanfile.py后想重试,得先删掉本地缓存里的旧包:conan remove mylib/2.1.0@myuser/testing,否则export-pkg会静默跳过
真正麻烦的从来不是命令本身,而是 setting 字符串和本地二进制真实编译环境之间那几处细微差异——比如你用 MinGW-w64 编译的 .a,却传了 -s compiler=msvc,包就废了。建议把构建该二进制时用的完整命令或 CI 日志截一段,照着抄 setting。











