PEP 599 – manylinux2014 平台标签
- 作者:
- Dustin Ingram <di at python.org>
- 发起人:
- Paul Moore <p.f.moore at gmail.com>
- BDFL 委托:
- Paul Moore <p.f.moore at gmail.com>
- 讨论至:
- Discourse 帖子
- 状态:
- 已取代
- 类型:
- 信息性
- 主题:
- 打包
- 创建日期:
- 2019年4月29日
- 发布历史:
- 2019年4月29日
- 取代者:
- 600
- 决议:
- Discourse 消息
摘要
本 PEP 提议创建 manylinux2014 平台标签,以接替由 PEP 513 引入的 manylinux2010 标签。它还提议更新 PyPI 和 pip,以支持在兼容平台上上传、下载和安装 manylinux2014 发行版。
基本原理
CentOS 6 现为支持的最早 CentOS 版本,并将持续维护更新至 2020 年 11 月 30 日 [1],届时将停止支持,不再提供安全补丁等更新。在此之后,在 manylinux2010 镜像下构建的所有 wheel 将保持过时版本。
因此,我们提议延续现有 manylinux 标准,并从 CentOS 7 派生一个新的 PEP 425 样式平台标签,命名为 manylinux2014,并更新 manylinux 工具链、PyPI 和 pip 以支持它。
与 PEP 571 和 PEP 513 分别从 CentOS 5.11 和 CentOS 6 中提取允许的共享库及其符号版本类似,manylinux2014 平台标签将从 CentOS 7 中提取其库和符号版本,CentOS 7 将于 2024 年 6 月 30 日停止支持。[1]
manylinuxYYYY 模式具有许多优点,促使我们继续保持现状
- 定义明确的 Docker 镜像,具有明确指定的兼容库;
- 无需调查跨多个版本的兼容性问题;
- 每个架构一个构建镜像和
auditwheel配置文件。
也存在一些缺点
- 每个新标准都需要起草新的 PEP;
- 需要将新平台标签添加到安装程序(例如,
pip); - 安装程序无法安装早于给定发行版的平台标签。
任何提案都将面临挑战,包括定义、准备和发布 Docker 镜像及相应的 auditwheel 配置文件所需的时间和精力。这些挑战在 manylinux2010 的漫长推广期中已经经历过,从 PEP 接受到兼容构建环境发布大约花费了 1 年时间。[3]
然而,如果此 PEP 能够成为一个指示器,那么该过程现在已经明确定义且易于重复,这应该会加快新更新平台标签的推广时间。
manylinux2014 策略
以下标准决定了 linux wheel 是否符合 manylinux2014 标签的条件
- 该 wheel 只能包含为 CentOS 7 或 CentOS 7 兼容基础镜像(例如 ubi7)支持的以下架构之一编译的二进制可执行文件和共享对象:[4]
x86_64 i686 aarch64 armv7l ppc64 ppc64le s390x
此列表增加了对 CentOS 替代架构特别兴趣小组支持的 ARMv7 (armv7l)、ARMv8 (aarch64) 和 PowerPC (ppc64, ppc64le) 架构以及 IBM Z (s390x) 架构的支持。[5]
- 该 wheel 的二进制可执行文件或共享对象不得链接到外部提供的库,除非是以下列表中的库
libgcc_s.so.1 libstdc++.so.6 libm.so.6 libdl.so.2 librt.so.1 libc.so.6 libnsl.so.1 libutil.so.1 libpthread.so.0 libresolv.so.2 libX11.so.6 libXext.so.6 libXrender.so.1 libICE.so.6 libSM.so.6 libGL.so.1 libgobject-2.0.so.0 libgthread-2.0.so.0 libglib-2.0.so.0
此列表与最初允许用于
manylinux2010的外部提供的库相同,但有一个例外:libcrypt.so.1已被移除,因为它在 Fedora 30 中已被弃用。libpythonX.Y仍然不符合包含条件,原因与 PEP 513 中所述相同。在基于 Debian 的系统上,这些库由以下软件包提供
软件包 库 libc6 libdl.so.2, libresolv.so.2, librt.so.1, libc.so.6, libpthread.so.0, libm.so.6, libutil.so.1, libnsl.so.1 libgcc1 libgcc_s.so.1 libgl1 libGL.so.1 libglib2.0-0 libgobject-2.0.so.0, libgthread-2.0.so.0, libglib-2.0.so.0 libice6 libICE.so.6 libsm6 libSM.so.6 libstdc++6 libstdc++.so.6 libx11-6 libX11.so.6 libxext6 libXext.so.6 libxrender1 libXrender.so.1 在基于 RPM 的系统上,它们由这些软件包提供
软件包 库 glib2 libglib-2.0.so.0, libgthread-2.0.so.0, libgobject-2.0.so.0 glibc libresolv.so.2, libutil.so.1, libnsl.so.1, librt.so.1, libpthread.so.0, libdl.so.2, libm.so.6, libc.so.6 libICE libICE.so.6 libX11 libX11.so.6 libXext libXext.so.6 libXrender libXrender.so.1 libgcc libgcc_s.so.1 libstdc++ libstdc++.so.6 mesa libGL.so.1 - 如果 wheel 包含链接到任何允许的库(也导出版本化符号)的二进制可执行文件或共享对象,它们只能依赖于以下最大版本
GLIBC_2.17 CXXABI_1.3.7, CXXABI_TM_1 is also allowed GLIBCXX_3.4.19 GCC_4.8.0
例如,
manylinux2014wheel 可以包含需要glibc符号版本GLIBC_2.12的二进制工件,因为这比最大版本GLIBC_2.17早。 - 如果一个 wheel 是为任何版本的 CPython 2 或 CPython 3.0 到 3.2 版本(含)构建的,它必须包含一个 CPython ABI 标签,指示其 Unicode ABI。因此,针对 Python 2 构建的
manylinux2014wheel 必须包含cpy27mu标签(表示它是针对 UCS-4 ABI 解释器构建的)或cpy27m标签(表示它是针对 UCS-2 ABI 解释器构建的)。(PEP 3149 [7]) - 一个 wheel 不得要求
PyFPE_jbuf符号。这通过在编译 Python 时不使用--with-fpectlconfigure标志来实现。
兼容 Wheel 的编译
与 manylinux1 类似,auditwheel 工具将 manylinux2014 平台标签添加到在 manylinux2014 Docker 容器中由 pip wheel 或 bdist_wheel 构建的 linux wheel。
Docker 镜像
应提供基于 CentOS 7 x86_64 的 manylinux2014 Docker 镜像,用于构建可可靠转换为 manylinux2014 wheel 的二进制 linux wheel。此镜像将预装完整的编译器套件(gcc、g++ 和 gfortran 4.8.5)以及最新版本的 Python 和 pip。
Auditwheel
auditwheel 工具也将更新以生成 manylinux2014 wheel。[8] 其行为和目的将与 PEP 513 保持不变。
安装程序的平台检测
平台可以在 PEP 513 中描述的 _manylinux 模块上定义一个 manylinux2014_compatible 布尔属性。如果该属性为 False,则认为该平台与 manylinux2014 不兼容。
如果找不到 _manylinux 模块,或者它没有 manylinux2014_compatible 属性,工具可以回退到检查 glibc。如果平台具有 glibc 2.17 或更高版本,则假定它兼容,除非 _manylinux 模块另有说明。
具体来说,我们提议的算法是
def is_manylinux2014_compatible():
# Only Linux, and only supported architectures
from distutils.util import get_platform
if get_platform() not in [
"linux-x86_64",
"linux-i686",
"linux-aarch64",
"linux-armv7l",
"linux-ppc64",
"linux-ppc64le",
"linux-s390x",
]:
return False
# Check for presence of _manylinux module
try:
import _manylinux
return bool(_manylinux.manylinux2014_compatible)
except (ImportError, AttributeError):
# Fall through to heuristic check below
pass
# Check glibc version. CentOS 7 uses glibc 2.17.
# PEP 513 contains an implementation of this function.
return have_compatible_glibc(2, 17)
与 manylinux2010 wheel 的向后兼容性
正如 PEP 513 中所解释的,manylinux1 允许的库的指定符号版本构成一个上限。本 PEP 中为 manylinux2014 定义的符号版本也是如此。因此,manylinux1 和 manylinux2010 wheel 被视为 manylinux2014 wheel。因此,识别 manylinux2014 平台标签的 pip 将为 manylinux2014 平台安装 manylinux2010 wheel——即使明确设置——当没有 manylinux2014 wheel 可用时。
PyPI 支持
PyPI 应该允许包含 manylinux2014 平台标签的 wheel 上传,就像它允许 manylinux2010 一样。
如果技术上可行,PyPI 应尝试验证 manylinux2014 wheel 的兼容性,但该功能并非采纳本 PEP 的必要条件。
软件包作者不应上传不符合规范的 manylinux2014 wheel 到 PyPI,并且应注意 PyPI 可能会开始阻止上传不符合规范的 wheel。
参考资料
接受
版权
本文档置于公共领域或 CC0-1.0-Universal 许可证下,以更宽松者为准。
来源: https://github.com/python/peps/blob/main/peps/pep-0599.rst
最后修改: 2025-02-01 08:59:27 GMT