Skip to content

Commit a5edd3d

Browse files
dincoghlan
authored andcommitted
PEP 599: manylinux2014 PEP (#1121)
Updated manylinux baseline, to be considered in combination with the (competing/complementary?) perennial manylinux proposal in PEP 600.
1 parent 455f8e4 commit a5edd3d

File tree

2 files changed

+317
-1
lines changed

2 files changed

+317
-1
lines changed

pep-0566.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ PEP: 566
22
Title: Metadata for Python Software Packages 2.1
33
Version: $Revision$
44
Last-Modified: $Date$
5-
Author: Dustin Ingram <di@di.codes>
5+
Author: Dustin Ingram <di@python.org>
66
BDFL-Delegate: Daniel Holth
77
Discussions-To: distutils-sig <distutils-sig at python.org>
88
Status: Final

pep-0599.rst

+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
PEP: 599
2+
Title: The manylinux2014 Platform Tag
3+
Version: $Revision$
4+
Last-Modified: $Date$
5+
Author: Dustin Ingram <[email protected]>
6+
Sponsor: Paul Moore <[email protected]>
7+
BDFL-Delegate: Paul Moore <[email protected]>
8+
Discussions-To: https://discuss.python.org/t/the-next-manylinux-specification/
9+
Status: Draft
10+
Type: Informational
11+
Content-Type: text/x-rst
12+
Created: 29-April-2019
13+
Post-History: 29-April-2019
14+
15+
16+
Abstract
17+
========
18+
19+
This PEP proposes the creation of a ``manylinux2014`` platform tag to
20+
succeed the ``manylinux2010`` tag introduced by :pep:`513`. It also
21+
proposes that PyPI and ``pip`` both be updated to support uploading,
22+
downloading, and installing ``manylinux2014`` distributions on
23+
compatible platforms.
24+
25+
Rationale
26+
=========
27+
28+
CentOS 6 is now the oldest supported CentOS release, and will receive
29+
maintenance updates through November 30th, 2020, [1]_ at which point
30+
it will reach end-of-life, and no further updates such as security
31+
patches will be made available. All wheels built under the
32+
``manylinux2010`` images will remain at obsolete versions after that
33+
point.
34+
35+
Therefore, we propose the continuation of the existing manylinux
36+
standard, and that a new PEP 425-style [2]_ platform tag called
37+
``manylinux2014`` be derived from CentOS 7 and that the ``manylinux``
38+
toolchain, PyPI, and ``pip`` be updated to support it.
39+
40+
Similar to how :pep:`571` and :pep:`513` drew allowed shared
41+
libraries and their symbol versions from CentOS 5.11 and CentOS 6,
42+
respectively, a ``manylinux2014`` platform tag will draw its libraries
43+
and symbol versions from CentOS 7, which will reach end-of-life on
44+
June 30th, 2024. [1]_
45+
46+
The ``manylinuxYYYY`` pattern has a number of advantages that motivate
47+
continuing with the current status quo:
48+
49+
- Well-defined Docker images with clearly specified compatible
50+
libraries;
51+
- No need to survey for compatibility issues across multiple releases;
52+
- A single build image and ``auditwheel`` profile per architecture.
53+
54+
There are also some disadvantages:
55+
56+
- Requires drafting a new PEP for every new standard;
57+
- Requires adding the new platform tag to installers (e.g., ``pip``);
58+
- Installers are unable to install a platform tag which predates a
59+
given release.
60+
61+
There are also challenges which would exist for any proposal,
62+
including the time and effort it takes to define, prepare and release
63+
the Docker images and corresponding ``auditwheel`` profiles. These
64+
challenges were experienced in the long rollout period for
65+
``manylinux2010``, which took approximately 1 year from PEP acceptance
66+
to compatible build environment published. [3]_
67+
68+
However, if this PEP can be an indicator, the process is now
69+
well-defined and easily repeatable, which should increase the timeline
70+
for rollout of a newer, updated platform tag.
71+
72+
The ``manylinux2014`` policy
73+
============================
74+
75+
The following criteria determine a ``linux`` wheel's eligibility for
76+
the ``manylinux2014`` tag:
77+
78+
1. The wheel may only contain binary executables and shared objects
79+
compiled for one of the following architectures supported by CentOS
80+
7, or a CentOS 7 compatible base image (such as ubi7): [4]_ ::
81+
82+
x86_64
83+
i686
84+
aarch64
85+
armhfp
86+
ppc64
87+
ppc64le
88+
s390x
89+
90+
This list adds support for ARM (aarch64, armhfp) and PowerPC
91+
(ppc64, ppc64le) architectures supported by the CentOS Alternative
92+
Architecture Special Interest Group, as well as the IBM Z (s390x)
93+
architecture. [5]_
94+
95+
2. The wheel's binary executables or shared objects may not link
96+
against externally-provided libraries except those in the following
97+
list: ::
98+
99+
libgcc_s.so.1
100+
libstdc++.so.6
101+
libm.so.6
102+
libdl.so.2
103+
librt.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+
originally allowed for ``manylinux2010``, with one exception:
121+
``libcrypt.so.1`` was removed due to being deprecated in Fedora 30.
122+
``libpythonX.Y`` remains ineligible for inclusion for the same
123+
reasons outlined in :pep:`513`.
124+
125+
On Debian-based systems, these libraries are provided by the
126+
packages:
127+
128+
============ =======================================================
129+
Package Libraries
130+
============ =======================================================
131+
libc6 libdl.so.2, libresolv.so.2, librt.so.1, libc.so.6,
132+
libpthread.so.0, libm.so.6, libutil.so.1, libnsl.so.1
133+
libgcc1 libgcc_s.so.1
134+
libgl1 libGL.so.1
135+
libglib2.0-0 libgobject-2.0.so.0, libgthread-2.0.so.0, libglib-2.0.so.0
136+
libice6 libICE.so.6
137+
libsm6 libSM.so.6
138+
libstdc++6 libstdc++.so.6
139+
libx11-6 libX11.so.6
140+
libxext6 libXext.so.6
141+
libxrender1 libXrender.so.1
142+
============ =======================================================
143+
144+
On RPM-based systems, they are provided by these packages:
145+
146+
============ =======================================================
147+
Package Libraries
148+
============ =======================================================
149+
glib2 libglib-2.0.so.0, libgthread-2.0.so.0, libgobject-2.0.so.0
150+
glibc libresolv.so.2, libutil.so.1, libnsl.so.1, librt.so.1,
151+
libpthread.so.0, libdl.so.2, libm.so.6, 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 should be
195+
provided for building binary ``linux`` wheels that can reliably be
196+
converted to ``manylinux2014`` wheels. This image will come with a
197+
full compiler suite installed (``gcc``, ``g++``, and ``gfortran``
198+
4.8.5) as well as 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 will also be updated to produce
215+
``manylinux2014`` wheels. [8]_ Its behavior and purpose will be
216+
otherwise 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] auditwheel
301+
(https://github.com/pypa/auditwheel/)
302+
303+
Copyright
304+
=========
305+
306+
This document is placed in the public domain or under the
307+
CC0-1.0-Universal license, whichever is more permissive.
308+
309+
..
310+
Local Variables:
311+
mode: indented-text
312+
indent-tabs-mode: nil
313+
sentence-end-double-space: t
314+
fill-column: 70
315+
coding: utf-8
316+
End:

0 commit comments

Comments
 (0)