# pypa/manylinux — Python wheels that work on any linux (almost)

# manylinux

Repo: https://github.com/pypa/manylinux
Stars: ~1,764 · License: MIT · Primary language: Shell · Description: "Python wheels that work on any linux (almost)"

Older archives: https://groups.google.com/forum/#!forum/manylinux-discuss

The goal of the manylinux project is to provide a convenient way to distribute binary Python extensions as wheels on Linux. This effort has produced:

- PEP 513 (manylinux1)
- PEP 571 (manylinux2010)
- PEP 599 (manylinux2014)
- PEP 600 (manylinux_x_y)
- PEP 656 (musllinux_x_y)

PEP 513 defined `manylinux1_x86_64` and `manylinux1_i686` platform tags; wheels were built on CentOS 5. CentOS 5 reached EOL on March 31st, 2017.

PEP 571 defined `manylinux2010_x86_64` and `manylinux2010_i686` platform tags; wheels were built on CentOS 6. CentOS 6 reached EOL on November 30th, 2020.

PEP 599 defines: `manylinux2014_x86_64`, `manylinux2014_i686`, `manylinux2014_aarch64`, `manylinux2014_armv7l`, `manylinux2014_ppc64`, `manylinux2014_ppc64le`, `manylinux2014_s390x`. Wheels built on CentOS 7. CentOS 7 reached EOL on June 30th, 2024.

PEP 600 was designed to be "future-proof" and does not enforce specific symbols and a specific distro to build. It only states that a wheel tagged `manylinux_x_y` shall work on any distro based on `glibc>=x.y`. PEP 656 added `musllinux_x_y` tags for `musl>=x.y`.

An overview of distros per glibc version: https://github.com/mayeut/pep600_compliance

The manylinux project supports:

- `manylinux2014` images for x86_64, i686, aarch64, ppc64le, s390x
- `manylinux_2_28` images for x86_64, i686, aarch64, ppc64le, s390x
- `manylinux_2_31` images for armv7l
- `manylinux_2_34` images for x86_64, i686, aarch64, ppc64le, s390x
- `manylinux_2_35` images for armv7l
- `manylinux_2_39` images for aarch64, riscv64
- `musllinux_1_2` images for x86_64, i686, aarch64, ppc64le, s390x, armv7l, riscv64

Wheel packages compliant with those tags can be uploaded to PyPI (e.g. with twine) and installed with pip.

## pip / CPython compatibility (from README table)

| manylinux tag | Client-side pip required | CPython (sources) embedding compatible pip |
|---|---|---|
| `manylinux_x_y` | pip >= 20.3 | 3.8.10+, 3.9.5+, 3.10.0+ |
| `manylinux2014` | pip >= 19.3 | 3.7.8+, 3.8.4+, 3.9.0+ |
| `manylinux2010` | pip >= 19.0 | 3.7.3+, 3.8.0+ |
| `manylinux1` | pip >= 8.1.0 | 3.5.2+, 3.6.0+ |

The various manylinux tags allow projects to distribute wheels that are automatically installed (and work) on the vast majority of desktop and server Linux distributions.

## Docker images

Building manylinux-compatible wheels is not trivial; as a general rule, binaries built on one Linux distro will only work on other Linux distros that are the same age or newer. Therefore, to make binaries that run on most distros, you have to use an old enough distro. Rather than forcing you to install an old distro yourself, the project provides Docker images (uploaded to `quay.io/pypa/...`, tagged for repeatable builds).

### manylinux_2_39 (AlmaLinux/RockyLinux 10 based) — ALPHA
Toolchain: GCC 14
- aarch64: `quay.io/pypa/manylinux_2_39_aarch64`
- riscv64: `quay.io/pypa/manylinux_2_39_riscv64`
- Compatible with glibc 2.39+: Debian 13+, Ubuntu 24.04+, Fedora 40+, CentOS/RHEL 10+

### manylinux_2_35 (Ubuntu 22.04 based) — armv7l only
Only Debian derivatives are available for armv7l; they don't provide recent GCC toolchain builds, so only the GCC shipped with the base distro is available. This image uses apt / Debian package names instead of yum/dnf / RHEL names. Example: `dnf -y install openssl-devel` (RHEL) vs `apt-get install -y libssl-dev` (Debian).
Toolchain: GCC 11
- armv7l: `quay.io/pypa/manylinux_2_35_armv7l`
- Compatible with glibc 2.35+: Debian 12+, Ubuntu 22.04+

### manylinux_2_34 (AlmaLinux 9 based) — ALPHA
Caveat: on x86_64, RHEL 9+ derivatives use the x86-64-v2 target architecture. manylinux worked around this when building from sources (intercepting compiler calls to target x86_64), but every library installed with dnf will most likely target x86-64-v2, which if grafted into a wheel will fail on older hardware. No PEP yet handles micro-architecture variants for packaging/installing wheels; auditwheel doesn't detect this either. See issue #1725.
Toolchain: GCC 14
- x86_64, i686, aarch64, ppc64le, s390x images
- Compatible with glibc 2.34+: Debian 12+, Ubuntu 21.10+, Fedora 35+, CentOS/RHEL 9+

### manylinux_2_31 (Ubuntu 20.04 based) — armv7l only
Same Debian-derivative caveats as manylinux_2_35.
Toolchain: GCC 9
- armv7l: `quay.io/pypa/manylinux_2_31_armv7l`
- Compatible with glibc 2.31+: Debian 11+, Ubuntu 20.04+

### manylinux_2_28 (AlmaLinux 8 based)
Toolchain: GCC 14
- x86_64, i686, aarch64, ppc64le, s390x images
- Compatible with glibc 2.28+: Debian 10+, Ubuntu 18.10+, Fedora 29+, CentOS/RHEL 8+

### manylinux2014 (CentOS 7 based, glibc 2.17)
Toolchain: GCC 10
- x86_64, i686, aarch64, ppc64le, s390x images
- Compatible with glibc 2.17+: Debian 8+, Ubuntu 13.10+, Fedora 19+, RHEL 7+

### manylinux_2_24 (Debian 9 based) — EOL
Support ended January 1st, 2023 (issue #1332). Toolchain: GCC 6. Images for x86_64, i686, aarch64, ppc64le, s390x.

### manylinux2010 (CentOS 6 based, glibc 2.12) — EOL
Support ended August 1st, 2022 (issue #1281). Toolchain: GCC 8. Images for x86_64, i686.

### manylinux1 (CentOS 5 based, glibc 2.5) — EOL
Support ended January 1st, 2022 (issue #994). Toolchain: GCC 4.8. Code/details in the `v2024.04.29-manylinux1` tag. Images for x86_64, i686.

### musllinux_1_2 (Alpine Linux 3.22 based, 3.13+ compatible)
Toolchain: GCC 14
- x86_64, i686, aarch64, ppc64le, s390x, armv7l, riscv64 images

This repository hosts several manylinux-related things (Docker images, tooling, PEP definitions).
