本地Conan仓有缓存还是触发了源码构建

问题描述

整包构建报错

libsoc_adapter/1.100.26@openubmc/stable: WARN: Trying to remove corrupted source folder
libsoc_adapter/1.100.26@openubmc/stable: WARN: This can take a while for big packages
libsoc_adapter/1.100.26@openubmc/stable: Calling source() in /root/.conan2/p/libso691bd631b8c34/s
ERROR:  
        KeyError: 'pwd'

本地仓有缓存为什么还是触发了源码构建?

# conan list libsoc_adapter
Found 1 pkg/version recipes matching libsoc_adapter in local cache
Local Cache
  libsoc_adapter
    libsoc_adapter/1.100.26@openubmc/stable

环境信息

  • 操作系统:Ubuntu 24.04

  • 软件版本:OpenUBMC2512

答案内容由AI生成,仅供参考:

本地Conan缓存存在但为何仍触发源码构建问题分析

问题概述

在构建过程中,尽管本地Conan缓存中已存在 libsoc_adapter/1.100.26@openubmc/stable 包,系统却仍然触发了源码构建流程(即调用 source() 方法),并最终报错:

ERROR: KeyError: 'pwd'

这表明虽然包存在于本地缓存中,但Conan并未直接使用已构建的二进制包,而是尝试重新拉取源码进行构建。


原因分析

1. 缓存不完整或源码目录已损坏

根据日志:

libsoc_adapter/1.100.26@openubmc/stable: WARN: Trying to remove corrupted source folder

表明Conan检测到该包的源码目录(s文件夹)已损坏或不一致,因此主动清理并尝试重新执行 source() 方法获取源码。

说明:Conan缓存中即使有二进制包(p文件夹),若源码部分损坏,某些构建流程仍可能触发重拉源码,尤其是当构建配置发生变化或依赖校验失败时。


2. 构建配置(Profile / Settings)不匹配导致无法复用缓存

Conan为每个包维护多个二进制变体,依据以下关键参数生成唯一标识:

  • 编译器(compiler)
  • 编译器版本(version)
  • 架构(architecture)
  • 构建类型(build_type)
  • 其他选项(options)

如果当前构建环境的 profile 或 settings 与先前构建 libsoc_adapter 时不同,Conan将认为现有缓存不可用,进而尝试从源码重建。

虽然包名存在,但对应的二进制包(package_id)可能并不存在于本地缓存中。


3. source() 方法中存在运行时逻辑错误——KeyError: ‘pwd’

报错 KeyError: 'pwd' 表示在 conanfile.pysource() 方法中,尝试访问 self.pwdos.environ['pwd'] 等不存在的属性或环境变量。

