Skip to content

Commit 32298e3

Browse files
committed
Add manylinux2014 draft
1 parent 256f428 commit 32298e3

File tree

1 file changed

+317
-0
lines changed

1 file changed

+317
-0
lines changed

pep-9999.rst

+317
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
PEP: 9999
2+
Title: The manylinux2014 Platform Tag
3+
Version: $Revision$
4+
Last-Modified: $Date$
5+
Author: Dustin Ingram <[email protected]>
6+
BDFL-Delegate: Paul Moore <[email protected]>
7+
Discussions-To: Distutils SIG <[email protected]>
8+
Status: Active
9+
Type: Informational
10+
Content-Type: text/x-rst
11+
Created: 29-April-2019
12+
Post-History: 29-April-2019
13+
14+
15+
Abstract
16+
========
17+
18+
This PEP proposes the creation of a ``manylinux2014`` platform tag to
19+
succeed the ``manylinux2010`` tag introduced by :pep:`513`. It also
20+
proposes that PyPI and ``pip`` both be updated to support uploading,
21+
downloading, and installing ``manylinux2014`` distributions on
22+
compatible platforms.
23+
24+
Rationale
25+
=========
26+
27+
CentOS 6 is now the oldest supported CentOS release, and will receive
28+
maintenance updates through November 30th, 2020, [1]_ at which point
29+
it will reach end-of-life, and no further updates such as security
30+
patches will be made available. All wheels built under the
31+
``manylinux2010`` images will remain at obsolete versions after that
32+
point.
33+
34+
Therefore, we propose the continuation of the existing manylinux
35+
standard, and that a new PEP 425-style [2]_ platform tag called
36+
``manylinux2014`` be derived from CentOS 7 and that the ``manylinux``
37+
toolchain, PyPI, and ``pip`` be updated to support it.
38+
39+
Similar to how :pep:`571` and :pep:`513` drew allowed shared
40+
libraries and their symbol versions from CentOS 5.11 and CentOS 6,
41+
respectively, a ``manylinux2014`` platform tag will draw its libraries
42+
and symbol versions from CentOS 7, which will reach end-of-life on
43+
June 30th, 2024. [1]_
44+
45+
The ``manylinuxYYYY`` pattern has a number of advantages that motivate
46+
continuing with the current status quo:
47+
48+
- Well-defined Docker images with clearly specified compatible
49+
libraries;
50+
- No need to survey for compatibility issues across multiple releases;
51+
- A single build image and ``auditwheel`` profile per architecture.
52+
53+
There are also some disadvantages:
54+
55+
- Requires drafting a new PEP for every new standard;
56+
- Requires adding the new platform tag to installers (e.g., ``pip``);
57+
- Installers are unable to install a platform tag which predates a
58+
given release.
59+
60+
There are also challenges which would exist for any proposal,
61+
including the time and effort it takes to define, prepare and release
62+
the Docker images and corresponding ``auditwheel`` profiles. These
63+
challenges were experienced in the long rollout period for
64+
``manylinux2010``, which took approximately 1 year from PEP acceptance
65+
to compatible build environment published. [3]_
66+
67+
However, if this PEP can be an indicator, the process is now
68+
well-defined and easily repeatable, which should increase the timeline
69+
for rollout of a newer, updated platform tag.
70+
71+
The ``manylinux2014`` policy
72+
============================
73+
74+
The following criteria determine a ``linux`` wheel's eligibility for
75+
the ``manylinux2014`` tag:
76+
77+
1. The wheel may only contain binary executables and shared objects
78+
compiled for one of the following architectures supported by CentOS
79+
7, or a CentOS 7 compatible base image (such as ubi7): [4]_ ::
80+
81+
x86_64
82+
i686
83+
aarch64
84+
armhfp
85+
ppc64
86+
ppc64le
87+
s390x
88+
89+
This list adds support for ARM (aarch64, armhfp) and PowerPC
90+
(ppc64, ppc64le) architectures supported by the CentOS Alternative
91+
Architecture Special Interest Group, as well as the IBM Z (s390x)
92+
architecture. [5]_
93+
94+
2. The wheel's binary executables or shared objects may not link
95+
against externally-provided libraries except those in the following
96+
list: ::
97+
98+
libgcc_s.so.1
99+
libstdc++.so.6
100+
libm.so.6
101+
libdl.so.2
102+
librt.so.1
103+
libcrypt.so.1
104+
libc.so.6
105+
libnsl.so.1
106+
libutil.so.1
107+
libpthread.so.0
108+
libresolv.so.2
109+
libX11.so.6
110+
libXext.so.6
111+
libXrender.so.1
112+
libICE.so.6
113+
libSM.so.6
114+
libGL.so.1
115+
libgobject-2.0.so.0
116+
libgthread-2.0.so.0
117+
libglib-2.0.so.0
118+
119+
This list is identical to the externally-provided libraries
120+
allowed for ``manylinux2010``. ``libpythonX.Y`` remains ineligible
121+
for inclusion for the same reasons outlined in :pep:`513`.
122+
123+
On Debian-based systems, these libraries are provided by the
124+
packages:
125+
126+
============ =======================================================
127+
Package Libraries
128+
============ =======================================================
129+
libc6 libdl.so.2, libresolv.so.2, librt.so.1, libc.so.6,
130+
libpthread.so.0, libm.so.6, libutil.so.1, libcrypt.so.1,
131+
libnsl.so.1
132+
libgcc1 libgcc_s.so.1
133+
libgl1 libGL.so.1
134+
libglib2.0-0 libgobject-2.0.so.0, libgthread-2.0.so.0, libglib-2.0.so.0
135+
libice6 libICE.so.6
136+
libsm6 libSM.so.6
137+
libstdc++6 libstdc++.so.6
138+
libx11-6 libX11.so.6
139+
libxext6 libXext.so.6
140+
libxrender1 libXrender.so.1
141+
============ =======================================================
142+
143+
On RPM-based systems, they are provided by these packages:
144+
145+
============ =======================================================
146+
Package Libraries
147+
============ =======================================================
148+
glib2 libglib-2.0.so.0, libgthread-2.0.so.0, libgobject-2.0.so.0
149+
glibc libresolv.so.2, libutil.so.1, libnsl.so.1, librt.so.1,
150+
libcrypt.so.1, libpthread.so.0, libdl.so.2, libm.so.6,
151+
libc.so.6
152+
libICE libICE.so.6
153+
libX11 libX11.so.6
154+
libXext: libXext.so.6
155+
libXrender libXrender.so.1
156+
libgcc: libgcc_s.so.1
157+
libstdc++ libstdc++.so.6
158+
mesa libGL.so.1
159+
============ =======================================================
160+
161+
3. If the wheel contains binary executables or shared objects linked
162+
against any allowed libraries that also export versioned symbols,
163+
they may only depend on the following maximum versions::
164+
165+
GLIBC_2.17
166+
CXXABI_1.3.7
167+
GLIBCXX_3.4.19
168+
GCC_4.8.5
169+
170+
As an example, ``manylinux2014`` wheels may include binary
171+
artifacts that require ``glibc`` symbols at version ``GLIBC_2.12``,
172+
because this an earlier version than the maximum of ``GLIBC_2.17``.
173+
4. If a wheel is built for any version of CPython 2 or CPython
174+
versions 3.0 up to and including 3.2, it *must* include a CPython
175+
ABI tag indicating its Unicode ABI. A ``manylinux2014`` wheel
176+
built against Python 2, then, must include either the ``cpy27mu``
177+
tag indicating it was built against an interpreter with the UCS-4
178+
ABI or the ``cpy27m`` tag indicating an interpreter with the UCS-2
179+
ABI. [6]_ [7]_
180+
5. A wheel *must not* require the ``PyFPE_jbuf`` symbol. This is
181+
achieved by building it against a Python compiled *without* the
182+
``--with-fpectl`` ``configure`` flag.
183+
184+
Compilation of Compliant Wheels
185+
===============================
186+
187+
Like ``manylinux1``, the ``auditwheel`` tool adds ``manylinux2014``
188+
platform tags to ``linux`` wheels built by ``pip wheel`` or
189+
``bdist_wheel`` in a ``manylinux2014`` Docker container.
190+
191+
Docker Images
192+
-------------
193+
194+
A ``manylinux2014`` Docker image based on CentOS 7 x86_64 is provided
195+
for building binary ``linux`` wheels that can reliably be converted to
196+
``manylinux2014`` wheels. [8]_ This image comes with a full compiler
197+
suite installed (``gcc``, ``g++``, and ``gfortran`` 4.8.5) as well as
198+
the latest releases of Python and ``pip``.
199+
200+
Compatibility with kernels that lack ``vsyscall``
201+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202+
203+
Similar to CentOS 6, CentOS 7 includes a version of ``glibc`` that
204+
depends on the ``vsyscall`` page. As described in :pep:`571`, this
205+
breaks the assumption that a Docker containers userland is compatible
206+
wtih its host's kernel. Similar to ``manylinux2010``, Docker images
207+
for ``manylinux2014`` require patching ``glibc`` to remove all
208+
dependencies on ``vsyscall`` in the version of ``glibc`` included with
209+
our Docker image.
210+
211+
Auditwheel
212+
----------
213+
214+
The ``auditwheel`` tool has also been updated to produce
215+
``manylinux2014`` wheels. [9]_ Its behavior and purpose are otherwise
216+
unchanged from :pep:`513`.
217+
218+
Platform Detection for Installers
219+
=================================
220+
221+
Platforms may define a ``manylinux2014_compatible`` boolean attribute
222+
on the ``_manylinux`` module described in :pep:`513`. A platform is
223+
considered incompatible with ``manylinux2014`` if the attribute is
224+
``False``.
225+
226+
If the ``_manylinux`` module is not found, or it does not have the
227+
attribute ``manylinux2014_compatible``, tools may fall back to
228+
checking for glibc. If the platform has glibc 2.17 or newer, it is
229+
assumed to be compatible unless the ``_manylinux`` module says
230+
otherwise.
231+
232+
Specifically, the algorithm we propose is::
233+
234+
def is_manylinux2014_compatible():
235+
# Only Linux, and only supported architectures
236+
from distutils.util import get_platform
237+
238+
if get_platform() not in [
239+
"linux-x86_64",
240+
"linux-i686",
241+
"linux-aarch64",
242+
"linux-armhfp",
243+
"linux-ppc64",
244+
"linux-ppc64le",
245+
"linux-s390x",
246+
]:
247+
return False
248+
249+
# Check for presence of _manylinux module
250+
try:
251+
import _manylinux
252+
253+
return bool(_manylinux.manylinux2014_compatible)
254+
except (ImportError, AttributeError):
255+
# Fall through to heuristic check below
256+
pass
257+
258+
# Check glibc version. CentOS 7 uses glibc 2.17.
259+
# PEP 513 contains an implementation of this function.
260+
return have_compatible_glibc(2, 17)
261+
262+
Backwards compatibility with ``manylinux2010`` wheels
263+
=====================================================
264+
265+
As explained in :pep:`513`, the specified symbol versions for
266+
``manylinux1`` allowed libraries constitute an *upper bound*. The
267+
same is true for the symbol versions defined for ``manylinux2014`` in
268+
this PEP. As a result, ``manylinux1`` and ``manylinux2010`` wheels
269+
are considered ``manylinux2014`` wheels. A ``pip`` that recognizes
270+
the ``manylinux2014`` platform tag will thus install ``manylinux2010``
271+
wheels for ``manylinux2014`` platforms -- even when explicitly set --
272+
when no ``manylinux2014`` wheels are available.
273+
274+
PyPI Support
275+
============
276+
277+
PyPI should permit wheels containing the ``manylinux2014`` platform
278+
tag to be uploaded in the same way that it permits ``manylinux2010``.
279+
It should not attempt to verify the compatibility of ``manylinux2014``
280+
wheels.
281+
282+
References
283+
==========
284+
285+
.. [1] CentOS Product Specifications
286+
(https://wiki.centos.org/About/Product)
287+
.. [2] PEP 425 -- Compatibility Tags for Built Distributions
288+
(https://www.python.org/dev/peps/pep-0425/)
289+
.. [3] Tracking issue for manylinux2010 rollout
290+
(https://github.com/pypa/manylinux/issues/179)
291+
.. [4] Red Hat Universal Base Image 7
292+
(https://access.redhat.com/containers/?tab=overview#/registry.access.redhat.com/ubi7)
293+
(https://wiki.centos.org/SpecialInterestGroup/AltArch)
294+
.. [5] The CentOS Alternative Architecture Special Interest Group
295+
(https://wiki.centos.org/SpecialInterestGroup/AltArch)
296+
.. [6] PEP 3149
297+
https://www.python.org/dev/peps/pep-3149/
298+
.. [7] SOABI support for Python 2.X and PyPy
299+
https://github.com/pypa/pip/pull/3075
300+
.. [8] manylinux2014 Docker images
301+
(https://quay.io/repository/pypa/manylinux2014_x86_64)
302+
.. [9] auditwheel
303+
(https://github.com/pypa/auditwheel/)
304+
305+
Copyright
306+
=========
307+
308+
This document has been placed into the public domain.
309+
310+
..
311+
Local Variables:
312+
mode: indented-text
313+
indent-tabs-mode: nil
314+
sentence-end-double-space: t
315+
fill-column: 70
316+
coding: utf-8
317+
End:

0 commit comments

Comments
 (0)