在Yocto Mickledore中升级Python至3.12引发python3-distutils依赖错误
问题背景
我在Yocto Mickledore镜像中需要使用Python 3.12,但Yocto Mickledore默认仅包含Python 3.11。因此我从OpenEmbedded层的Scarthgap分支复制了meta/recipes-devtools/python/*到自己的Mickledore层,并在local.conf中配置了PREFERRED_VERSION_python3 = "3.12.%"。随后出现如下警告与错误:
WARNING: preferred version 3.12.% of python3 not available (for item python3-distutils)
WARNING: versions of python3 available: 3.11.5
WARNING: preferred version 3.12.% of python3 not available (for item python3-smtpd)
WARNING: versions of python3 available: 3.11.5
WARNING: preferred version 3.12.% of python3 not available (for item python3-distutils-windows)
WARNING: versions of python3 available: 3.11.5...
ERROR: Multiple versions of python3 are due to be built (/home//yocto//recipes-python/packages-python3.12/python3_3.12.11.bb /home/***/yocto/layers/poky/meta/recipes-devtools/python/python3_3.11.5.bb). Only one version of a given PN should be built in any given build. You likely need to set PREFERRED_VERSION_python3 to select the correct version or don't depend on multiple versions.
已知distutils已从Python 3.12中移除,但部分配方仍可能依赖它,需要排查依赖链并修复不兼容的配方。
一、解决Python多版本冲突问题
- 调整层优先级:在
bblayers.conf中将你的自定义层放在poky层之前,确保Yocto优先加载你复制的Python 3.12配方,而非默认的3.11版本。 - 清理构建缓存:执行以下命令彻底清除Python 3的旧构建状态,避免缓存干扰:
bitbake -c cleansstate python3 bitbake -c cleanall python3 - 完善版本配置:在
local.conf中补充native环境的版本指定,确保构建工具链也同步使用3.12:PREFERRED_VERSION_python3 = "3.12.%" PREFERRED_VERSION_python3-native = "3.12.%"
二、排查并修复distutils依赖问题
- 定位依赖包:通过以下命令找出所有直接依赖
python3-distutils的配方:# 生成依赖图后查找 bitbake -g <你的镜像名称> grep -r "python3-distutils" pn-buildlist # 或通过包数据工具查找 oe-pkgdata-util find-path /usr/lib/python3.*/distutils - 逐个适配依赖:
- 替换为setuptools:Python 3.12后distutils的核心功能已被setuptools继承,修改目标配方的
DEPENDS或RDEPENDS字段,将python3-distutils替换为python3-setuptools。 - 单独封装distutils:如果某些配方必须依赖原始distutils结构,可以创建
python3-distutils_*.bb配方,让它依赖python3-setuptools,并通过软链接将setuptools中的distutils映射到系统路径:ln -sf ${libdir}/python${PYTHON_MAJMIN}/site-packages/setuptools/_distutils ${libdir}/python${PYTHON_MAJMIN}/distutils - 移除无效依赖:检查配方是否真的需要distutils,部分旧配方可能残留了不必要的依赖,直接删除即可。
- 替换为setuptools:Python 3.12后distutils的核心功能已被setuptools继承,修改目标配方的
三、处理其他Python 3.12不兼容配方
- 适配smtpd依赖:Python 3.12中
smtpd模块被移除,替代方案是aiosmtpd。修改依赖配方的DEPENDS/RDEPENDS为python3-aiosmtpd,若无需该功能则直接从镜像中排除相关包。 - 批量兼容性检查:执行
bitbake --dry-run <你的镜像名称>列出所有待构建包,对照Python 3.12的官方变更文档(移除模块、API调整等),逐个排查并修复不兼容的配方。 - 同步Scarthgap分支修复:除了Python核心配方,Scarthgap分支中可能还有其他适配3.12的补丁,同步相关层中的修复到你的自定义层,减少手动适配工作量。
内容的提问来源于stack exchange,提问作者Thugmek