常见原因包括:

  • 错误地使用 self.pwd(应使用 os.getcwd()
  • 使用了已被废弃的Conan 1.x API,而在Conan 2.x中移除
  • source() 中依赖外部脚本或环境变量未正确设置

:light_bulb: 提示:Conan 2.x 已弃用部分旧API,迁移过程中若组件未适配,可能导致此类问题。


4. 缓存中的包是“配方”而非“完整二进制包”

conan list libsoc_adapter 仅显示存在 recipe(配方),不代表存在可复用的二进制包(binary package)。

可通过以下命令确认是否存在可用的二进制包:

conan list "libsoc_adapter/1.100.26@openubmc/stable" --format=json
# 或检查具体路径
ls ~/.conan2/p/libso691bd631b8c34/p/

若无 p 目录或为空,则表示只有配方缓存,没有构建产物,必然触发源码构建。


解决方案

:white_check_mark: 方案一:清除损坏缓存并重新下载

由于缓存可能已损坏,建议清除后重新拉取:

# 清除本地缓存(Conan 2.x)
rm -rf ~/.conan2/p/libso*

# 从远程仓库重新下载完整包
conan download libsoc_adapter/1.100.26@openubmc/stable -r openubmc_opensource

确保远程 openubmc_opensource 可访问,可通过 conan remote list 验证。


:white_check_mark: 方案二:检查并统一构建环境配置

确保当前构建使用的 profile 与二进制包构建时一致:

# 查看当前默认 profile
conan profile show default

# 使用指定 profile 构建(推荐与项目匹配)
conan build -pr:h=your-profile.txt

建议使用项目提供的标准 profile 文件,避免因配置差异导致重建。


:white_check_mark: 方案三:验证并修复组件的 conanfile.py

检查 libsoc_adapter 组件的 conanfile.pysource() 方法是否包含非法调用,例如:

def source(self):
    # ❌ 错误写法(self.pwd 通常不存在)
    # os.chdir(self.pwd)

    # ✅ 正确写法
    os.chdir(os.getcwd())

如发现使用了已废弃的属性或环境变量,需联系组件维护者更新至 Conan 2.x 兼容版本。


:white_check_mark: 方案四:强制跳过源码构建(仅用于调试)

若确定不需要重新构建,可临时跳过源码拉取阶段:

# 使用 --no-download-source 跳过 source() 执行(视版本支持情况)
# 或在构建命令中指定不从源构建
bingo build --no_cache  # 清除缓存后重试

更推荐使用 --update_conan_cache 强制刷新依赖:

bingo build -ucc

预防建议

建议 说明
:white_check_mark: 定期维护 Conan 缓存 使用 conan cache clean "*" 定期清理无效缓存
:white_check_mark: 使用统一构建环境 所有开发者采用相同的 Conan profile 和 toolchain
:white_check_mark: 组件适配 Conan 2.x 避免使用已废弃 API,确保 source()build() 方法健壮
:white_check_mark: 自动化构建前清理 CI/CD 流程中加入缓存校验与修复机制

结论

尽管 libsoc_adapter 包存在于本地缓存中,但由于 源码目录损坏构建配置不匹配,Conan 判定现有缓存不可用,因此触发 source() 方法试图重建。然而,由于 source() 方法中存在 KeyError: 'pwd' 运行时错误,导致构建失败。

:white_check_mark: 根本解决步骤

  1. 清除损坏缓存:rm -rf ~/.conan2/p/libso*
  2. 重新下载完整包:conan download libsoc_adapter/... -r openubmc_opensource
  3. 检查并修复 conanfile.py 中的 source() 方法逻辑错误

如此可避免重复触发不必要的源码构建,恢复正常的缓存复用行为。

一个recipe(构建脚本)会构建出 n个package,你查的只是本地的recipe,有recipe只是表示找到了构建脚本,缺少package说明你当前的构建参数、SDK版本、编译器等发生变更,依赖的package找不到。

按之前的经验,大概有以下几个原因:

  1. bmc_sdk不匹配,导致工具或conan包不匹配。
  2. 远程仓配置错误,需要与bmc_sdk匹配,可以使用conan remote相关命令查看、修改conan仓。

环境1(下图左边):

仓库分支

manifest$ git branch 
* 25.12_2026.12.31_LTS
  main

构建情况

2512 LTS的manifest+高可用组件直接构建使用的libsoc_adapter,整包构建通过
该libsoc_adapter是iBMC300_5.12.0.1_debug.tar.gz导入的
revisions
81ae90285357ea5b05237410662816eb (2025-12-23 07:04:09 UTC)
packages
60537f7cd075307ad1be3c796ad4633b31e03ae2

环境2(下图右边):

仓库分支

account$ git branch 
* 25.12_2026.12.31_LTS
  main
manifest$ git branch 
* 25.12_2026.12.31_LTS
  main

构建情况

2512 LTS对应的account组件(1.101.3)构建时使用的libsoc_adapter,组件构建通过
该libsoc_adapter是openubmc_sdk仓的
revisions
344352ceafab8e9641ac6dd85a80f9e0 (2026-02-24 04:23:35 UTC)
packages
96d92ecd6fcbe66042797a0a737123ba0af3da92
再构建2512 LTS的manifest+高可用组件,整包构建不通过


看起来是找错了revisions


请教下这个问题需要如何解决?

本地存在正确的reversionId情况下,可以在manifest.yml中指定版本:libsoc_adapter/1.100.26@openubmc/stable#{reversion_id}

指定revision可以解决。
account构建和整包构建依赖不同revision的libsoc_adapter会有问题吗?

可以在/output/graph.info中查找下account组件的reversion_id验证是否用的是之前构建的版本。

是同一个,aea92f0849a8984cfd8328486aa9fb19

Local Cache
  account
    account/1.100.34@openubmc/rc
      revisions
        aea92f0849a8984cfd8328486aa9fb19 (2026-03-12 09:01:25 UTC)
            "130": {
                "ref": "account/1.100.34@openubmc/rc#aea92f0849a8984cfd8328486aa9fb19",
                "id": "130",
                "recipe": "Cache",
                "package_id": "86691710ba2fa61642e91cffe06065ead43b89fc",
                "prev": "a5d784b4708e6b3ca46a9721f31bf6de",
                "rrev": "aea92f0849a8984cfd8328486aa9fb19",
                "rrev_timestamp": 1773306085.9159148,
                "prev_timestamp": 1773320485.336947,

整包和组件使用的libsoc_adapter不一致会导致缺包问题。建议在account组件中以同样方式指定libsoc_adapter版本后重新构建,并使用该版本整包构建