feat: add musllinux armv7l (#2017)

* feature: add musllinux armv7l

* fix: local armv7l images

* fix python 3.8 tests

* address review comments

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
This commit is contained in:
Matthieu Darbois
2024-10-01 10:33:57 -04:00
committed by GitHub
co-authored by Henry Schreiner
parent dfd01af9aa
commit 9fad66fcfb
16 changed files with 126 additions and 63 deletions
+14 -14
View File
@@ -22,20 +22,20 @@ Python wheels are great. Building them across **Mac, Linux, Windows**, on **mult
What does it do? What does it do?
---------------- ----------------
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x | Pyodide | | | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x | musllinux armv7l | Pyodide |
|----------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|-----| |----------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|---|-----|
| CPython 3.6 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.6 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| CPython 3.7 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.7 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁴ | | CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁴ |
| CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A | | CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | | PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | | PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | | PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | | PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
<sup>¹ PyPy is only supported for manylinux wheels.</sup><br> <sup>¹ PyPy is only supported for manylinux wheels.</sup><br>
<sup>² Windows arm64 support is experimental.</sup><br> <sup>² Windows arm64 support is experimental.</sup><br>
+3
View File
@@ -137,6 +137,9 @@ properties:
musllinux-aarch64-image: musllinux-aarch64-image:
type: string type: string
description: Specify alternative manylinux / musllinux container images description: Specify alternative manylinux / musllinux container images
musllinux-armv7l-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-i686-image: musllinux-i686-image:
type: string type: string
description: Specify alternative manylinux / musllinux container images description: Specify alternative manylinux / musllinux container images
+1
View File
@@ -65,6 +65,7 @@ images = [
Image("musllinux_1_2", "aarch64", "quay.io/pypa/musllinux_1_2_aarch64", None), Image("musllinux_1_2", "aarch64", "quay.io/pypa/musllinux_1_2_aarch64", None),
Image("musllinux_1_2", "ppc64le", "quay.io/pypa/musllinux_1_2_ppc64le", None), Image("musllinux_1_2", "ppc64le", "quay.io/pypa/musllinux_1_2_ppc64le", None),
Image("musllinux_1_2", "s390x", "quay.io/pypa/musllinux_1_2_s390x", None), Image("musllinux_1_2", "s390x", "quay.io/pypa/musllinux_1_2_s390x", None),
Image("musllinux_1_2", "armv7l", "quay.io/pypa/musllinux_1_2_armv7l", None),
] ]
config = configparser.ConfigParser() config = configparser.ConfigParser()
+5 -5
View File
@@ -37,6 +37,7 @@ class Architecture(Enum):
aarch64 = "aarch64" aarch64 = "aarch64"
ppc64le = "ppc64le" ppc64le = "ppc64le"
s390x = "s390x" s390x = "s390x"
armv7l = "armv7l"
# mac archs # mac archs
universal2 = "universal2" universal2 = "universal2"
@@ -132,6 +133,7 @@ class Architecture(Enum):
Architecture.aarch64, Architecture.aarch64,
Architecture.ppc64le, Architecture.ppc64le,
Architecture.s390x, Architecture.s390x,
Architecture.armv7l,
}, },
"macos": {Architecture.x86_64, Architecture.arm64, Architecture.universal2}, "macos": {Architecture.x86_64, Architecture.arm64, Architecture.universal2},
"windows": {Architecture.x86, Architecture.AMD64, Architecture.ARM64}, "windows": {Architecture.x86, Architecture.AMD64, Architecture.ARM64},
@@ -140,17 +142,15 @@ class Architecture(Enum):
return all_archs_map[platform] return all_archs_map[platform]
@staticmethod @staticmethod
# pylint: disable-next=inconsistent-return-statements
def bitness_archs(platform: PlatformName, bitness: Literal["64", "32"]) -> set[Architecture]: def bitness_archs(platform: PlatformName, bitness: Literal["64", "32"]) -> set[Architecture]:
archs_32 = {Architecture.i686, Architecture.x86} archs_32 = {Architecture.i686, Architecture.x86, Architecture.armv7l}
auto_archs = Architecture.auto_archs(platform) auto_archs = Architecture.auto_archs(platform)
if bitness == "64": if bitness == "64":
return auto_archs - archs_32 return auto_archs - archs_32
elif bitness == "32": if bitness == "32":
return auto_archs & archs_32 return auto_archs & archs_32
else: assert_never(bitness)
assert_never(bitness)
def allowed_architectures_check( def allowed_architectures_check(
+1
View File
@@ -35,6 +35,7 @@ ARCHITECTURE_OCI_PLATFORM_MAP = {
Architecture.aarch64: OCIPlatform.ARM64, Architecture.aarch64: OCIPlatform.ARM64,
Architecture.ppc64le: OCIPlatform.PPC64LE, Architecture.ppc64le: OCIPlatform.PPC64LE,
Architecture.s390x: OCIPlatform.S390X, Architecture.s390x: OCIPlatform.S390X,
Architecture.armv7l: OCIPlatform.ARMV7,
} }
+2 -1
View File
@@ -27,7 +27,8 @@ PLATFORM_IDENTIFIER_DESCRIPTIONS: Final[dict[str, str]] = {
"musllinux_i686": "musllinux i686", "musllinux_i686": "musllinux i686",
"musllinux_aarch64": "musllinux aarch64", "musllinux_aarch64": "musllinux aarch64",
"musllinux_ppc64le": "musllinux ppc64le", "musllinux_ppc64le": "musllinux ppc64le",
"musllinux_s390x": "manylinux s390x", "musllinux_s390x": "musllinux s390x",
"musllinux_armv7l": "musllinux armv7l",
"win32": "Windows 32bit", "win32": "Windows 32bit",
"win_amd64": "Windows 64bit", "win_amd64": "Windows 64bit",
"win_arm64": "Windows on ARM 64bit", "win_arm64": "Windows on ARM 64bit",
+15 -9
View File
@@ -38,6 +38,7 @@ ContainerEngineName = Literal["docker", "podman"]
class OCIPlatform(Enum): class OCIPlatform(Enum):
i386 = "linux/386" i386 = "linux/386"
AMD64 = "linux/amd64" AMD64 = "linux/amd64"
ARMV7 = "linux/arm/v7"
ARM64 = "linux/arm64" ARM64 = "linux/arm64"
PPC64LE = "linux/ppc64le" PPC64LE = "linux/ppc64le"
S390X = "linux/s390x" S390X = "linux/s390x"
@@ -208,7 +209,11 @@ class OCIContainer:
"inspect", "inspect",
self.image, self.image,
"--format", "--format",
"{{.Os}}/{{.Architecture}}", (
"{{.Os}}/{{.Architecture}}/{{.Variant}}"
if len(oci_platform.value.split("/")) == 3
else "{{.Os}}/{{.Architecture}}"
),
capture_stdout=True, capture_stdout=True,
).strip() ).strip()
if image_platform == oci_platform.value: if image_platform == oci_platform.value:
@@ -235,7 +240,7 @@ class OCIContainer:
platform_args = self._get_platform_args() platform_args = self._get_platform_args()
simulate_32_bit = False simulate_32_bit = False
if self.oci_platform == OCIPlatform.i386: if self.oci_platform in {OCIPlatform.i386, OCIPlatform.ARMV7}:
# If the architecture running the image is already the right one # If the architecture running the image is already the right one
# or the image entrypoint takes care of enforcing this, then we don't need to # or the image entrypoint takes care of enforcing this, then we don't need to
# simulate this # simulate this
@@ -246,13 +251,14 @@ class OCIContainer:
*run_cmd, *platform_args, self.image, *ctr_cmd, capture_stdout=True *run_cmd, *platform_args, self.image, *ctr_cmd, capture_stdout=True
).strip() ).strip()
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
# The image might have been built with amd64 architecture if self.oci_platform == OCIPlatform.i386:
# Let's try that # The image might have been built with amd64 architecture
platform_args = self._get_platform_args(oci_platform=OCIPlatform.AMD64) # Let's try that
container_machine = call( platform_args = self._get_platform_args(oci_platform=OCIPlatform.AMD64)
*run_cmd, *platform_args, self.image, *ctr_cmd, capture_stdout=True container_machine = call(
).strip() *run_cmd, *platform_args, self.image, *ctr_cmd, capture_stdout=True
simulate_32_bit = container_machine != "i686" ).strip()
simulate_32_bit = container_machine not in {"i686", "armv7l", "armv8l"}
shell_args = ["linux32", "/bin/bash"] if simulate_32_bit else ["/bin/bash"] shell_args = ["linux32", "/bin/bash"] if simulate_32_bit else ["/bin/bash"]
@@ -102,6 +102,15 @@ python_configurations = [
{ identifier = "cp312-musllinux_s390x", version = "3.12", path_str = "/opt/python/cp312-cp312" }, { identifier = "cp312-musllinux_s390x", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp313-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313t" }, { identifier = "cp313t-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-musllinux_armv7l", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-musllinux_armv7l", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-musllinux_armv7l", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-musllinux_armv7l", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-musllinux_armv7l", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_armv7l", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_armv7l", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
] ]
[macos] [macos]
@@ -312,6 +312,11 @@
"description": "Specify alternative manylinux / musllinux container images", "description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_AARCH64_IMAGE" "title": "CIBW_MUSLLINUX_AARCH64_IMAGE"
}, },
"musllinux-armv7l-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_ARMV7L_IMAGE"
},
"musllinux-i686-image": { "musllinux-i686-image": {
"type": "string", "type": "string",
"description": "Specify alternative manylinux / musllinux container images", "description": "Specify alternative manylinux / musllinux container images",
@@ -542,6 +547,9 @@
"musllinux-aarch64-image": { "musllinux-aarch64-image": {
"$ref": "#/properties/musllinux-aarch64-image" "$ref": "#/properties/musllinux-aarch64-image"
}, },
"musllinux-armv7l-image": {
"$ref": "#/properties/musllinux-armv7l-image"
},
"musllinux-i686-image": { "musllinux-i686-image": {
"$ref": "#/properties/musllinux-i686-image" "$ref": "#/properties/musllinux-i686-image"
}, },
@@ -630,6 +638,9 @@
"musllinux-aarch64-image": { "musllinux-aarch64-image": {
"$ref": "#/properties/musllinux-aarch64-image" "$ref": "#/properties/musllinux-aarch64-image"
}, },
"musllinux-armv7l-image": {
"$ref": "#/properties/musllinux-armv7l-image"
},
"musllinux-i686-image": { "musllinux-i686-image": {
"$ref": "#/properties/musllinux-i686-image" "$ref": "#/properties/musllinux-i686-image"
}, },
+1
View File
@@ -37,6 +37,7 @@ musllinux-i686-image = "musllinux_1_2"
musllinux-aarch64-image = "musllinux_1_2" musllinux-aarch64-image = "musllinux_1_2"
musllinux-ppc64le-image = "musllinux_1_2" musllinux-ppc64le-image = "musllinux_1_2"
musllinux-s390x-image = "musllinux_1_2" musllinux-s390x-image = "musllinux_1_2"
musllinux-armv7l-image = "musllinux_1_2"
[tool.cibuildwheel.linux] [tool.cibuildwheel.linux]
@@ -52,3 +52,6 @@ manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.09.28-3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.09.28-3 manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.09.28-3
[armv7l]
musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2024.09.22-4
+1
View File
@@ -83,6 +83,7 @@ MUSLLINUX_ARCHS: Final[tuple[str, ...]] = (
"aarch64", "aarch64",
"ppc64le", "ppc64le",
"s390x", "s390x",
"armv7l",
) )
DEFAULT_CIBW_CACHE_PATH: Final[Path] = user_cache_path(appname="cibuildwheel", appauthor="pypa") DEFAULT_CIBW_CACHE_PATH: Final[Path] = user_cache_path(appname="cibuildwheel", appauthor="pypa")
+18 -17
View File
@@ -288,20 +288,20 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
<div class="build-id-table-marker"></div> <div class="build-id-table-marker"></div>
| | macOS | Windows | Linux Intel | Linux Other | | | macOS | Windows | Linux Intel | Linux Other |
|---------------|------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| |---------------|------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686<br/>cp36-musllinux_x86_64<br/>cp36-musllinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x<br/>cp36-musllinux_aarch64<br/>cp36-musllinux_ppc64le<br/>cp36-musllinux_s390x | | Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686<br/>cp36-musllinux_x86_64<br/>cp36-musllinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x<br/>cp36-musllinux_aarch64<br/>cp36-musllinux_ppc64le<br/>cp36-musllinux_s390x<br/>cp36-musllinux_armv7l |
| Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686<br/>cp37-musllinux_x86_64<br/>cp37-musllinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x<br/>cp37-musllinux_aarch64<br/>cp37-musllinux_ppc64le<br/>cp37-musllinux_s390x | | Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686<br/>cp37-musllinux_x86_64<br/>cp37-musllinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x<br/>cp37-musllinux_aarch64<br/>cp37-musllinux_ppc64le<br/>cp37-musllinux_s390x<br/>cp37-musllinux_armv7l |
| Python 3.8 | cp38-macosx_x86_64<br/>cp38-macosx_universal2<br/>cp38-macosx_arm64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686<br/>cp38-musllinux_x86_64<br/>cp38-musllinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x<br/>cp38-musllinux_aarch64<br/>cp38-musllinux_ppc64le<br/>cp38-musllinux_s390x | | Python 3.8 | cp38-macosx_x86_64<br/>cp38-macosx_universal2<br/>cp38-macosx_arm64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686<br/>cp38-musllinux_x86_64<br/>cp38-musllinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x<br/>cp38-musllinux_aarch64<br/>cp38-musllinux_ppc64le<br/>cp38-musllinux_s390x<br/>cp38-musllinux_armv7l |
| Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32<br/>cp39-win_arm64 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686<br/>cp39-musllinux_x86_64<br/>cp39-musllinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x<br/>cp39-musllinux_aarch64<br/>cp39-musllinux_ppc64le<br/>cp39-musllinux_s390x | | Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32<br/>cp39-win_arm64 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686<br/>cp39-musllinux_x86_64<br/>cp39-musllinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x<br/>cp39-musllinux_aarch64<br/>cp39-musllinux_ppc64le<br/>cp39-musllinux_s390x<br/>cp39-musllinux_armv7l |
| Python 3.10 | cp310-macosx_x86_64<br/>cp310-macosx_universal2<br/>cp310-macosx_arm64 | cp310-win_amd64<br/>cp310-win32<br/>cp310-win_arm64 | cp310-manylinux_x86_64<br/>cp310-manylinux_i686<br/>cp310-musllinux_x86_64<br/>cp310-musllinux_i686 | cp310-manylinux_aarch64<br/>cp310-manylinux_ppc64le<br/>cp310-manylinux_s390x<br/>cp310-musllinux_aarch64<br/>cp310-musllinux_ppc64le<br/>cp310-musllinux_s390x | | Python 3.10 | cp310-macosx_x86_64<br/>cp310-macosx_universal2<br/>cp310-macosx_arm64 | cp310-win_amd64<br/>cp310-win32<br/>cp310-win_arm64 | cp310-manylinux_x86_64<br/>cp310-manylinux_i686<br/>cp310-musllinux_x86_64<br/>cp310-musllinux_i686 | cp310-manylinux_aarch64<br/>cp310-manylinux_ppc64le<br/>cp310-manylinux_s390x<br/>cp310-musllinux_aarch64<br/>cp310-musllinux_ppc64le<br/>cp310-musllinux_s390x<br/>cp310-musllinux_armv7l |
| Python 3.11 | cp311-macosx_x86_64<br/>cp311-macosx_universal2<br/>cp311-macosx_arm64 | cp311-win_amd64<br/>cp311-win32<br/>cp311-win_arm64 | cp311-manylinux_x86_64<br/>cp311-manylinux_i686<br/>cp311-musllinux_x86_64<br/>cp311-musllinux_i686 | cp311-manylinux_aarch64<br/>cp311-manylinux_ppc64le<br/>cp311-manylinux_s390x<br/>cp311-musllinux_aarch64<br/>cp311-musllinux_ppc64le<br/>cp311-musllinux_s390x | | Python 3.11 | cp311-macosx_x86_64<br/>cp311-macosx_universal2<br/>cp311-macosx_arm64 | cp311-win_amd64<br/>cp311-win32<br/>cp311-win_arm64 | cp311-manylinux_x86_64<br/>cp311-manylinux_i686<br/>cp311-musllinux_x86_64<br/>cp311-musllinux_i686 | cp311-manylinux_aarch64<br/>cp311-manylinux_ppc64le<br/>cp311-manylinux_s390x<br/>cp311-musllinux_aarch64<br/>cp311-musllinux_ppc64le<br/>cp311-musllinux_s390x<br/>cp311-musllinux_armv7l |
| Python 3.12 | cp312-macosx_x86_64<br/>cp312-macosx_universal2<br/>cp312-macosx_arm64 | cp312-win_amd64<br/>cp312-win32<br/>cp312-win_arm64 | cp312-manylinux_x86_64<br/>cp312-manylinux_i686<br/>cp312-musllinux_x86_64<br/>cp312-musllinux_i686 | cp312-manylinux_aarch64<br/>cp312-manylinux_ppc64le<br/>cp312-manylinux_s390x<br/>cp312-musllinux_aarch64<br/>cp312-musllinux_ppc64le<br/>cp312-musllinux_s390x | | Python 3.12 | cp312-macosx_x86_64<br/>cp312-macosx_universal2<br/>cp312-macosx_arm64 | cp312-win_amd64<br/>cp312-win32<br/>cp312-win_arm64 | cp312-manylinux_x86_64<br/>cp312-manylinux_i686<br/>cp312-musllinux_x86_64<br/>cp312-musllinux_i686 | cp312-manylinux_aarch64<br/>cp312-manylinux_ppc64le<br/>cp312-manylinux_s390x<br/>cp312-musllinux_aarch64<br/>cp312-musllinux_ppc64le<br/>cp312-musllinux_s390x<br/>cp312-musllinux_armv7l |
| Python 3.13 | cp313-macosx_x86_64<br/>cp313-macosx_universal2<br/>cp313-macosx_arm64 | cp313-win_amd64<br/>cp313-win32<br/>cp313-win_arm64 | cp313-manylinux_x86_64<br/>cp313-manylinux_i686<br/>cp313-musllinux_x86_64<br/>cp313-musllinux_i686 | cp313-manylinux_aarch64<br/>cp313-manylinux_ppc64le<br/>cp313-manylinux_s390x<br/>cp313-musllinux_aarch64<br/>cp313-musllinux_ppc64le<br/>cp313-musllinux_s390x | | Python 3.13 | cp313-macosx_x86_64<br/>cp313-macosx_universal2<br/>cp313-macosx_arm64 | cp313-win_amd64<br/>cp313-win32<br/>cp313-win_arm64 | cp313-manylinux_x86_64<br/>cp313-manylinux_i686<br/>cp313-musllinux_x86_64<br/>cp313-musllinux_i686 | cp313-manylinux_aarch64<br/>cp313-manylinux_ppc64le<br/>cp313-manylinux_s390x<br/>cp313-musllinux_aarch64<br/>cp313-musllinux_ppc64le<br/>cp313-musllinux_s390x<br/>cp313-musllinux_armv7l |
| PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win_amd64 | pp37-manylinux_x86_64<br/>pp37-manylinux_i686 | pp37-manylinux_aarch64 | | PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win_amd64 | pp37-manylinux_x86_64<br/>pp37-manylinux_i686 | pp37-manylinux_aarch64 |
| PyPy3.8 v7.3 | pp38-macosx_x86_64<br/>pp38-macosx_arm64 | pp38-win_amd64 | pp38-manylinux_x86_64<br/>pp38-manylinux_i686 | pp38-manylinux_aarch64 | | PyPy3.8 v7.3 | pp38-macosx_x86_64<br/>pp38-macosx_arm64 | pp38-win_amd64 | pp38-manylinux_x86_64<br/>pp38-manylinux_i686 | pp38-manylinux_aarch64 |
| PyPy3.9 v7.3 | pp39-macosx_x86_64<br/>pp39-macosx_arm64 | pp39-win_amd64 | pp39-manylinux_x86_64<br/>pp39-manylinux_i686 | pp39-manylinux_aarch64 | | PyPy3.9 v7.3 | pp39-macosx_x86_64<br/>pp39-macosx_arm64 | pp39-win_amd64 | pp39-manylinux_x86_64<br/>pp39-manylinux_i686 | pp39-manylinux_aarch64 |
| PyPy3.10 v7.3 | pp310-macosx_x86_64<br/>pp310-macosx_arm64 | pp310-win_amd64 | pp310-manylinux_x86_64<br/>pp310-manylinux_i686 | pp310-manylinux_aarch64 | | PyPy3.10 v7.3 | pp310-macosx_x86_64<br/>pp310-macosx_arm64 | pp310-win_amd64 | pp310-manylinux_x86_64<br/>pp310-manylinux_i686 | pp310-manylinux_aarch64 |
The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to cibuildwheel. The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to cibuildwheel.
The format is `python_tag-platform_tag`, with tags similar to those in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details). The format is `python_tag-platform_tag`, with tags similar to those in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details).
@@ -475,7 +475,7 @@ machine, provided the cross-compiling tools are installed.
Options: Options:
- Linux: `x86_64` `i686` `aarch64` `ppc64le` `s390x` - Linux: `x86_64` `i686` `aarch64` `ppc64le` `s390x` `armv7l`
- macOS: `x86_64` `arm64` `universal2` - macOS: `x86_64` `arm64` `universal2`
- Windows: `AMD64` `x86` `ARM64` - Windows: `AMD64` `x86` `ARM64`
- Pyodide: `wasm32` - Pyodide: `wasm32`
@@ -1174,6 +1174,7 @@ The available options are (default value):
- `CIBW_MUSLLINUX_AARCH64_IMAGE` ([`quay.io/pypa/musllinux_1_2_aarch64`](https://quay.io/pypa/musllinux_1_2_aarch64)) - `CIBW_MUSLLINUX_AARCH64_IMAGE` ([`quay.io/pypa/musllinux_1_2_aarch64`](https://quay.io/pypa/musllinux_1_2_aarch64))
- `CIBW_MUSLLINUX_PPC64LE_IMAGE` ([`quay.io/pypa/musllinux_1_2_ppc64le`](https://quay.io/pypa/musllinux_1_2_ppc64le)) - `CIBW_MUSLLINUX_PPC64LE_IMAGE` ([`quay.io/pypa/musllinux_1_2_ppc64le`](https://quay.io/pypa/musllinux_1_2_ppc64le))
- `CIBW_MUSLLINUX_S390X_IMAGE` ([`quay.io/pypa/musllinux_1_2_s390x`](https://quay.io/pypa/musllinux_1_2_s390x)) - `CIBW_MUSLLINUX_S390X_IMAGE` ([`quay.io/pypa/musllinux_1_2_s390x`](https://quay.io/pypa/musllinux_1_2_s390x))
- `CIBW_MUSLLINUX_ARMV7L_IMAGE` ([`quay.io/pypa/musllinux_1_2_armv7l`](https://quay.io/pypa/musllinux_1_2_armv7l))
Set an alternative Docker image to be used for building [manylinux / musllinux](https://github.com/pypa/manylinux) wheels. Set an alternative Docker image to be used for building [manylinux / musllinux](https://github.com/pypa/manylinux) wheels.
@@ -1599,7 +1600,7 @@ This option is not supported in the overrides section in `pyproject.toml`.
```yaml ```yaml
# Will avoid testing on emulated architectures # Will avoid testing on emulated architectures
CIBW_TEST_SKIP: "*-*linux_{aarch64,ppc64le,s390x}" CIBW_TEST_SKIP: "*-*linux_{aarch64,ppc64le,s390x,armv7l}"
# Skip trying to test arm64 builds on Intel Macs # Skip trying to test arm64 builds on Intel Macs
CIBW_TEST_SKIP: "*-macosx_arm64 *-macosx_universal2:arm64" CIBW_TEST_SKIP: "*-macosx_arm64 *-macosx_universal2:arm64"
@@ -1610,7 +1611,7 @@ This option is not supported in the overrides section in `pyproject.toml`.
```toml ```toml
[tool.cibuildwheel] [tool.cibuildwheel]
# Will avoid testing on emulated architectures # Will avoid testing on emulated architectures
test-skip = "*-*linux_{aarch64,ppc64le,s390x}" test-skip = "*-*linux_{aarch64,ppc64le,s390x,armv7l}"
# Skip trying to test arm64 builds on Intel Macs # Skip trying to test arm64 builds on Intel Macs
test-skip = "*-macosx_arm64 *-macosx_universal2:arm64" test-skip = "*-macosx_arm64 *-macosx_universal2:arm64"
+3 -1
View File
@@ -170,7 +170,9 @@ def expected_wheels(
machine_arch = "aarch64" machine_arch = "aarch64"
if manylinux_versions is None: if manylinux_versions is None:
if machine_arch == "x86_64": if machine_arch == "armv7l":
manylinux_versions = []
elif machine_arch == "x86_64":
manylinux_versions = [ manylinux_versions = [
"manylinux_2_5", "manylinux_2_5",
"manylinux1", "manylinux1",
@@ -179,6 +179,7 @@ def test_archs_platform_all(platform, intercepted_build_args, monkeypatch):
Architecture.aarch64, Architecture.aarch64,
Architecture.ppc64le, Architecture.ppc64le,
Architecture.s390x, Architecture.s390x,
Architecture.armv7l,
} }
elif platform == "windows": elif platform == "windows":
assert options.globals.architectures == { assert options.globals.architectures == {
+38 -16
View File
@@ -535,16 +535,33 @@ def test_disable_host_mount(tmp_path: Path, container_engine, config, should_hav
container.call(["cat", host_mount_path], capture_output=True) container.call(["cat", host_mount_path], capture_output=True)
def test_local_image(container_engine): @pytest.mark.parametrize("platform", list(OCIPlatform))
local_image = f"cibw_test_{container_engine.name}_local:latest" def test_local_image(container_engine, platform, tmp_path: Path):
if (
detect_ci_provider() in {CIProvider.travis_ci}
and pm in {"s390x", "ppc64le"}
and platform != DEFAULT_OCI_PLATFORM
):
pytest.skip("Skipping test because docker on this platform does not support QEMU")
if container_engine.name == "podman" and platform == OCIPlatform.ARMV7:
# both GHA & local macOS arm64 podman desktop are failing
pytest.xfail("podman fails with armv7l images")
remote_image = "debian:12-slim"
platform_name = platform.value.replace("/", "_")
local_image = f"cibw_{container_engine.name}_{platform_name}_local:latest"
dockerfile = tmp_path / "Dockerfile"
dockerfile.write_text(f"FROM {remote_image}")
subprocess.run( subprocess.run(
[container_engine.name, "pull", f"--platform={DEFAULT_OCI_PLATFORM.value}", DEFAULT_IMAGE], [container_engine.name, "pull", f"--platform={platform.value}", remote_image],
check=True, check=True,
) )
subprocess.run([container_engine.name, "image", "tag", DEFAULT_IMAGE, local_image], check=True) subprocess.run(
with OCIContainer( [container_engine.name, "build", f"--platform={platform.value}", "-t", local_image, "."],
engine=container_engine, image=local_image, oci_platform=DEFAULT_OCI_PLATFORM check=True,
): cwd=tmp_path,
)
with OCIContainer(engine=container_engine, image=local_image, oci_platform=platform):
pass pass
@@ -556,27 +573,32 @@ def test_multiarch_image(container_engine, platform):
and platform != DEFAULT_OCI_PLATFORM and platform != DEFAULT_OCI_PLATFORM
): ):
pytest.skip("Skipping test because docker on this platform does not support QEMU") pytest.skip("Skipping test because docker on this platform does not support QEMU")
if container_engine.name == "podman" and platform == OCIPlatform.ARMV7:
# both GHA & local macOS arm64 podman desktop are failing
pytest.xfail("podman fails with armv7l images")
with OCIContainer( with OCIContainer(
engine=container_engine, image="debian:12-slim", oci_platform=platform engine=container_engine, image="debian:12-slim", oci_platform=platform
) as container: ) as container:
output = container.call(["uname", "-m"], capture_output=True) output = container.call(["uname", "-m"], capture_output=True)
output_map = { output_map_kernel = {
OCIPlatform.i386: "i686", OCIPlatform.i386: ("i686",),
OCIPlatform.AMD64: "x86_64", OCIPlatform.AMD64: ("x86_64",),
OCIPlatform.ARM64: "aarch64", OCIPlatform.ARMV7: ("armv7l", "armv8l"),
OCIPlatform.PPC64LE: "ppc64le", OCIPlatform.ARM64: ("aarch64",),
OCIPlatform.S390X: "s390x", OCIPlatform.PPC64LE: ("ppc64le",),
OCIPlatform.S390X: ("s390x",),
} }
assert output_map[platform] == output.strip() assert output.strip() in output_map_kernel[platform]
output = container.call(["dpkg", "--print-architecture"], capture_output=True) output = container.call(["dpkg", "--print-architecture"], capture_output=True)
output_map = { output_map_dpkg = {
OCIPlatform.i386: "i386", OCIPlatform.i386: "i386",
OCIPlatform.AMD64: "amd64", OCIPlatform.AMD64: "amd64",
OCIPlatform.ARMV7: "armhf",
OCIPlatform.ARM64: "arm64", OCIPlatform.ARM64: "arm64",
OCIPlatform.PPC64LE: "ppc64el", OCIPlatform.PPC64LE: "ppc64el",
OCIPlatform.S390X: "s390x", OCIPlatform.S390X: "s390x",
} }
assert output_map[platform] == output.strip() assert output_map_dpkg[platform] == output.strip()
@pytest.mark.parametrize( @pytest.mark.parametrize(