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 派生一个名为 manylinux2014
的新的 PEP 425 样式平台标签,并更新 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
例如,
manylinux2014
wheel 可以包含需要版本为GLIBC_2.12
的glibc
符号的二进制构件,因为这早于GLIBC_2.17
的最大值。 - 如果为任何版本的 CPython 2 或 CPython 3.0 及包括 3.2 的版本构建 wheel,则 *必须* 包含一个指示其 Unicode ABI 的 CPython ABI 标签。然后,针对 Python 2 构建的
manylinux2014
wheel 必须包含cpy27mu
标签(表示它针对具有 UCS-4 ABI 的解释器构建)或cpy27m
标签(表示具有 UCS-2 ABI 的解释器)。(PEP 3149 [7]) - wheel *不得* 要求使用
PyFPE_jbuf
符号。这是通过针对 *不带*--with-fpectl
configure
标志编译的 Python 进行构建来实现的。
兼容 Wheel 的编译
与 manylinux1
一样,auditwheel
工具会将 manylinux2014
平台标签添加到由 pip wheel
或 bdist_wheel
在 manylinux2014
Docker 容器中构建的 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
轮子被认为是manylinux2014
轮子。因此,识别manylinux2014
平台标签的pip
将安装manylinux2010
轮子到manylinux2014
平台 - 即使显式设置 - 当没有可用的manylinux2014
轮子时。
PyPI 支持
PyPI 应该允许上传包含manylinux2014
平台标签的轮子,就像允许manylinux2010
一样。
如果技术上可行,PyPI 应该尝试验证manylinux2014
轮子的兼容性,但此功能不是采用本 PEP 的必要条件。
软件包作者不应将不兼容的manylinux2014
轮子上传到 PyPI,并且应该意识到 PyPI 可能会开始阻止上传不兼容的轮子。
参考文献
接受
版权
本文档置于公共领域或根据 CC0-1.0-Universal 许可证,以两者中较宽松者为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0599.rst