conan export-pkg 误包文件包括构建中间产物(.o、CMakeCache.txt)、调试符号(.pdb、.dSYM)、recipe 文件(conanfile.py)、未显式指定的 LICENSE 及因 self.copy() 路径错误引入的无关文件。

conan export-pkg 时哪些文件会被误包进去
直接用 conan export-pkg 打包现有二进制时,Conan 不会自动过滤“不该进包”的内容——它只按你 package() 方法里写的 self.copy() 路径来搬运。常见误包包括:
-
build/或out/目录下的中间产物(如.o、.obj、CMakeCache.txt) - 调试符号文件(
.pdb、.dSYM),除非你明确需要分发调试版且已用self.cpp_info.debug区分 - 源码树根目录下的
conanfile.py或CMakeLists.txt—— 它们属于 recipe,不是二进制工件 - 第三方许可证的副本(如
LICENSE)若未显式self.copy("LICENSE", dst="licenses"),就不会进包;但若你复制了整个src/目录,它就可能混进去
package() 方法中 self.copy() 的路径陷阱
self.copy() 的 src 参数是相对路径起点,容易因当前工作目录或 layout 设置错位而多拷、少拷或越界。典型问题:
- 写
self.copy("*.h", src=".", dst="include")→ 可能把test/下的头文件也拖进来 - 没设
keep_path=False,导致src/foo/bar.h变成include/foo/bar.h,破坏 include 路径一致性 - 用通配符
"*"匹配目录时(如self.copy("*", src="bin", dst="bin")),若bin/下有子目录含构建脚本,也会被一并打包 - Linux 下忽略大小写风险:写
"*.SO"会漏掉.so,但 Conan 默认不区分大小写匹配,实际行为依赖底层 OS 文件系统
conanfile.py 中 package_id() 对打包内容的隐性影响
package_id() 不控制“打包什么”,但它决定“这个包是否该被复用”。如果它把不该参与 hash 的字段(比如 self.settings.compiler.version)纳入计算,而你又用 export-pkg 打了一个只适配 GCC 12 的二进制,那在 GCC 13 环境下 Conan 就找不到匹配包——结果用户被迫重编译,或者手动覆盖 package_id() 导致二进制被错误复用。关键点:
- 对 pre-built 二进制,
package_id()应严格反映其真实构建环境:必须包含os、arch、compiler、build_type,缺一不可 - 不要在
package_id()里调用self.info.options去剔除选项,除非你 100% 确认该二进制对所有选项变体都兼容(极少见) - 若二进制是跨平台通用的(如纯 C 静态库 + no-rtti),可显式清空部分 settings:
del self.info.settings.compiler,但必须同步文档说明限制
导出包前没清理 build 缓存的风险
用 conan export-pkg 时,Conan 默认不会清空你本地 build 目录。这意味着:
- 上一次失败构建残留的
libhello_d.a可能被误打包进 release 包 - IDE 自动生成的
cmake-build-debug/下的libhello.so若路径没排除,会覆盖你本意要导出的 release 版本 - Windows 下
vc143.pdb和vc142.pdb可能共存,self.copy("*.pdb")会全扫进去,增大包体积且混淆调试信息 - 推荐做法:导出前先确认
build_folder是干净的,或改用--build-folder显式指定一个临时路径,避免污染
最常被忽略的是 package_id() 和实际二进制 ABI 兼容范围之间的 gap:你打包了一个 GCC 11 编译的 .so,却在 package_id() 里删掉了 compiler.version,Conan 就会把它当成 GCC 12 可用的包——运行时报 undefined symbol 时,很难回溯到这个配置偏差。


















