Robert McGibbon: Thanks for writing up this PEP :-)

Some comments below...

On 21.01.2016 04:55, Nathaniel Smith wrote:
> The ``manylinux1`` policy
> =========================
> 
> For these reasons, to achieve broad portability, Python wheels
> 
>  * should depend only on an extremely limited set of external shared
>    libraries; and
>  * should depend only on ``old`` symbol versions in those external shared
>    libraries.
> 
> The ``manylinux1`` policy thus encompasses a standard for what the
> permitted external shared libraries a wheel may depend on, and the maximum
> depended-upon symbol versions therein.
> 
> The permitted external shared libraries are: ::
> 
>     libpanelw.so.5
>     libncursesw.so.5
>     libgcc_s.so.1
>     libstdc++.so.6
>     libm.so.6
>     libdl.so.2
>     librt.so.1
>     libcrypt.so.1
>     libc.so.6
>     libnsl.so.1
>     libutil.so.1
>     libpthread.so.0
>     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

The list is good start, but limiting the possible external
references to only these libraries will make it impossible
to have manylinux1 wheels which link against other, similarly
old, but very common libraries, or alternatively rather
new ones, which are then optionally included via subpackage
instead of being mandatory.

At eGenix we have been tackling this problem for years with
our extensions and the approach that's been the most
successful was to simply use Linux build systems which
are at least 5 years old. In our case, that's openSUSE 11.3.

I think a better approach is to use the above list to
test for used library *versions* and then apply the tag
based on the findings.

If a package includes binaries which link to e.g.
later libc.so versions, it would be rejected. If it
includes other libraries not listed in the above listing,
that's fine, as long as these libraries also comply to
the version limitation.

What I'm getting at here is that incompatibilities are
not caused by libraries being absent on the system
(the package simply won't load, but that's not due to the
the package being incompatible to the platform, only due
to the system lacking a few packages), but instead by
having the packages use more recent versions of these
system libraries.

> Compilation and Tooling
> =======================
> 
> To support the compilation of wheels meeting the ``manylinux1`` standard, we
> provide initial drafts of two tools.
> 
> The first is a Docker image based on CentOS 5.11, which is recommended as an
> easy to use self-contained build box for compiling ``manylinux1`` wheels [4]_.
> Compiling on a more recently-released linux distribution will generally
> introduce dependencies on too-new versioned symbols. The image comes with a
> full compiler suite installed (``gcc``, ``g++``, and ``gfortran`` 4.8.2) as
> well as the latest releases of Python and pip.
> 
> The second tool is a command line executable called ``auditwheel`` [5]_. 
> First,
> it inspects all of the ELF files inside a wheel to check for dependencies on
> versioned symbols or external shared libraries, and verifies conformance with
> the ``manylinux1`` policy. This includes the ability to add the new platform
> tag to conforming wheels.
> 
> In addition, ``auditwheel`` has the ability to automatically modify wheels 
> that
> depend on external shared libraries by copying those shared libraries from
> the system into the wheel itself, and modifying the appropriate RPATH entries
> such that these libraries will be picked up at runtime. This accomplishes a
> similar result as if the libraries had been statically linked without 
> requiring
> changes to the build system.

This approach has a few problems:

* Libraries typically depend on a lot more context than just
  the code that is provided in the libraries file, e.g. config
  files, external resources, other libraries which are loaded
  on demand, etc.

* By including the libraries in the wheel you are distributing
  the binary, which can lead to licensing problems, esp. with
  GPLed or LGPLed code.

> Neither of these tools are necessary to build wheels which conform with the
> ``manylinux1`` policy. Similar results can usually be achieved by statically
> linking external dependencies and/or using certain inline assembly constructs
> to instruct the linker to prefer older symbol versions, however these tricks
> can be quite esoteric.

Static linking only helps in very few cases, where the context
needed for the external library to work is minimal.

> Platform Detection for Installers
> =================================
> 
> Because the ``manylinux1`` profile is already known to work for the many
> thousands of users of popular commercial Python distributions, we suggest that
> installation tools like ``pip`` should error on the side of assuming that a
> system *is* compatible, unless there is specific reason to think otherwise.
> 
> We know of three main sources of potential incompatibility that are likely to
> arise in practice:
> 
> * A linux distribution that is too old (e.g. RHEL 4)
> * A linux distribution that does not use glibc (e.g. Alpine Linux, which is
>   based on musl libc, or Android)
> * Eventually, in the future, there may exist distributions that break
>   compatibility with this profile
> 
> To handle the first two cases, we propose the following simple and reliable
> check: ::
>     def have_glibc_version(major, minimum_minor):
>         [...]

It would be better to use platform.libc_ver() for this.

> ``manylinux1`` wheels distributed through PyPI that bundle security-critical
> libraries like OpenSSL will thus assume responsibility for prompt updates in
> response disclosed vulnerabilities and patches. This closely parallels the
> security implications of the distribution of binary wheels on Windows that,
> because the platform lacks a system package manager, generally bundle their
> dependencies. In particular, because its lacks a stable ABI, OpenSSL cannot be
> included in the ``manylinux1`` profile.

The OpenSSL ABI has been quite stable in recent years (unlike in the
days of 0.9.7 and earlier).

Since many libraries do link against OpenSSL (basically everything
that uses network connections nowadays), using the fixed scheme
outlined in the PEP would severely limited the usefulness.

By using the version based approach, we'd not run into this
problem and gain a lot more.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Jan 21 2016)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...           http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...           http://zope.egenix.com/
________________________________________________________________________

::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/
                      http://www.malemburg.com/

_______________________________________________
Distutils-SIG maillist  -  Distutils-SIG@python.org
https://mail.python.org/mailman/listinfo/distutils-sig

Reply via email to