From 1c90b801b2074c9acc691dc5623955cda826ac45 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 22 Mar 2025 11:31:55 +0100 Subject: [PATCH] feat: move default manylinux build to manylinux_2_28 --- cibuildwheel/options.py | 13 +-- cibuildwheel/resources/defaults.toml | 12 +-- docs/options.md | 36 +++---- test/test_container_images.py | 5 +- test/utils.py | 126 +++++++++++----------- unit_test/main_tests/main_options_test.py | 4 +- unit_test/option_prepare_test.py | 2 +- unit_test/options_toml_test.py | 2 +- 8 files changed, 100 insertions(+), 100 deletions(-) diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 5ab256232..8e8229a29 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -795,10 +795,7 @@ def _compute_build_options(self, identifier: str | None) -> BuildOptions: 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: + if config_value in pinned_images: image = pinned_images[config_value] else: image = config_value @@ -806,11 +803,11 @@ def _compute_build_options(self, identifier: str | None) -> BuildOptions: for build_platform in MUSLLINUX_ARCHS: pinned_images = all_pinned_container_images[build_platform] - config_value = self.reader.get(f"musllinux-{build_platform}-image") + config_value = self.reader.get( + f"musllinux-{build_platform}-image", ignore_empty=True + ) self._check_pinned_image(config_value, pinned_images) - if not config_value: - image = pinned_images["musllinux_1_2"] - elif config_value in pinned_images: + if config_value in pinned_images: image = pinned_images[config_value] else: image = config_value diff --git a/cibuildwheel/resources/defaults.toml b/cibuildwheel/resources/defaults.toml index 6b65e6369..bd17245b4 100644 --- a/cibuildwheel/resources/defaults.toml +++ b/cibuildwheel/resources/defaults.toml @@ -25,15 +25,15 @@ test-groups = [] container-engine = "docker" -manylinux-x86_64-image = "manylinux2014" +manylinux-x86_64-image = "manylinux_2_28" manylinux-i686-image = "manylinux2014" -manylinux-aarch64-image = "manylinux2014" -manylinux-ppc64le-image = "manylinux2014" -manylinux-s390x-image = "manylinux2014" +manylinux-aarch64-image = "manylinux_2_28" +manylinux-ppc64le-image = "manylinux_2_28" +manylinux-s390x-image = "manylinux_2_28" manylinux-armv7l-image = "manylinux_2_31" -manylinux-pypy_x86_64-image = "manylinux2014" +manylinux-pypy_x86_64-image = "manylinux_2_28" manylinux-pypy_i686-image = "manylinux2014" -manylinux-pypy_aarch64-image = "manylinux2014" +manylinux-pypy_aarch64-image = "manylinux_2_28" musllinux-x86_64-image = "musllinux_1_2" musllinux-i686-image = "musllinux_1_2" diff --git a/docs/options.md b/docs/options.md index 2e8a199c7..0c4ade208 100644 --- a/docs/options.md +++ b/docs/options.md @@ -1168,25 +1168,23 @@ Platform-specific environment variables are also available:
The available options are: -| Option | Default | Future default* | -|-----------------------------------|----------------------------------------------------------------|-----------------------------------------------------------------| -| CIBW_MANYLINUX_X86_64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_x86_64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_x86_64) | -| CIBW_MANYLINUX_I686_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_i686) | | -| CIBW_MANYLINUX_PYPY_X86_64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_x86_64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_x86_64) | -| CIBW_MANYLINUX_AARCH64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_aarch64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_aarch64) | -| CIBW_MANYLINUX_PPC64LE_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_ppc64le) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_ppc64le) | -| CIBW_MANYLINUX_S390X_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_s390x) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_s390x) | -| CIBW_MANYLINUX_ARMV7L_IMAGE | [`manylinux_2_31`](https://quay.io/pypa/manylinux_2_31_armv7l) | | -| CIBW_MANYLINUX_PYPY_AARCH64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_aarch64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_aarch64) | -| CIBW_MANYLINUX_PYPY_I686_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_i686) | | -| CIBW_MUSLLINUX_X86_64_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_x86_64) | | -| CIBW_MUSLLINUX_I686_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_i686) | | -| CIBW_MUSLLINUX_AARCH64_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_aarch64) | | -| CIBW_MUSLLINUX_PPC64LE_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_ppc64le) | | -| CIBW_MUSLLINUX_S390X_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_s390x) | | -| CIBW_MUSLLINUX_ARMV7L_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_armv7l) | | - -* The default is scheduled to change in a cibuildwheel release on or after 6th May 2025 - if you don't want the new default, you should set the value to `manylinux2014`. +| Option | Default | +|-----------------------------------|-----------------------------------------------------------------| +| CIBW_MANYLINUX_X86_64_IMAGE | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_x86_64) | +| CIBW_MANYLINUX_I686_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_i686) | +| CIBW_MANYLINUX_PYPY_X86_64_IMAGE | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_x86_64) | +| CIBW_MANYLINUX_AARCH64_IMAGE | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_aarch64) | +| CIBW_MANYLINUX_PPC64LE_IMAGE | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_ppc64le) | +| CIBW_MANYLINUX_S390X_IMAGE | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_s390x) | +| CIBW_MANYLINUX_ARMV7L_IMAGE | [`manylinux_2_31`](https://quay.io/pypa/manylinux_2_31_armv7l) | +| CIBW_MANYLINUX_PYPY_AARCH64_IMAGE | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_aarch64) | +| CIBW_MANYLINUX_PYPY_I686_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_i686) | +| CIBW_MUSLLINUX_X86_64_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_x86_64) | +| CIBW_MUSLLINUX_I686_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_i686) | +| CIBW_MUSLLINUX_AARCH64_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_aarch64) | +| CIBW_MUSLLINUX_PPC64LE_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_ppc64le) | +| CIBW_MUSLLINUX_S390X_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_s390x) | +| CIBW_MUSLLINUX_ARMV7L_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_armv7l) | Set the Docker image to be used for building [manylinux / musllinux](https://github.com/pypa/manylinux) wheels. diff --git a/test/test_container_images.py b/test/test_container_images.py index 17626a2ef..f1d4fda8b 100644 --- a/test/test_container_images.py +++ b/test/test_container_images.py @@ -43,9 +43,12 @@ def test(tmp_path): ) # also check that we got the right wheels built + manylinux_versions = ["manylinux_2_5", "manylinux1", "manylinux_2_17", "manylinux2014"] expected_wheels = [ w - for w in utils.expected_wheels("spam", "0.1.0", musllinux_versions=[]) + for w in utils.expected_wheels( + "spam", "0.1.0", manylinux_versions=manylinux_versions, musllinux_versions=[] + ) if "-cp38-" in w or "-cp39-" in w ] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/utils.py b/test/utils.py index 4548f0a52..6846223fb 100644 --- a/test/utils.py +++ b/test/utils.py @@ -162,6 +162,57 @@ def expected_wheels( include_universal2: bool = False, single_python: bool = False, single_arch: bool = False, +) -> list[str]: + """ + Returns a list of expected wheels from a run of cibuildwheel. + """ + if machine_arch is None: + machine_arch = pm.machine() + if platform == "linux": + machine_arch = arch_name_for_linux(machine_arch) + + architectures = [machine_arch] + if not single_arch: + if platform == "linux": + if machine_arch == "x86_64": + architectures.append("i686") + elif ( + machine_arch == "aarch64" + and sys.platform.startswith("linux") + and _AARCH64_CAN_RUN_ARMV7 + ): + architectures.append("armv7l") + elif platform == "windows" and machine_arch == "AMD64": + architectures.append("x86") + + wheels: list[str] = [] + for architecture in architectures: + wheels.extend( + _expected_wheels( + package_name, + package_version, + architecture, + manylinux_versions, + musllinux_versions, + macosx_deployment_target, + python_abi_tags, + include_universal2, + single_python, + ) + ) + return wheels + + +def _expected_wheels( + package_name: str, + package_version: str, + machine_arch: str, + manylinux_versions: list[str] | None, + musllinux_versions: list[str] | None, + macosx_deployment_target: str, + python_abi_tags: list[str] | None, + include_universal2: bool, + single_python: bool, ) -> list[str]: """ Returns a list of expected wheels from a run of cibuildwheel. @@ -171,24 +222,12 @@ def expected_wheels( # {python tag} and {abi tag} are closely related to the python interpreter used to build the wheel # so we'll merge them below as python_abi_tag - if machine_arch is None: - machine_arch = pm.machine() - if platform == "linux" and machine_arch.lower() == "arm64": - # we're running linux tests from macOS/Windows arm64, override platform - machine_arch = "aarch64" - if manylinux_versions is None: - if machine_arch in ("armv7l", "aarch64"): - manylinux_versions = ["manylinux_2_17", "manylinux2014", "manylinux_2_31"] - elif machine_arch == "x86_64": - manylinux_versions = [ - "manylinux_2_5", - "manylinux1", - "manylinux_2_17", - "manylinux2014", - ] - else: - manylinux_versions = ["manylinux_2_17", "manylinux2014"] + manylinux_versions = { + "armv7l": ["manylinux_2_17", "manylinux2014", "manylinux_2_31"], + "i686": ["manylinux_2_5", "manylinux1", "manylinux_2_17", "manylinux2014"], + "x86_64": ["manylinux_2_5", "manylinux1", "manylinux_2_28"], + }.get(machine_arch, ["manylinux_2_17", "manylinux2014", "manylinux_2_28"]) if musllinux_versions is None: musllinux_versions = ["musllinux_1_2"] @@ -206,7 +245,7 @@ def expected_wheels( "cp313-cp313t", ] - if machine_arch in ["x86_64", "AMD64", "x86", "aarch64"]: + if machine_arch in ["x86_64", "i686", "AMD64", "aarch64", "arm64"]: python_abi_tags += [ "pp38-pypy38_pp73", "pp39-pypy39_pp73", @@ -214,22 +253,6 @@ def expected_wheels( "pp311-pypy311_pp73", ] - if platform == "macos" and machine_arch == "arm64": - # arm64 macs are only supported by cp38+ - python_abi_tags = [ - "cp38-cp38", - "cp39-cp39", - "cp310-cp310", - "cp311-cp311", - "cp312-cp312", - "cp313-cp313", - "cp313-cp313t", - "pp38-pypy38_pp73", - "pp39-pypy39_pp73", - "pp310-pypy310_pp73", - "pp311-pypy311_pp73", - ] - if single_python: python_tag = "cp{}{}-".format(*SINGLE_PYTHON_VERSION) python_abi_tags = [ @@ -252,44 +275,23 @@ def expected_wheels( platform_tags = [] if platform == "linux": - architectures = [arch_name_for_linux(machine_arch)] - - if not single_arch: - if machine_arch == "x86_64": - architectures.append("i686") - elif ( - machine_arch == "aarch64" - and sys.platform.startswith("linux") - and not python_abi_tag.startswith("pp") - and _AARCH64_CAN_RUN_ARMV7 - ): - architectures.append("armv7l") - if len(manylinux_versions) > 0: platform_tags = [ ".".join( - f"{manylinux_version}_{architecture}" + f"{manylinux_version}_{machine_arch}" for manylinux_version in manylinux_versions - if (manylinux_version, architecture) != ("manylinux_2_31", "aarch64") ) - for architecture in architectures ] if len(musllinux_versions) > 0 and not python_abi_tag.startswith("pp"): - platform_tags.extend( - [ - ".".join( - f"{musllinux_version}_{architecture}" - for musllinux_version in musllinux_versions - ) - for architecture in architectures - ] + platform_tags.append( + ".".join( + f"{musllinux_version}_{machine_arch}" + for musllinux_version in musllinux_versions + ) ) elif platform == "windows": - if python_abi_tag.startswith("pp"): - platform_tags = ["win_amd64"] - else: - platform_tags = ["win32", "win_amd64"] + platform_tags = ["win_amd64"] if machine_arch == "AMD64" else ["win32"] elif platform == "macos": if python_abi_tag.startswith("pp"): diff --git a/unit_test/main_tests/main_options_test.py b/unit_test/main_tests/main_options_test.py index a869d615f..b8d773124 100644 --- a/unit_test/main_tests/main_options_test.py +++ b/unit_test/main_tests/main_options_test.py @@ -79,7 +79,7 @@ def test_empty_selector(monkeypatch): @pytest.mark.parametrize( ("architecture", "image", "full_image"), [ - ("x86_64", None, "quay.io/pypa/manylinux2014_x86_64:*"), + ("x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64:*"), ("x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64:*"), ("x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64:*"), ("x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64:*"), @@ -87,7 +87,7 @@ def test_empty_selector(monkeypatch): ("i686", None, "quay.io/pypa/manylinux2014_i686:*"), ("i686", "manylinux2014", "quay.io/pypa/manylinux2014_i686:*"), ("i686", "custom_image", "custom_image"), - ("pypy_x86_64", None, "quay.io/pypa/manylinux2014_x86_64:*"), + ("pypy_x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64:*"), ("pypy_x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64:*"), ("pypy_x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64:*"), ("pypy_x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64:*"), diff --git a/unit_test/option_prepare_test.py b/unit_test/option_prepare_test.py index 27b25377c..44f4da79b 100644 --- a/unit_test/option_prepare_test.py +++ b/unit_test/option_prepare_test.py @@ -59,7 +59,7 @@ def test_build_default_launches(monkeypatch): # In Python 3.8+, this can be simplified to [0].kwargs kwargs = build_in_container.call_args_list[0][1] - assert "quay.io/pypa/manylinux2014_x86_64" in kwargs["container"]["image"] + assert "quay.io/pypa/manylinux_2_28_x86_64" in kwargs["container"]["image"] assert kwargs["container"]["cwd"] == PurePosixPath("/project") assert kwargs["container"]["oci_platform"] == OCIPlatform.AMD64 diff --git a/unit_test/options_toml_test.py b/unit_test/options_toml_test.py index 03e125013..e5c8d5593 100644 --- a/unit_test/options_toml_test.py +++ b/unit_test/options_toml_test.py @@ -276,7 +276,7 @@ def test_environment_override_empty(tmp_path): assert options_reader.get("manylinux-i686-image") == "" assert options_reader.get("manylinux-aarch64-image") == "manylinux1" - assert options_reader.get("manylinux-x86_64-image", ignore_empty=True) == "manylinux2014" + assert options_reader.get("manylinux-x86_64-image", ignore_empty=True) == "manylinux_2_28" assert options_reader.get("manylinux-i686-image", ignore_empty=True) == "manylinux1" assert options_reader.get("manylinux-aarch64-image", ignore_empty=True) == "manylinux1"