Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop EOL manylinux images #2316

Merged
merged 3 commits into from
Mar 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 34 additions & 60 deletions bin/update_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,45 @@
@dataclass(frozen=True)
class Image:
manylinux_version: str
platform: str
platforms: list[str]
image_name: str
tag: str | None # Set this to pin the image
tag: str | None = None # Set this to pin the image
use_platform_suffix: bool = False


class PyPAImage(Image):
def __init__(self, manylinux_version: str, platform: str, tag: str | None):
platform_no_pypy = platform.removeprefix("pypy_")
image_name = f"quay.io/pypa/{manylinux_version}_{platform_no_pypy}"
super().__init__(manylinux_version, platform, image_name, tag)
def __init__(self, manylinux_version: str, platforms: list[str], tag: str | None = None):
image_name = f"quay.io/pypa/{manylinux_version}"
super().__init__(manylinux_version, platforms, image_name, tag, True)


images = [
# manylinux1 images, EOL -> use tag
PyPAImage("manylinux1", "x86_64", "2024-04-29-76807b8"),
PyPAImage("manylinux1", "i686", "2024-04-29-76807b8"),
# manylinux2010 images, EOL -> use tag
PyPAImage("manylinux2010", "x86_64", "2022-08-05-4535177"),
PyPAImage("manylinux2010", "i686", "2022-08-05-4535177"),
PyPAImage("manylinux2010", "pypy_x86_64", "2022-08-05-4535177"),
PyPAImage("manylinux2010", "pypy_i686", "2022-08-05-4535177"),
# manylinux2014 images
PyPAImage("manylinux2014", "x86_64", None),
PyPAImage("manylinux2014", "i686", None),
PyPAImage("manylinux2014", "aarch64", None),
PyPAImage("manylinux2014", "ppc64le", None),
PyPAImage("manylinux2014", "s390x", None),
PyPAImage("manylinux2014", "pypy_x86_64", None),
PyPAImage("manylinux2014", "pypy_i686", None),
PyPAImage("manylinux2014", "pypy_aarch64", None),
# manylinux_2_24 images, EOL -> use tag
PyPAImage("manylinux_2_24", "x86_64", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "i686", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "aarch64", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "ppc64le", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "s390x", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "pypy_x86_64", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "pypy_i686", "2022-12-26-0d38463"),
PyPAImage("manylinux_2_24", "pypy_aarch64", "2022-12-26-0d38463"),
PyPAImage(
"manylinux2014",
[
"x86_64",
"i686",
"aarch64",
"ppc64le",
"s390x",
"pypy_x86_64",
"pypy_i686",
"pypy_aarch64",
],
),
# manylinux_2_28 images
PyPAImage("manylinux_2_28", "x86_64", None),
PyPAImage("manylinux_2_28", "aarch64", None),
PyPAImage("manylinux_2_28", "ppc64le", None),
PyPAImage("manylinux_2_28", "s390x", None),
PyPAImage("manylinux_2_28", "pypy_x86_64", None),
PyPAImage("manylinux_2_28", "pypy_aarch64", None),
PyPAImage(
"manylinux_2_28", ["x86_64", "aarch64", "ppc64le", "s390x", "pypy_x86_64", "pypy_aarch64"]
),
# manylinux_2_31 images
PyPAImage("manylinux_2_31", "armv7l", None),
PyPAImage("manylinux_2_31", ["armv7l"]),
# manylinux_2_34 images
PyPAImage("manylinux_2_34", "x86_64", None),
PyPAImage("manylinux_2_34", "aarch64", None),
PyPAImage("manylinux_2_34", "ppc64le", None),
PyPAImage("manylinux_2_34", "s390x", None),
PyPAImage("manylinux_2_34", "pypy_x86_64", None),
PyPAImage("manylinux_2_34", "pypy_aarch64", None),
# musllinux_1_1 images, EOL -> use tag
PyPAImage("musllinux_1_1", "x86_64", "2024.10.26-1"),
PyPAImage("musllinux_1_1", "i686", "2024.10.26-1"),
PyPAImage("musllinux_1_1", "aarch64", "2024.10.26-1"),
PyPAImage("musllinux_1_1", "ppc64le", "2024.10.26-1"),
PyPAImage("musllinux_1_1", "s390x", "2024.10.26-1"),
PyPAImage(
"manylinux_2_34", ["x86_64", "aarch64", "ppc64le", "s390x", "pypy_x86_64", "pypy_aarch64"]
),
# musllinux_1_2 images
PyPAImage("musllinux_1_2", "x86_64", None),
PyPAImage("musllinux_1_2", "i686", None),
PyPAImage("musllinux_1_2", "aarch64", None),
PyPAImage("musllinux_1_2", "ppc64le", None),
PyPAImage("musllinux_1_2", "s390x", None),
PyPAImage("musllinux_1_2", "armv7l", None),
PyPAImage("musllinux_1_2", ["x86_64", "i686", "aarch64", "ppc64le", "s390x", "armv7l"]),
]

config = configparser.ConfigParser()
Expand Down Expand Up @@ -137,10 +108,13 @@ def __init__(self, manylinux_version: str, platform: str, tag: str | None):
)
tag_name = pinned_tag["name"]

