feat: remove 32-bit linux from auto arch, fix auto32 on linux aarch64 (#2458)
* feat: remove 32-bit linux from auto arch, fix auto32 on linux aarch64 Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * Apply suggestions from code review Co-authored-by: Joe Rickerby <joerick@mac.com> * Update cibuildwheel/architecture.py --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: Joe Rickerby <joerick@mac.com>
This commit is contained in:
co-authored by
Joe Rickerby
parent
3fa7bd1e72
commit
e188d9e260
@@ -75,24 +75,24 @@ class Architecture(StrEnum):
|
||||
def parse_config(config: str, platform: PlatformName) -> "set[Architecture]":
|
||||
result = set()
|
||||
for arch_str in re.split(r"[\s,]+", config):
|
||||
if arch_str == "auto":
|
||||
result |= Architecture.auto_archs(platform=platform)
|
||||
elif arch_str == "native":
|
||||
native_arch = Architecture.native_arch(platform=platform)
|
||||
if native_arch:
|
||||
result.add(native_arch)
|
||||
elif arch_str == "all":
|
||||
result |= Architecture.all_archs(platform=platform)
|
||||
elif arch_str == "auto64":
|
||||
result |= Architecture.bitness_archs(platform=platform, bitness="64")
|
||||
elif arch_str == "auto32":
|
||||
result |= Architecture.bitness_archs(platform=platform, bitness="32")
|
||||
else:
|
||||
try:
|
||||
result.add(Architecture(arch_str))
|
||||
except ValueError as e:
|
||||
msg = f"Invalid architecture '{arch_str}'"
|
||||
raise errors.ConfigurationError(msg) from e
|
||||
match arch_str:
|
||||
case "auto":
|
||||
result |= Architecture.auto_archs(platform=platform)
|
||||
case "native":
|
||||
if native_arch := Architecture.native_arch(platform=platform):
|
||||
result.add(native_arch)
|
||||
case "all":
|
||||
result |= Architecture.all_archs(platform=platform)
|
||||
case "auto64":
|
||||
result |= Architecture.bitness_archs(platform=platform, bitness="64")
|
||||
case "auto32":
|
||||
result |= Architecture.bitness_archs(platform=platform, bitness="32")
|
||||
case _:
|
||||
try:
|
||||
result.add(Architecture(arch_str))
|
||||
except ValueError as e:
|
||||
msg = f"Invalid architecture '{arch_str}'"
|
||||
raise errors.ConfigurationError(msg) from e
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
@@ -142,19 +142,12 @@ class Architecture(StrEnum):
|
||||
return set() # can't build anything on this platform
|
||||
result = {native_arch}
|
||||
|
||||
if platform == "linux":
|
||||
if Architecture.x86_64 in result:
|
||||
# x86_64 machines can run i686 containers
|
||||
result.add(Architecture.i686)
|
||||
elif Architecture.aarch64 in result and _check_aarch32_el0():
|
||||
result.add(Architecture.armv7l)
|
||||
|
||||
elif platform == "windows" and Architecture.AMD64 in result:
|
||||
result.add(Architecture.x86)
|
||||
|
||||
elif platform == "ios" and native_arch == Architecture.arm64_iphonesimulator:
|
||||
# Also build the device wheel if we're on ARM64.
|
||||
result.add(Architecture.arm64_iphoneos)
|
||||
match platform:
|
||||
case "windows" if Architecture.AMD64 in result:
|
||||
result.add(Architecture.x86)
|
||||
case "ios" if native_arch == Architecture.arm64_iphonesimulator:
|
||||
# Also build the device wheel if we're on ARM64.
|
||||
result.add(Architecture.arm64_iphoneos)
|
||||
|
||||
return result
|
||||
|
||||
@@ -183,14 +176,35 @@ class Architecture(StrEnum):
|
||||
|
||||
@staticmethod
|
||||
def bitness_archs(platform: PlatformName, bitness: Literal["64", "32"]) -> "set[Architecture]":
|
||||
archs_32 = {Architecture.i686, Architecture.x86, Architecture.armv7l}
|
||||
auto_archs = Architecture.auto_archs(platform)
|
||||
# This map maps 64-bit architectures to their 32-bit equivalents.
|
||||
archs_map = {
|
||||
Architecture.x86_64: Architecture.i686,
|
||||
Architecture.AMD64: Architecture.x86,
|
||||
Architecture.aarch64: Architecture.armv7l,
|
||||
}
|
||||
native_arch = Architecture.native_arch(platform)
|
||||
|
||||
if bitness == "64":
|
||||
return auto_archs - archs_32
|
||||
if bitness == "32":
|
||||
return auto_archs & archs_32
|
||||
typing.assert_never(bitness)
|
||||
if native_arch is None:
|
||||
return set() # can't build anything on this platform
|
||||
|
||||
if native_arch == Architecture.wasm32:
|
||||
return {native_arch} if bitness == "32" else set()
|
||||
|
||||
match bitness:
|
||||
case "64":
|
||||
return {native_arch} if native_arch not in archs_map.values() else set()
|
||||
case "32":
|
||||
if native_arch in archs_map.values():
|
||||
return {native_arch}
|
||||
elif native_arch in archs_map and platform in {"linux", "windows"}:
|
||||
if native_arch == Architecture.aarch64 and not _check_aarch32_el0():
|
||||
# If we're on aarch64, skip if we cannot build armv7l wheels.
|
||||
return set()
|
||||
return {archs_map[native_arch]}
|
||||
else:
|
||||
return set()
|
||||
case _:
|
||||
typing.assert_never(bitness)
|
||||
|
||||
|
||||
def allowed_architectures_check(
|
||||
|
||||
+31
-8
@@ -191,10 +191,10 @@ Options:
|
||||
- Windows: `AMD64` `x86` `ARM64`
|
||||
- Pyodide: `wasm32`
|
||||
- iOS: `arm64_iphoneos` `arm64_iphonesimulator` `x86_64_iphonesimulator`
|
||||
- `auto`: The default archs for your machine - see the table below.
|
||||
- `auto64`: Just the 64-bit auto archs
|
||||
- `auto32`: Just the 32-bit auto archs
|
||||
- `native`: the native arch of the build machine - Matches [`platform.machine()`](https://docs.python.org/3/library/platform.html#platform.machine).
|
||||
- `auto`: The recommended archs for your machine - see the table below.
|
||||
- `auto64`: The 64-bit arch(s) supported by your machine (includes device and simulator for iOS)
|
||||
- `auto32`: The 32-bit arch supported by your machine
|
||||
- `native`: the native arch of the build machine - matches [`platform.machine()`](https://docs.python.org/3/library/platform.html#platform.machine).
|
||||
- `all` : expands to all the architectures supported on this OS. You may want
|
||||
to use [`build`](#build-skip) with this option to target specific
|
||||
architectures via build selectors.
|
||||
@@ -205,16 +205,34 @@ Default: `auto`
|
||||
|
||||
| Runner | `native` | `auto` | `auto64` | `auto32` |
|
||||
|---|---|---|---|---|
|
||||
| Linux / Intel | `x86_64` | `x86_64` `i686` | `x86_64` | `i686` |
|
||||
| Windows / Intel | `AMD64` | `AMD64` `x86` | `AMD64` | `x86` |
|
||||
| Linux / Intel 64-bit | `x86_64` | `x86_64` | `x86_64` | `i686` |
|
||||
| Linux / Intel 32-bit | `i686` | `i686` | | `i686` |
|
||||
| Linux / Arm 64-bit | `aarch64` | `aarch64` | `aarch64` | `armv7l`¹ |
|
||||
| Linux / Arm 32-bit | `armv7l` | `armv7l` | | `armv7l` |
|
||||
| Windows / Intel 64-bit | `AMD64` | `AMD64` `x86` | `AMD64` | `x86` |
|
||||
| Windows / Intel 32-bit | `x86` | `x86` | | `x86` |
|
||||
| Windows / ARM64 | `ARM64` | `ARM64` | `ARM64` | |
|
||||
| macOS / Intel | `x86_64` | `x86_64` | `x86_64` | |
|
||||
| macOS / Apple Silicon | `arm64` | `arm64` | `arm64` | |
|
||||
| iOS on macOS / Intel | `x86_64_iphonesimulator` | `x86_64_iphonesimulator` | `x86_64_iphonesimulator` | |
|
||||
| iOS on macOS / Apple Silicon | `arm64_iphonesimulator` | `arm64_iphoneos` `arm64_iphonesimulator` | `arm64_iphoneos` `arm64_iphonesimulator` |
|
||||
|
||||
¹: This will only be included if the runner supports it.
|
||||
|
||||
If not listed above, `auto` is the same as `native`.
|
||||
|
||||
!!! warning
|
||||
The `auto` option only includes 32-bit architectures if they are
|
||||
commonly built. `cibuildwheel` 3.0 removed 32-bit Linux builds from `auto`,
|
||||
and a future release may remove 32-bit Windows builds from `auto` as well.
|
||||
If you know you need them, please include `auto32`. Note that modern
|
||||
manylinux image do not support 32-bit builds. If you want to avoid 32-bit
|
||||
Windows builds today, feel free to use `auto64`.
|
||||
|
||||
!!! note
|
||||
Pyodide currently ignores the architecture setting, as it always builds for
|
||||
`wasm32`.
|
||||
|
||||
[setup-qemu-action]: https://github.com/docker/setup-qemu-action
|
||||
[binfmt]: https://hub.docker.com/r/tonistiigi/binfmt
|
||||
|
||||
@@ -238,6 +256,10 @@ This option can also be set using the [command-line option](#command-line)
|
||||
# On an Linux Intel runner with qemu installed, build Intel and ARM wheels
|
||||
[tool.cibuildwheel.linux]
|
||||
archs = ["auto", "aarch64"]
|
||||
|
||||
# Build all 32-bit and 64-bit wheels natively buildable on the image
|
||||
[tool.cibuildwheel]
|
||||
archs = ["auto64", "auto32"]
|
||||
```
|
||||
|
||||
!!! tab examples "Environment variables"
|
||||
@@ -250,12 +272,13 @@ This option can also be set using the [command-line option](#command-line)
|
||||
|
||||
# On an Linux Intel runner with qemu installed, build Intel and ARM wheels
|
||||
CIBW_ARCHS_LINUX: "auto aarch64"
|
||||
|
||||
# Build all 32-bit and 64-bit wheels natively buildable on the image
|
||||
CIBW_ARCHS: "auto64 auto32"
|
||||
```
|
||||
|
||||
Separate multiple archs with a space.
|
||||
|
||||
|
||||
|
||||
It is generally recommended to use the environment variable or
|
||||
command-line option for Linux, as selecting archs often depends
|
||||
on your specific runner having qemu installed.
|
||||
|
||||
+2
-1
@@ -175,6 +175,7 @@ def expected_wheels(
|
||||
include_universal2: bool = False,
|
||||
single_python: bool = False,
|
||||
single_arch: bool = False,
|
||||
full_auto: bool = False,
|
||||
) -> list[str]:
|
||||
"""
|
||||
Returns the expected wheels from a run of cibuildwheel.
|
||||
@@ -194,7 +195,7 @@ def expected_wheels(
|
||||
|
||||
architectures = [machine_arch]
|
||||
if not single_arch:
|
||||
if platform == "linux":
|
||||
if platform == "linux" and full_auto:
|
||||
if machine_arch == "x86_64":
|
||||
architectures.append("i686")
|
||||
elif (
|
||||
|
||||
@@ -34,8 +34,8 @@ def test_arch_auto(platform_machine):
|
||||
arch_set = Architecture.auto_archs("linux")
|
||||
expected = {
|
||||
"32": {Architecture.i686},
|
||||
"64": {Architecture.x86_64, Architecture.i686},
|
||||
"arm": {Architecture.aarch64, Architecture.armv7l},
|
||||
"64": {Architecture.x86_64},
|
||||
"arm": {Architecture.aarch64},
|
||||
}
|
||||
assert arch_set == expected[machine_name]
|
||||
|
||||
@@ -94,5 +94,24 @@ def test_arch_auto_no_aarch32(monkeypatch):
|
||||
arch_set = Architecture.parse_config("auto64", "linux")
|
||||
assert arch_set == {Architecture.aarch64}
|
||||
|
||||
monkeypatch.setattr(cibuildwheel.architecture, "_check_aarch32_el0", lambda: True)
|
||||
arch_set = Architecture.parse_config("auto32", "linux")
|
||||
assert len(arch_set) == 0
|
||||
assert arch_set == {Architecture.armv7l}
|
||||
|
||||
monkeypatch.setattr(cibuildwheel.architecture, "_check_aarch32_el0", lambda: False)
|
||||
arch_set = Architecture.parse_config("auto32", "linux")
|
||||
assert arch_set == set()
|
||||
|
||||
|
||||
def test_arch_native_on_ios(monkeypatch):
|
||||
monkeypatch.setattr(sys, "platform", "darwin")
|
||||
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
|
||||
arch_set = Architecture.parse_config("native", platform="ios")
|
||||
assert arch_set == {Architecture.arm64_iphonesimulator}
|
||||
|
||||
|
||||
def test_arch_auto_on_ios(monkeypatch):
|
||||
monkeypatch.setattr(sys, "platform", "darwin")
|
||||
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
|
||||
arch_set = Architecture.parse_config("auto", platform="ios")
|
||||
assert arch_set == {Architecture.arm64_iphonesimulator, Architecture.arm64_iphoneos}
|
||||
|
||||
@@ -79,7 +79,7 @@ def test_archs_default(platform, intercepted_build_args):
|
||||
options = intercepted_build_args.args[0]
|
||||
|
||||
if platform == "linux":
|
||||
assert options.globals.architectures == {Architecture.x86_64, Architecture.i686}
|
||||
assert options.globals.architectures == {Architecture.x86_64}
|
||||
elif platform == "windows":
|
||||
assert options.globals.architectures == {Architecture.AMD64, Architecture.x86}
|
||||
else:
|
||||
|
||||
@@ -51,6 +51,7 @@ def mock_build_container(monkeypatch):
|
||||
@pytest.mark.usefixtures("mock_build_container", "fake_package_dir")
|
||||
def test_build_default_launches(monkeypatch):
|
||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--platform=linux"])
|
||||
monkeypatch.setenv("CIBW_ARCHS", "auto64 auto32")
|
||||
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
||||
|
||||
main()
|
||||
@@ -105,6 +106,7 @@ def test_build_with_override_launches(monkeypatch, tmp_path):
|
||||
manylinux-x86_64-image = "manylinux_2_28"
|
||||
musllinux-x86_64-image = "musllinux_1_2"
|
||||
enable = ["pypy", "pypy-eol", "graalpy", "cpython-freethreading"]
|
||||
archs = ["auto64", "auto32"]
|
||||
|
||||
# Before Python 3.10, use manylinux2014
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
|
||||
@@ -25,6 +25,7 @@ PYPROJECT_1 = """
|
||||
[tool.cibuildwheel]
|
||||
build = ["cp38-*", "cp313-*"]
|
||||
skip = ["*musllinux*"]
|
||||
archs = ["auto64", "auto32"]
|
||||
environment = {FOO="BAR"}
|
||||
|
||||
test-command = "pyproject"
|
||||
|
||||
Reference in New Issue
Block a user