diff --git a/Changelog.md b/Changelog.md index 2831c1d5..188dae43 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,8 @@ rules on making a good Changelog. - Existing libraries causing DelocationError were not shown due to bad string formatting. [#216](https://github.com/matthew-brett/delocate/pull/216) +- Wheels for macOS 11 and later were using invalid literal versions in tags + instead of the macOS release version required by Python packagers. ## [0.11.0] - 2024-03-22 diff --git a/delocate/delocating.py b/delocate/delocating.py index fe9e7087..d806a8cc 100644 --- a/delocate/delocating.py +++ b/delocate/delocating.py @@ -808,8 +808,18 @@ def _calculate_minimum_wheel_name( f"Failed to find any binary with the required architecture: {e}" ) from e prefix = wheel_name.rsplit("-", 1)[0] + + # Wheel platform tags MUST use the macOS release version, not the literal + # version provided by macOS. Since macOS 11 the minor version number is not + # part of the macOS release version and MUST be zero for tagging purposes. + def get_release_version(version: Version) -> str: + """Return the macOS release version from the given actual version.""" + if require_target_macos_version is not None: + version = max(version, require_target_macos_version) + return f"{version.major}_{0 if version.major >= 11 else version.minor}" + platform_tag = ".".join( - f"macosx_{version.major}_{version.minor}_{arch}" + f"macosx_{get_release_version(version)}_{arch}" for arch, version in arch_version.items() ) return f"{prefix}-{platform_tag}.whl", problematic_libs diff --git a/delocate/tests/test_scripts.py b/delocate/tests/test_scripts.py index bd3a3ddd..6fb6c631 100644 --- a/delocate/tests/test_scripts.py +++ b/delocate/tests/test_scripts.py @@ -830,11 +830,13 @@ def test_delocate_wheel_verify_name_universal2_verify_crash_env_var( whl_10_9 = tmp_path / "plat2-1.0-cp311-cp311-macosx_10_9_universal2.whl" dir2zip(tmp_path / "plat", whl_10_9) + env = os.environ.copy() + env["MACOSX_DEPLOYMENT_TARGET"] = "10.9" result = script_runner.run( ["delocate-wheel", whl_10_9], check=False, cwd=tmp_path, - env={"MACOSX_DEPLOYMENT_TARGET": "10.9"}, + env=env, ) assert result.returncode != 0 assert "Library dependencies do not satisfy target MacOS" in result.stderr @@ -842,3 +844,21 @@ def test_delocate_wheel_verify_name_universal2_verify_crash_env_var( assert "module2.abi3.so has a minimum target of 11.0" not in result.stderr assert "MACOSX_DEPLOYMENT_TARGET=12.0" in result.stderr assert "--require-target-macos-version 12.0" in result.stderr + + +@pytest.mark.xfail( # type: ignore[misc] + sys.platform != "darwin", reason="Needs macOS linkage." +) +def test_delocate_wheel_macos_release_minor_version( + plat_wheel: PlatWheel, script_runner: ScriptRunner, tmp_path: Path +) -> None: + env = os.environ.copy() + env["MACOSX_DEPLOYMENT_TARGET"] = "13.1" + script_runner.run( + ["delocate-wheel", plat_wheel.whl, "-vv"], env=env, check=True + ) + + # Should create a 13.0 wheel instead of the requested 13.1 + assert {tmp_path / "plat-1.0-cp311-cp311-macosx_13_0_x86_64.whl"} == set( + file for file in tmp_path.iterdir() if file.suffix == ".whl" + )