CINXE.COM
PEP 571 – The manylinux2010 Platform Tag | peps.python.org
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="color-scheme" content="light dark"> <title>PEP 571 – The manylinux2010 Platform Tag | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0571/"> <link rel="stylesheet" href="../_static/style.css" type="text/css"> <link rel="stylesheet" href="../_static/mq.css" type="text/css"> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light"> <link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark"> <link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss"> <meta property="og:title" content='PEP 571 – The manylinux2010 Platform Tag | peps.python.org'> <meta property="og:description" content="This PEP proposes the creation of a manylinux2010 platform tag to succeed the manylinux1 tag introduced by PEP 513. It also proposes that PyPI and pip both be updated to support uploading, downloading, and installing manylinux2010 distributions on comp..."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0571/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="This PEP proposes the creation of a manylinux2010 platform tag to succeed the manylinux1 tag introduced by PEP 513. It also proposes that PyPI and pip both be updated to support uploading, downloading, and installing manylinux2010 distributions on comp..."> <meta name="theme-color" content="#3776ab"> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> <title>Following system colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="9"></circle> <path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all"> <title>Selected dark colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all"> <title>Selected light colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> </svg> <script> document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto" </script> <section id="pep-page-section"> <header> <h1>Python Enhancement Proposals</h1> <ul class="breadcrumbs"> <li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li> <li><a href="../pep-0000/">PEP Index</a> » </li> <li>PEP 571</li> </ul> <button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())"> <svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg> <span class="visually-hidden">Toggle light / dark / auto colour theme</span> </button> </header> <article> <section id="pep-content"> <h1 class="page-title">PEP 571 – The manylinux2010 Platform Tag</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Mark Williams <mrw at enotuniq.org>, Geoffrey Thomas <geofft at ldpreload.com>, Thomas Kluyver <thomas at kluyver.me.uk></dd> <dt class="field-even">BDFL-Delegate<span class="colon">:</span></dt> <dd class="field-even">Alyssa Coghlan <ncoghlan at gmail.com></dd> <dt class="field-odd">Discussions-To<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="https://mail.python.org/archives/list/distutils-sig@python.org/">Distutils-SIG list</a></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Replaced by another succeeding PEP">Superseded</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd> <dt class="field-even">Topic<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="../topic/packaging/">Packaging</a></dd> <dt class="field-odd">Created<span class="colon">:</span></dt> <dd class="field-odd">05-Feb-2018</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even"><p></p></dd> <dt class="field-odd">Superseded-By<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="../pep-0600/">600</a></dd> <dt class="field-even">Resolution<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="https://mail.python.org/pipermail/distutils-sig/2018-April/032156.html">Distutils-SIG message</a></dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#the-manylinux2010-policy">The <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> policy</a></li> <li><a class="reference internal" href="#compilation-of-compliant-wheels">Compilation of Compliant Wheels</a><ul> <li><a class="reference internal" href="#docker-image">Docker Image</a><ul> <li><a class="reference internal" href="#compatibility-with-kernels-that-lack-vsyscall">Compatibility with kernels that lack <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code></a></li> </ul> </li> <li><a class="reference internal" href="#auditwheel">Auditwheel</a></li> </ul> </li> <li><a class="reference internal" href="#platform-detection-for-installers">Platform Detection for Installers</a></li> <li><a class="reference internal" href="#backwards-compatibility-with-manylinux1-wheels">Backwards compatibility with <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheels</a></li> <li><a class="reference internal" href="#pypi-support">PyPI Support</a></li> <li><a class="reference internal" href="#summary-of-changes-to-pep-571">Summary of changes to PEP 571</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP proposes the creation of a <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> platform tag to succeed the <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> tag introduced by <a class="pep reference internal" href="../pep-0513/" title="PEP 513 – A Platform Tag for Portable Linux Built Distributions">PEP 513</a>. It also proposes that PyPI and <code class="docutils literal notranslate"><span class="pre">pip</span></code> both be updated to support uploading, downloading, and installing <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> distributions on compatible platforms.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>True to its name, the <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> platform tag has made the installation of binary extension modules a reality on many Linux systems. Libraries like <code class="docutils literal notranslate"><span class="pre">cryptography</span></code> <a class="footnote-reference brackets" href="#id21" id="id1">[2]</a> and <code class="docutils literal notranslate"><span class="pre">numpy</span></code> <a class="footnote-reference brackets" href="#id22" id="id2">[3]</a> are more accessible to Python developers now that their installation on common architectures does not depend on fragile development environments and build toolchains.</p> <p><code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheels achieve their portability by allowing the extension modules they contain to link against only a small set of system-level shared libraries that export versioned symbols old enough to benefit from backwards-compatibility policies. Extension modules in a <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheel that rely on <code class="docutils literal notranslate"><span class="pre">glibc</span></code>, for example, must be built against version 2.5 or earlier; they may then be run systems that provide more recent <code class="docutils literal notranslate"><span class="pre">glibc</span></code> version that still export the required symbols at version 2.5.</p> <p><a class="pep reference internal" href="../pep-0513/" title="PEP 513 – A Platform Tag for Portable Linux Built Distributions">PEP 513</a> drew its whitelisted shared libraries and their symbol versions from CentOS 5.11, which was the oldest supported CentOS release at the time of its writing. Unfortunately, CentOS 5.11 reached its end-of-life on March 31st, 2017 with a clear warning against its continued use. <a class="footnote-reference brackets" href="#id23" id="id3">[4]</a> No further updates, such as security patches, will be made available. This means that its packages will remain at obsolete versions that hamper the efforts of Python software packagers who use the <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> Docker image.</p> <p>CentOS 6 is now the oldest supported CentOS release, and will receive maintenance updates through November 30th, 2020. <a class="footnote-reference brackets" href="#id24" id="id4">[5]</a> We propose that a new <a class="pep reference internal" href="../pep-0425/" title="PEP 425 – Compatibility Tags for Built Distributions">PEP 425</a>-style platform tag called <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> be derived from CentOS 6 and that the <code class="docutils literal notranslate"><span class="pre">manylinux</span></code> toolchain, PyPI, and <code class="docutils literal notranslate"><span class="pre">pip</span></code> be updated to support it.</p> <p>This was originally proposed as <code class="docutils literal notranslate"><span class="pre">manylinux2</span></code>, but the versioning has been changed to use calendar years (also known as CalVer <a class="footnote-reference brackets" href="#id39" id="id5">[22]</a>). This makes it easier to define future <em>manylinux</em> tags out of order: for example, a hypothetical <code class="docutils literal notranslate"><span class="pre">manylinux2017</span></code> standard may be defined via a new PEP before <code class="docutils literal notranslate"><span class="pre">manylinux2014</span></code>, or a <code class="docutils literal notranslate"><span class="pre">manylinux2007</span></code> standard might be defined that targets systems older than this PEP but newer than <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code>.</p> <p>Calendar versioning also gives a rough idea of which Linux distribution versions support which tag: <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> will work on most distribution versions released since 2010. This is only an approximation, however: the actual compatibility rules are defined below, and some newer distributions may not meet them.</p> </section> <section id="the-manylinux2010-policy"> <h2><a class="toc-backref" href="#the-manylinux2010-policy" role="doc-backlink">The <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> policy</a></h2> <p>The following criteria determine a <code class="docutils literal notranslate"><span class="pre">linux</span></code> wheel’s eligibility for the <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> tag:</p> <ol class="arabic"> <li>The wheel may only contain binary executables and shared objects compiled for one of the two architectures supported by CentOS 6: x86_64 or i686. <a class="footnote-reference brackets" href="#id24" id="id6">[5]</a></li> <li>The wheel’s binary executables or shared objects may not link against externally-provided libraries except those in the following whitelist:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">libgcc_s</span><span class="o">.</span><span class="n">so</span><span class="mf">.1</span> <span class="n">libstdc</span><span class="o">++.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libm</span><span class="o">.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libdl</span><span class="o">.</span><span class="n">so</span><span class="mf">.2</span> <span class="n">librt</span><span class="o">.</span><span class="n">so</span><span class="mf">.1</span> <span class="n">libc</span><span class="o">.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libnsl</span><span class="o">.</span><span class="n">so</span><span class="mf">.1</span> <span class="n">libutil</span><span class="o">.</span><span class="n">so</span><span class="mf">.1</span> <span class="n">libpthread</span><span class="o">.</span><span class="n">so</span><span class="mf">.0</span> <span class="n">libresolv</span><span class="o">.</span><span class="n">so</span><span class="mf">.2</span> <span class="n">libX11</span><span class="o">.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libXext</span><span class="o">.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libXrender</span><span class="o">.</span><span class="n">so</span><span class="mf">.1</span> <span class="n">libICE</span><span class="o">.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libSM</span><span class="o">.</span><span class="n">so</span><span class="mf">.6</span> <span class="n">libGL</span><span class="o">.</span><span class="n">so</span><span class="mf">.1</span> <span class="n">libgobject</span><span class="o">-</span><span class="mf">2.0</span><span class="o">.</span><span class="n">so</span><span class="mf">.0</span> <span class="n">libgthread</span><span class="o">-</span><span class="mf">2.0</span><span class="o">.</span><span class="n">so</span><span class="mf">.0</span> <span class="n">libglib</span><span class="o">-</span><span class="mf">2.0</span><span class="o">.</span><span class="n">so</span><span class="mf">.0</span> </pre></div> </div> <p>This list is identical to the externally-provided libraries whitelisted for <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code>, minus <code class="docutils literal notranslate"><span class="pre">libncursesw.so.5</span></code> and <code class="docutils literal notranslate"><span class="pre">libpanelw.so.5</span></code>. <a class="footnote-reference brackets" href="#id25" id="id7">[7]</a> <code class="docutils literal notranslate"><span class="pre">libpythonX.Y</span></code> remains ineligible for inclusion for the same reasons outlined in <a class="pep reference internal" href="../pep-0513/" title="PEP 513 – A Platform Tag for Portable Linux Built Distributions">PEP 513</a>.</p> <p><code class="docutils literal notranslate"><span class="pre">libcrypt.so.1</span></code> was retrospectively removed from the whitelist after Fedora 30 was released with <code class="docutils literal notranslate"><span class="pre">libcrypt.so.2</span></code> instead.</p> <p>On Debian-based systems, these libraries are provided by the packages:</p> <table class="docutils align-default"> <thead> <tr class="row-odd"><th class="head">Package</th> <th class="head">Libraries</th> </tr> </thead> <tbody> <tr class="row-even"><td>libc6</td> <td>libdl.so.2, libresolv.so.2, librt.so.1, libc.so.6, libpthread.so.0, libm.so.6, libutil.so.1, libnsl.so.1</td> </tr> <tr class="row-odd"><td>libgcc1</td> <td>libgcc_s.so.1</td> </tr> <tr class="row-even"><td>libgl1</td> <td>libGL.so.1</td> </tr> <tr class="row-odd"><td>libglib2.0-0</td> <td>libgobject-2.0.so.0, libgthread-2.0.so.0, libglib-2.0.so.0</td> </tr> <tr class="row-even"><td>libice6</td> <td>libICE.so.6</td> </tr> <tr class="row-odd"><td>libsm6</td> <td>libSM.so.6</td> </tr> <tr class="row-even"><td>libstdc++6</td> <td>libstdc++.so.6</td> </tr> <tr class="row-odd"><td>libx11-6</td> <td>libX11.so.6</td> </tr> <tr class="row-even"><td>libxext6</td> <td>libXext.so.6</td> </tr> <tr class="row-odd"><td>libxrender1</td> <td>libXrender.so.1</td> </tr> </tbody> </table> <p>On RPM-based systems, they are provided by these packages:</p> <table class="docutils align-default"> <thead> <tr class="row-odd"><th class="head">Package</th> <th class="head">Libraries</th> </tr> </thead> <tbody> <tr class="row-even"><td>glib2</td> <td>libglib-2.0.so.0, libgthread-2.0.so.0, libgobject-2.0.so.0</td> </tr> <tr class="row-odd"><td>glibc</td> <td>libresolv.so.2, libutil.so.1, libnsl.so.1, librt.so.1, libpthread.so.0, libdl.so.2, libm.so.6, libc.so.6</td> </tr> <tr class="row-even"><td>libICE</td> <td>libICE.so.6</td> </tr> <tr class="row-odd"><td>libX11</td> <td>libX11.so.6</td> </tr> <tr class="row-even"><td>libXext:</td> <td>libXext.so.6</td> </tr> <tr class="row-odd"><td>libXrender</td> <td>libXrender.so.1</td> </tr> <tr class="row-even"><td>libgcc:</td> <td>libgcc_s.so.1</td> </tr> <tr class="row-odd"><td>libstdc++</td> <td>libstdc++.so.6</td> </tr> <tr class="row-even"><td>mesa</td> <td>libGL.so.1</td> </tr> </tbody> </table> </li> <li>If the wheel contains binary executables or shared objects linked against any whitelisted libraries that also export versioned symbols, they may only depend on the following maximum versions:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">GLIBC_2</span><span class="mf">.12</span> <span class="n">CXXABI_1</span><span class="mf">.3.3</span> <span class="n">GLIBCXX_3</span><span class="mf">.4.13</span> <span class="n">GCC_4</span><span class="mf">.5.0</span> </pre></div> </div> <p>As an example, <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels may include binary artifacts that require <code class="docutils literal notranslate"><span class="pre">glibc</span></code> symbols at version <code class="docutils literal notranslate"><span class="pre">GLIBC_2.4</span></code>, because this an earlier version than the maximum of <code class="docutils literal notranslate"><span class="pre">GLIBC_2.12</span></code>.</p> </li> <li>If a wheel is built for any version of CPython 2 or CPython versions 3.0 up to and including 3.2, it <em>must</em> include a CPython ABI tag indicating its Unicode ABI. A <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheel built against Python 2, then, must include either the <code class="docutils literal notranslate"><span class="pre">cpy27mu</span></code> tag indicating it was built against an interpreter with the UCS-4 ABI or the <code class="docutils literal notranslate"><span class="pre">cpy27m</span></code> tag indicating an interpreter with the UCS-2 ABI. (<a class="pep reference internal" href="../pep-3149/" title="PEP 3149 – ABI version tagged .so files">PEP 3149</a>, <a class="footnote-reference brackets" href="#id26" id="id8">[9]</a>)</li> <li>A wheel <em>must not</em> require the <code class="docutils literal notranslate"><span class="pre">PyFPE_jbuf</span></code> symbol. This is achieved by building it against a Python compiled <em>without</em> the <code class="docutils literal notranslate"><span class="pre">--with-fpectl</span></code> <code class="docutils literal notranslate"><span class="pre">configure</span></code> flag.</li> </ol> </section> <section id="compilation-of-compliant-wheels"> <h2><a class="toc-backref" href="#compilation-of-compliant-wheels" role="doc-backlink">Compilation of Compliant Wheels</a></h2> <p>Like <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code>, the <code class="docutils literal notranslate"><span class="pre">auditwheel</span></code> tool adds <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> platform tags to <code class="docutils literal notranslate"><span class="pre">linux</span></code> wheels built by <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">wheel</span></code> or <code class="docutils literal notranslate"><span class="pre">bdist_wheel</span></code> in a <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> Docker container.</p> <section id="docker-image"> <h3><a class="toc-backref" href="#docker-image" role="doc-backlink">Docker Image</a></h3> <p>Two <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> Docker images based on CentOS 6 are provided for building binary <code class="docutils literal notranslate"><span class="pre">linux</span></code> wheels that can reliably be converted to <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels. <a class="footnote-reference brackets" href="#id27" id="id9">[10]</a> The x86_64 and i686 images comes with a new compiler suite installed (<code class="docutils literal notranslate"><span class="pre">gcc</span></code>, <code class="docutils literal notranslate"><span class="pre">g++</span></code>, and <code class="docutils literal notranslate"><span class="pre">gfortran</span></code> from <code class="docutils literal notranslate"><span class="pre">devtoolset-8</span></code>) as well as the latest releases of Python and <code class="docutils literal notranslate"><span class="pre">pip</span></code>.</p> <section id="compatibility-with-kernels-that-lack-vsyscall"> <h4><a class="toc-backref" href="#compatibility-with-kernels-that-lack-vsyscall" role="doc-backlink">Compatibility with kernels that lack <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code></a></h4> <p>A Docker container assumes that its userland is compatible with its host’s kernel. Unfortunately, an increasingly common kernel configuration breaks this assumption for x86_64 CentOS 6 Docker images.</p> <p>Versions 2.14 and earlier of <code class="docutils literal notranslate"><span class="pre">glibc</span></code> require the kernel provide an archaic system call optimization known as <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> on x86_64. <a class="footnote-reference brackets" href="#id28" id="id10">[11]</a> To effect the optimization, the kernel maps a read-only page of frequently-called system calls – most notably <code class="docutils literal notranslate"><span class="pre">time(2)</span></code> – into each process at a fixed memory location. <code class="docutils literal notranslate"><span class="pre">glibc</span></code> then invokes these system calls by dereferencing a function pointer to the appropriate offset into the <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> page and calling it. This avoids the overhead associated with invoking the kernel that affects normal system call invocation. <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> has long been deprecated in favor of an equivalent mechanism known as vDSO, or “virtual dynamic shared object”, in which the kernel instead maps a relocatable virtual shared object containing the optimized system calls into each process. <a class="footnote-reference brackets" href="#id29" id="id11">[12]</a></p> <p>The <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> page has serious security implications because it does not participate in address space layout randomization (ASLR). Its predictable location and contents make it a useful source of gadgets used in return-oriented programming attacks. <a class="footnote-reference brackets" href="#id30" id="id12">[13]</a> At the same time, its elimination breaks the x86_64 ABI, because <code class="docutils literal notranslate"><span class="pre">glibc</span></code> versions that depend on <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> suffer from segmentation faults when attempting to dereference a system call pointer into a non-existent page. As a compromise, Linux 3.1 implemented an “emulated” <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> that reduced the executable code, and thus the material for ROP gadgets, mapped into the process. <a class="footnote-reference brackets" href="#id31" id="id13">[14]</a> <code class="docutils literal notranslate"><span class="pre">vsyscall=emulated</span></code> has been the default configuration in most distribution’s kernels for many years.</p> <p>Unfortunately, <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> emulation still exposes predictable code at a reliable memory location, and continues to be useful for return-oriented programming. <a class="footnote-reference brackets" href="#id32" id="id14">[15]</a> Because most distributions have now upgraded to <code class="docutils literal notranslate"><span class="pre">glibc</span></code> versions that do not depend on <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code>, they are beginning to ship kernels that do not support <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> at all. <a class="footnote-reference brackets" href="#id33" id="id15">[16]</a></p> <p>CentOS 5.11 and 6 both include versions of <code class="docutils literal notranslate"><span class="pre">glibc</span></code> that depend on the <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> page (2.5 and 2.12.2 respectively), so containers based on either cannot run under kernels provided with many distribution’s upcoming releases. <a class="footnote-reference brackets" href="#id34" id="id16">[17]</a> If Travis CI, for example, begins running jobs under a kernel that does not provide the <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> interface, Python packagers will not be able to use our Docker images there to build <code class="docutils literal notranslate"><span class="pre">manylinux</span></code> wheels. <a class="footnote-reference brackets" href="#id35" id="id17">[18]</a></p> <p>We have derived a patch from the <code class="docutils literal notranslate"><span class="pre">glibc</span></code> git repository that backports the removal of all dependencies on <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> to the version of <code class="docutils literal notranslate"><span class="pre">glibc</span></code> included with our <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> image. <a class="footnote-reference brackets" href="#id36" id="id18">[19]</a> Rebuilding <code class="docutils literal notranslate"><span class="pre">glibc</span></code>, and thus building <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> image itself, still requires a host kernel that provides the <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> mechanism, but the resulting image can be both run on hosts that provide it and those that do not. Because the <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> interface is an optimization that is only applied to running processes, the <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels built with this modified image should be identical to those built on an unmodified CentOS 6 system. Also, the <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code> problem applies only to x86_64; it is not part of the i686 ABI.</p> </section> </section> <section id="auditwheel"> <h3><a class="toc-backref" href="#auditwheel" role="doc-backlink">Auditwheel</a></h3> <p>The <code class="docutils literal notranslate"><span class="pre">auditwheel</span></code> tool has also been updated to produce <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels. <a class="footnote-reference brackets" href="#id37" id="id19">[20]</a> Its behavior and purpose are otherwise unchanged from <a class="pep reference internal" href="../pep-0513/" title="PEP 513 – A Platform Tag for Portable Linux Built Distributions">PEP 513</a>.</p> </section> </section> <section id="platform-detection-for-installers"> <h2><a class="toc-backref" href="#platform-detection-for-installers" role="doc-backlink">Platform Detection for Installers</a></h2> <p>Platforms may define a <code class="docutils literal notranslate"><span class="pre">manylinux2010_compatible</span></code> boolean attribute on the <code class="docutils literal notranslate"><span class="pre">_manylinux</span></code> module described in <a class="pep reference internal" href="../pep-0513/" title="PEP 513 – A Platform Tag for Portable Linux Built Distributions">PEP 513</a>. A platform is considered incompatible with <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> if the attribute is <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p> <p>If the <code class="docutils literal notranslate"><span class="pre">_manylinux</span></code> module is not found, or it does not have the attribute <code class="docutils literal notranslate"><span class="pre">manylinux2010_compatible</span></code>, tools may fall back to checking for glibc. If the platform has glibc 2.12 or newer, it is assumed to be compatible unless the <code class="docutils literal notranslate"><span class="pre">_manylinux</span></code> module says otherwise.</p> <p>Specifically, the algorithm we propose is:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">is_manylinux2010_compatible</span><span class="p">():</span> <span class="c1"># Only Linux, and only x86-64 / i686</span> <span class="kn">from</span> <span class="nn">distutils.util</span> <span class="kn">import</span> <span class="n">get_platform</span> <span class="k">if</span> <span class="n">get_platform</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"linux-x86_64"</span><span class="p">,</span> <span class="s2">"linux-i686"</span><span class="p">]:</span> <span class="k">return</span> <span class="kc">False</span> <span class="c1"># Check for presence of _manylinux module</span> <span class="k">try</span><span class="p">:</span> <span class="kn">import</span> <span class="nn">_manylinux</span> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">_manylinux</span><span class="o">.</span><span class="n">manylinux2010_compatible</span><span class="p">)</span> <span class="k">except</span> <span class="p">(</span><span class="ne">ImportError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">):</span> <span class="c1"># Fall through to heuristic check below</span> <span class="k">pass</span> <span class="c1"># Check glibc version. CentOS 6 uses glibc 2.12.</span> <span class="c1"># PEP 513 contains an implementation of this function.</span> <span class="k">return</span> <span class="n">have_compatible_glibc</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">12</span><span class="p">)</span> </pre></div> </div> </section> <section id="backwards-compatibility-with-manylinux1-wheels"> <h2><a class="toc-backref" href="#backwards-compatibility-with-manylinux1-wheels" role="doc-backlink">Backwards compatibility with <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheels</a></h2> <p>As explained in <a class="pep reference internal" href="../pep-0513/" title="PEP 513 – A Platform Tag for Portable Linux Built Distributions">PEP 513</a>, the specified symbol versions for <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> whitelisted libraries constitute an <em>upper bound</em>. The same is true for the symbol versions defined for <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> in this PEP. As a result, <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheels are considered <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels. A <code class="docutils literal notranslate"><span class="pre">pip</span></code> that recognizes the <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> platform tag will thus install <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheels for <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> platforms – even when explicitly set – when no <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels are available. <a class="footnote-reference brackets" href="#id38" id="id20">[21]</a></p> </section> <section id="pypi-support"> <h2><a class="toc-backref" href="#pypi-support" role="doc-backlink">PyPI Support</a></h2> <p>PyPI should permit wheels containing the <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> platform tag to be uploaded in the same way that it permits <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code>. It should not attempt to verify the compatibility of <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> wheels.</p> </section> <section id="summary-of-changes-to-pep-571"> <h2><a class="toc-backref" href="#summary-of-changes-to-pep-571" role="doc-backlink">Summary of changes to PEP 571</a></h2> <p>The following changes were made to this PEP based on feedback received after it was approved:</p> <ul class="simple"> <li>The maximum version symbol of <code class="docutils literal notranslate"><span class="pre">libgcc_s</span></code> was updated from <code class="docutils literal notranslate"><span class="pre">GCC_4.3.0</span></code> to <code class="docutils literal notranslate"><span class="pre">GCC_4.5.0</span></code> to address 32-bit Cent OS 6. This doesn’t affect x86_64 because <code class="docutils literal notranslate"><span class="pre">libgcc_s</span></code> for x86_64 has no additional symbol from <code class="docutils literal notranslate"><span class="pre">GCC_4.3.0</span></code> to <code class="docutils literal notranslate"><span class="pre">GCC_4.5.0</span></code>.</li> </ul> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="id21" role="doc-footnote"> <dt class="label" id="id21">[<a href="#id1">2</a>]</dt> <dd>pyca/cryptography (<a class="reference external" href="https://cryptography.io/">https://cryptography.io/</a>)</aside> <aside class="footnote brackets" id="id22" role="doc-footnote"> <dt class="label" id="id22">[<a href="#id2">3</a>]</dt> <dd>numpy (<a class="reference external" href="https://numpy.org">https://numpy.org</a>)</aside> <aside class="footnote brackets" id="id23" role="doc-footnote"> <dt class="label" id="id23">[<a href="#id3">4</a>]</dt> <dd>CentOS 5.11 EOL announcement (<a class="reference external" href="https://lists.centos.org/pipermail/centos-announce/2017-April/022350.html">https://lists.centos.org/pipermail/centos-announce/2017-April/022350.html</a>)</aside> <aside class="footnote brackets" id="id24" role="doc-footnote"> <dt class="label" id="id24">[5]<em> (<a href='#id4'>1</a>, <a href='#id6'>2</a>) </em></dt> <dd>CentOS Product Specifications (<a class="reference external" href="https://web.archive.org/web/20180108090257/https://wiki.centos.org/About/Product">https://web.archive.org/web/20180108090257/https://wiki.centos.org/About/Product</a>)</aside> <aside class="footnote brackets" id="id25" role="doc-footnote"> <dt class="label" id="id25">[<a href="#id7">7</a>]</dt> <dd>ncurses 5 -> 6 transition means we probably need to drop some libraries from the manylinux whitelist (<a class="reference external" href="https://github.com/pypa/manylinux/issues/94">https://github.com/pypa/manylinux/issues/94</a>)</aside> <aside class="footnote brackets" id="id26" role="doc-footnote"> <dt class="label" id="id26">[<a href="#id8">9</a>]</dt> <dd>SOABI support for Python 2.X and PyPy <a class="reference external" href="https://github.com/pypa/pip/pull/3075">https://github.com/pypa/pip/pull/3075</a></aside> <aside class="footnote brackets" id="id27" role="doc-footnote"> <dt class="label" id="id27">[<a href="#id9">10</a>]</dt> <dd>manylinux2010 Docker image (<a class="reference external" href="https://quay.io/repository/pypa/manylinux2010_x86_64">https://quay.io/repository/pypa/manylinux2010_x86_64</a>)</aside> <aside class="footnote brackets" id="id28" role="doc-footnote"> <dt class="label" id="id28">[<a href="#id10">11</a>]</dt> <dd>On vsyscalls and the vDSO (<a class="reference external" href="https://lwn.net/Articles/446528/">https://lwn.net/Articles/446528/</a>)</aside> <aside class="footnote brackets" id="id29" role="doc-footnote"> <dt class="label" id="id29">[<a href="#id11">12</a>]</dt> <dd>vdso(7) (<a class="reference external" href="http://man7.org/linux/man-pages/man7/vdso.7.html">http://man7.org/linux/man-pages/man7/vdso.7.html</a>)</aside> <aside class="footnote brackets" id="id30" role="doc-footnote"> <dt class="label" id="id30">[<a href="#id12">13</a>]</dt> <dd>Framing Signals – A Return to Portable Shellcode (<a class="reference external" href="http://www.cs.vu.nl/~herbertb/papers/srop_sp14.pdf">http://www.cs.vu.nl/~herbertb/papers/srop_sp14.pdf</a>)</aside> <aside class="footnote brackets" id="id31" role="doc-footnote"> <dt class="label" id="id31">[<a href="#id13">14</a>]</dt> <dd>ChangeLog-3.1 (<a class="reference external" href="https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.1">https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.1</a>)</aside> <aside class="footnote brackets" id="id32" role="doc-footnote"> <dt class="label" id="id32">[<a href="#id14">15</a>]</dt> <dd>Project Zero: Three bypasses and a fix for one of Flash’s Vector.<*> mitigations (<a class="reference external" href="https://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html">https://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html</a>)</aside> <aside class="footnote brackets" id="id33" role="doc-footnote"> <dt class="label" id="id33">[<a href="#id15">16</a>]</dt> <dd>linux: activate CONFIG_LEGACY_VSYSCALL_NONE ? (<a class="reference external" href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852620">https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852620</a>)</aside> <aside class="footnote brackets" id="id34" role="doc-footnote"> <dt class="label" id="id34">[<a href="#id16">17</a>]</dt> <dd>[Wheel-builders] Heads-up re: new kernel configurations breaking the manylinux docker image (<a class="reference external" href="https://mail.python.org/pipermail/wheel-builders/2016-December/000239.html">https://mail.python.org/pipermail/wheel-builders/2016-December/000239.html</a>)</aside> <aside class="footnote brackets" id="id35" role="doc-footnote"> <dt class="label" id="id35">[<a href="#id17">18</a>]</dt> <dd>Travis CI (<a class="reference external" href="https://travis-ci.org/">https://travis-ci.org/</a>)</aside> <aside class="footnote brackets" id="id36" role="doc-footnote"> <dt class="label" id="id36">[<a href="#id18">19</a>]</dt> <dd>remove-vsyscall.patch <a class="reference external" href="https://github.com/markrwilliams/manylinux/commit/e9493d55471d153089df3aafca8cfbcb50fa8093#diff-3eda4130bdba562657f3ec7c1b3f5720">https://github.com/markrwilliams/manylinux/commit/e9493d55471d153089df3aafca8cfbcb50fa8093#diff-3eda4130bdba562657f3ec7c1b3f5720</a></aside> <aside class="footnote brackets" id="id37" role="doc-footnote"> <dt class="label" id="id37">[<a href="#id19">20</a>]</dt> <dd>auditwheel manylinux2 branch (<a class="reference external" href="https://github.com/markrwilliams/auditwheel/tree/manylinux2">https://github.com/markrwilliams/auditwheel/tree/manylinux2</a>)</aside> <aside class="footnote brackets" id="id38" role="doc-footnote"> <dt class="label" id="id38">[<a href="#id20">21</a>]</dt> <dd>pip manylinux2 branch <a class="reference external" href="https://github.com/markrwilliams/pip/commits/manylinux2">https://github.com/markrwilliams/pip/commits/manylinux2</a></aside> <aside class="footnote brackets" id="id39" role="doc-footnote"> <dt class="label" id="id39">[<a href="#id5">22</a>]</dt> <dd>Calendar Versioning <a class="reference external" href="http://calver.org/">http://calver.org/</a></aside> </aside> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed into the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0571.rst">https://github.com/python/peps/blob/main/peps/pep-0571.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0571.rst">2023-10-11 12:05:51 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#the-manylinux2010-policy">The <code class="docutils literal notranslate"><span class="pre">manylinux2010</span></code> policy</a></li> <li><a class="reference internal" href="#compilation-of-compliant-wheels">Compilation of Compliant Wheels</a><ul> <li><a class="reference internal" href="#docker-image">Docker Image</a><ul> <li><a class="reference internal" href="#compatibility-with-kernels-that-lack-vsyscall">Compatibility with kernels that lack <code class="docutils literal notranslate"><span class="pre">vsyscall</span></code></a></li> </ul> </li> <li><a class="reference internal" href="#auditwheel">Auditwheel</a></li> </ul> </li> <li><a class="reference internal" href="#platform-detection-for-installers">Platform Detection for Installers</a></li> <li><a class="reference internal" href="#backwards-compatibility-with-manylinux1-wheels">Backwards compatibility with <code class="docutils literal notranslate"><span class="pre">manylinux1</span></code> wheels</a></li> <li><a class="reference internal" href="#pypi-support">PyPI Support</a></li> <li><a class="reference internal" href="#summary-of-changes-to-pep-571">Summary of changes to PEP 571</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0571.rst">Page Source (GitHub)</a> </nav> </section> <script src="../_static/colour_scheme.js"></script> <script src="../_static/wrap_tables.js"></script> <script src="../_static/sticky_banner.js"></script> </body> </html>