if not config.has_section(image.platform):
config[image.platform] = {}

config[image.platform][image.manylinux_version] = f"{image.image_name}:{tag_name}"
for platform in image.platforms:
if not config.has_section(platform):
config[platform] = {}
suffix = ""
if image.use_platform_suffix:
suffix = f"_{platform.removeprefix('pypy_')}"
config[platform][image.manylinux_version] = f"{image.image_name}{suffix}:{tag_name}"

with open(RESOURCES / "pinned_docker_images.cfg", "w") as f:
config.write(f)
26 changes: 14 additions & 12 deletions cibuildwheel/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,18 @@ def globals(self) -> GlobalOptions:
)

def _check_pinned_image(self, value: str, pinned_images: Mapping[str, str]) -> None:
if (
value in {"manylinux1", "manylinux2010", "manylinux_2_24", "musllinux_1_1"}
and value not in self._image_warnings
):
error_set = {"manylinux1", "manylinux2010", "manylinux_2_24", "musllinux_1_1"}
warning_set: set[str] = set()

if value in error_set:
msg = (
f"cibuildwheel 3.x does not support the image {value!r}. Either upgrade to a "
"supported image or continue using the image by pinning it directly with"
" its full OCI registry '<name>{:<tag>|@<digest>}'."
)
raise errors.DeprecationError(msg)

if value in warning_set and value not in self._image_warnings:
self._image_warnings.add(value)
msg = (
f"Deprecated image {value!r}. This value will not work"
Expand Down Expand Up @@ -783,35 +791,29 @@ def _compute_build_options(self, identifier: str | None) -> BuildOptions:

for build_platform in MANYLINUX_ARCHS:
pinned_images = all_pinned_container_images[build_platform]

config_value = self.reader.get(
f"manylinux-{build_platform}-image", ignore_empty=True
)

self._check_pinned_image(config_value, pinned_images)
if not config_value:
# default to manylinux2014
image = pinned_images["manylinux2014"]
elif config_value in pinned_images:
self._check_pinned_image(config_value, pinned_images)
image = pinned_images[config_value]
else:
image = config_value

manylinux_images[build_platform] = image

for build_platform in MUSLLINUX_ARCHS:
pinned_images = all_pinned_container_images[build_platform]

config_value = self.reader.get(f"musllinux-{build_platform}-image")

self._check_pinned_image(config_value, pinned_images)
if not config_value:
image = pinned_images["musllinux_1_2"]
elif config_value in pinned_images:
self._check_pinned_image(config_value, pinned_images)
image = pinned_images[config_value]
else:
image = config_value

musllinux_images[build_platform] = image

container_engine_str = self.reader.get(
Expand Down
35 changes: 8 additions & 27 deletions cibuildwheel/resources/pinned_docker_images.cfg
Original file line number Diff line number Diff line change
@@ -1,60 +1,41 @@
[x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.03.15-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2025.03.15-1

[i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2025.03.15-1

[pypy_x86_64]
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.03.15-1

[pypy_i686]
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463

[aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.03.15-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2025.03.15-1

[ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2025.03.15-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2025.03.15-1

[s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2025.03.15-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2025.03.15-1

[pypy_x86_64]
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.15-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.03.15-1

[pypy_i686]
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.15-1

[pypy_aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.03.15-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.03.15-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.03.15-1

Expand Down
7 changes: 4 additions & 3 deletions docs/cpp_standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ title: Modern C++ standards
Building Python wheels with modern C++ standards (C++11 and later) requires a few tricks.


## manylinux1 and C++14
The past end-of-life `manylinux1` image (based on CentOS 5) contains a version of GCC and libstdc++ that only supports C++11 and earlier standards. There are however ways to compile wheels with the C++14 standard (and later): https://github.com/pypa/manylinux/issues/118
## manylinux2014 and C++20

`manylinux2010` and `manylinux2014` are newer and support all C++ standards (up to C++17).
The past end-of-life `manylinux2014` image (based on CentOS 7) contains a version of GCC and libstdc++ that only supports C++17 and earlier standards.

`manylinux_2_28` are newer and support all C++ standards (up to C++20).

## macOS and deployment target versions

Expand Down
2 changes: 1 addition & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ title: Tips and tricks

Linux wheels are built in [`manylinux`/`musllinux` containers](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 600](https://www.python.org/dev/peps/pep-0600/) / [PEP 656](https://www.python.org/dev/peps/pep-0656/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:

- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2010` or `manylinux2014`, `apt-get` for `manylinux_2_24`/`manylinux_2_31`, `dnf` for `manylinux_2_28` and `apk` for `musllinux_1_1` or `musllinux_1_2`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2014`, `apt-get` for `manylinux_2_31`, `dnf` for `manylinux_2_28` and `apk` for `musllinux_1_1` or `musllinux_1_2`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.

`cibuildwheel` supports this by providing the [`CIBW_ENVIRONMENT`](options.md#environment) and [`CIBW_BEFORE_ALL`](options.md#before-all) options to setup the build environment inside the running container.

Expand Down
Loading
Loading