Merge pull request #1266 from henryiii/henryiii/fix/crossplatform
fix: better cross-platform auto archs
This commit is contained in:
@@ -3,12 +3,19 @@ from __future__ import annotations
|
|||||||
import functools
|
import functools
|
||||||
import platform as platform_module
|
import platform as platform_module
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from .typing import Final, Literal, PlatformName, assert_never
|
from .typing import Final, Literal, PlatformName, assert_never
|
||||||
|
|
||||||
PRETTY_NAMES: Final = {"linux": "Linux", "macos": "macOS", "windows": "Windows"}
|
PRETTY_NAMES: Final = {"linux": "Linux", "macos": "macOS", "windows": "Windows"}
|
||||||
|
|
||||||
|
ARCH_SYNONYMS: Final[list[dict[PlatformName, str | None]]] = [
|
||||||
|
{"linux": "x86_64", "macos": "x86_64", "windows": "AMD64"},
|
||||||
|
{"linux": "i686", "macos": None, "windows": "x86"},
|
||||||
|
{"linux": "aarch64", "macos": "arm64", "windows": "ARM64"},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@functools.total_ordering
|
@functools.total_ordering
|
||||||
class Architecture(Enum):
|
class Architecture(Enum):
|
||||||
@@ -56,14 +63,37 @@ class Architecture(Enum):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def auto_archs(platform: PlatformName) -> set[Architecture]:
|
def auto_archs(platform: PlatformName) -> set[Architecture]:
|
||||||
native_architecture = Architecture(platform_module.machine())
|
native_machine = platform_module.machine()
|
||||||
|
|
||||||
|
# Cross-platform support. Used for --print-build-identifiers or docker builds.
|
||||||
|
host_platform: PlatformName = (
|
||||||
|
"windows"
|
||||||
|
if sys.platform.startswith("win")
|
||||||
|
else ("macos" if sys.platform.startswith("darwin") else "linux")
|
||||||
|
)
|
||||||
|
|
||||||
|
native_architecture = Architecture(native_machine)
|
||||||
|
|
||||||
|
# we might need to rename the native arch to the machine we're running
|
||||||
|
# on, as the same arch can have different names on different platforms
|
||||||
|
if host_platform != platform:
|
||||||
|
for arch_synonym in ARCH_SYNONYMS:
|
||||||
|
if native_machine == arch_synonym.get(host_platform):
|
||||||
|
synonym = arch_synonym[platform]
|
||||||
|
|
||||||
|
if synonym is None:
|
||||||
|
# can't build anything on this platform
|
||||||
|
return set()
|
||||||
|
|
||||||
|
native_architecture = Architecture(synonym)
|
||||||
|
|
||||||
result = {native_architecture}
|
result = {native_architecture}
|
||||||
|
|
||||||
if platform == "linux" and native_architecture == Architecture.x86_64:
|
if platform == "linux" and Architecture.x86_64 in result:
|
||||||
# x86_64 machines can run i686 containers
|
# x86_64 machines can run i686 containers
|
||||||
result.add(Architecture.i686)
|
result.add(Architecture.i686)
|
||||||
|
|
||||||
if platform == "windows" and native_architecture == Architecture.AMD64:
|
if platform == "windows" and Architecture.AMD64 in result:
|
||||||
result.add(Architecture.x86)
|
result.add(Architecture.x86)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import platform as platform_module
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from cibuildwheel.architecture import Architecture
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
params=[
|
||||||
|
pytest.param(("linux", "linux", "x86_64", "64"), id="linux-64"),
|
||||||
|
pytest.param(("linux", "linux", "i686", "32"), id="linux-32"),
|
||||||
|
pytest.param(("linux", "linux", "aarch64", "arm"), id="linux-arm"),
|
||||||
|
pytest.param(("macos", "darwin", "x86_64", "64"), id="macos-64"),
|
||||||
|
pytest.param(("macos", "darwin", "arm64", "arm"), id="macos-arm"),
|
||||||
|
pytest.param(("windows", "win32", "x86", "32"), id="windows-32"),
|
||||||
|
pytest.param(("windows", "win32", "AMD64", "64"), id="windows-64"),
|
||||||
|
pytest.param(("windows", "win32", "ARM64", "arm"), id="windows-arm"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def platform_machine(request, monkeypatch):
|
||||||
|
platform_name, platform_value, machine_value, machine_name = request.param
|
||||||
|
monkeypatch.setattr(sys, "platform", platform_value)
|
||||||
|
monkeypatch.setattr(platform_module, "machine", lambda: machine_value)
|
||||||
|
return platform_name, machine_name
|
||||||
|
|
||||||
|
|
||||||
|
def test_arch_auto(platform_machine):
|
||||||
|
platform_name, machine_name = platform_machine
|
||||||
|
|
||||||
|
arch_set = Architecture.auto_archs("linux")
|
||||||
|
expected = {
|
||||||
|
"32": {Architecture.i686},
|
||||||
|
"64": {Architecture.x86_64, Architecture.i686},
|
||||||
|
"arm": {Architecture.aarch64},
|
||||||
|
}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
arch_set = Architecture.auto_archs("macos")
|
||||||
|
expected = {"32": set(), "64": {Architecture.x86_64}, "arm": {Architecture.arm64}}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
arch_set = Architecture.auto_archs("windows")
|
||||||
|
expected = {
|
||||||
|
"32": {Architecture.x86},
|
||||||
|
"64": {Architecture.AMD64, Architecture.x86},
|
||||||
|
"arm": {Architecture.ARM64},
|
||||||
|
}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
|
||||||
|
def test_arch_auto64(platform_machine):
|
||||||
|
platform_name, machine_name = platform_machine
|
||||||
|
|
||||||
|
arch_set = Architecture.parse_config("auto64", "linux")
|
||||||
|
expected = {"32": set(), "64": {Architecture.x86_64}, "arm": {Architecture.aarch64}}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
arch_set = Architecture.parse_config("auto64", "macos")
|
||||||
|
expected = {"32": set(), "64": {Architecture.x86_64}, "arm": {Architecture.arm64}}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
arch_set = Architecture.parse_config("auto64", "windows")
|
||||||
|
expected = {"32": set(), "64": {Architecture.AMD64}, "arm": {Architecture.ARM64}}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
|
||||||
|
def test_arch_auto32(platform_machine):
|
||||||
|
platform_name, machine_name = platform_machine
|
||||||
|
|
||||||
|
arch_set = Architecture.parse_config("auto32", "linux")
|
||||||
|
expected = {"32": {Architecture.i686}, "64": {Architecture.i686}, "arm": set()}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
|
|
||||||
|
arch_set = Architecture.parse_config("auto32", "macos")
|
||||||
|
assert arch_set == set()
|
||||||
|
|
||||||
|
arch_set = Architecture.parse_config("auto32", "windows")
|
||||||
|
expected = {"32": {Architecture.x86}, "64": {Architecture.x86}, "arm": set()}
|
||||||
|
assert arch_set == expected[machine_name]
|
||||||
Reference in New Issue
Block a user