Skip to content

Commit 36049d8

Browse files
feature: add musllinux_1_2 support (#1561)
* feature: add musllinux_1_2 support * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix[test]: clean-up docker images in test_*linux*_only.py We are reaching disk space limits (14 GB) when running tests. Add a fixture to clean-up docker images after tests. This fixture is applied on tests that pull a specific image for one test only in order not to take too much time pulling that image many times. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 229f857 commit 36049d8

9 files changed

+147
-32
lines changed

bin/update_docker.py

+6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ class Image:
5959
Image("musllinux_1_1", "aarch64", "quay.io/pypa/musllinux_1_1_aarch64", None),
6060
Image("musllinux_1_1", "ppc64le", "quay.io/pypa/musllinux_1_1_ppc64le", None),
6161
Image("musllinux_1_1", "s390x", "quay.io/pypa/musllinux_1_1_s390x", None),
62+
# musllinux_1_2 images
63+
Image("musllinux_1_2", "x86_64", "quay.io/pypa/musllinux_1_2_x86_64", None),
64+
Image("musllinux_1_2", "i686", "quay.io/pypa/musllinux_1_2_i686", None),
65+
Image("musllinux_1_2", "aarch64", "quay.io/pypa/musllinux_1_2_aarch64", None),
66+
Image("musllinux_1_2", "ppc64le", "quay.io/pypa/musllinux_1_2_ppc64le", None),
67+
Image("musllinux_1_2", "s390x", "quay.io/pypa/musllinux_1_2_s390x", None),
6268
]
6369

6470
config = configparser.ConfigParser()
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,54 @@
11
[x86_64]
22
manylinux1 = quay.io/pypa/manylinux1_x86_64:2023-06-25-d2e0575
33
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
4-
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-07-14-55e4124
4+
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-07-29-8793e83
55
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
6-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-07-14-55e4124
7-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2023-07-14-55e4124
6+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-07-29-8793e83
7+
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2023-07-29-8793e83
8+
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2023-07-29-8793e83
89

910
[i686]
1011
manylinux1 = quay.io/pypa/manylinux1_i686:2023-06-25-d2e0575
1112
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
12-
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-07-14-55e4124
13+
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-07-29-8793e83
1314
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
14-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2023-07-14-55e4124
15+
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2023-07-29-8793e83
16+
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2023-07-29-8793e83
1517

1618
[pypy_x86_64]
1719
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
18-
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-07-14-55e4124
20+
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-07-29-8793e83
1921
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
20-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-07-14-55e4124
22+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-07-29-8793e83
2123

2224
[pypy_i686]
2325
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
24-
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-07-14-55e4124
26+
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-07-29-8793e83
2527
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
2628

2729
[aarch64]
28-
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-07-14-55e4124
30+
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-07-29-8793e83
2931
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
30-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-07-14-55e4124
31-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2023-07-14-55e4124
32+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-07-29-8793e83
33+
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2023-07-29-8793e83
34+
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2023-07-29-8793e83
3235

3336
[ppc64le]
34-
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2023-07-14-55e4124
37+
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2023-07-29-8793e83
3538
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463
36-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2023-07-14-55e4124
37-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2023-07-14-55e4124
39+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2023-07-29-8793e83
40+
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2023-07-29-8793e83
41+
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2023-07-29-8793e83
3842

3943
[s390x]
40-
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2023-07-14-55e4124
44+
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2023-07-29-8793e83
4145
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463
42-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2023-07-14-55e4124
43-
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2023-07-14-55e4124
46+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2023-07-29-8793e83
47+
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2023-07-29-8793e83
48+
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2023-07-29-8793e83
4449

4550
[pypy_aarch64]
46-
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-07-14-55e4124
51+
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-07-29-8793e83
4752
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
48-
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-07-14-55e4124
53+
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-07-29-8793e83
4954

docs/options.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ Set an alternative Docker image to be used for building [manylinux / musllinux](
981981
For `CIBW_MANYLINUX_*_IMAGE`, the value of this option can either be set to `manylinux1`, `manylinux2010`, `manylinux2014`, `manylinux_2_24` or `manylinux_2_28` to use a pinned version of the [official manylinux images](https://github.com/pypa/manylinux). Alternatively, set these options to any other valid Docker image name. For PyPy, the `manylinux1` image is not available. For architectures other
982982
than x86 (x86\_64 and i686) `manylinux2014`, `manylinux_2_24` or `manylinux_2_28` must be used, because the first version of the manylinux specification that supports additional architectures is `manylinux2014`. `manylinux_2_28` is not supported for `i686` architecture.
983983

984-
For `CIBW_MUSLLINUX_*_IMAGE`, the value of this option can either be set to `musllinux_1_1` to use a pinned version of the [official musllinux images](https://github.com/pypa/musllinux). Alternatively, set these options to any other valid Docker image name.
984+
For `CIBW_MUSLLINUX_*_IMAGE`, the value of this option can either be set to `musllinux_1_1` or `musllinux_1_2` to use a pinned version of the [official musllinux images](https://github.com/pypa/musllinux). Alternatively, set these options to any other valid Docker image name.
985985

986986
If this option is blank, it will fall though to the next available definition (environment variable -> pyproject.toml -> default).
987987

test/conftest.py

+34
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
from __future__ import annotations
22

3+
import json
4+
import subprocess
5+
from typing import Generator
6+
37
import pytest
48

9+
from cibuildwheel.util import detect_ci_provider
10+
11+
from .utils import platform
12+
513

614
def pytest_addoption(parser) -> None:
715
parser.addoption(
@@ -21,3 +29,29 @@ def pytest_addoption(parser) -> None:
2129
)
2230
def build_frontend_env(request) -> dict[str, str]:
2331
return request.param # type: ignore[no-any-return]
32+
33+
34+
@pytest.fixture()
35+
def docker_cleanup() -> Generator[None, None, None]:
36+
def get_images() -> set[str]:
37+
images = subprocess.run(
38+
["docker", "image", "ls", "--format", "{{json .ID}}"],
39+
text=True,
40+
check=True,
41+
stdout=subprocess.PIPE,
42+
).stdout
43+
return {json.loads(image.strip()) for image in images.splitlines() if image.strip()}
44+
45+
if detect_ci_provider() is None or platform != "linux":
46+
try:
47+
yield
48+
finally:
49+
pass
50+
return
51+
images_before = get_images()
52+
try:
53+
yield
54+
finally:
55+
images_after = get_images()
56+
for image in images_after - images_before:
57+
subprocess.run(["docker", "rmi", image], check=False)

test/test_container_images.py

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
)
2424

2525

26+
@pytest.mark.usefixtures("docker_cleanup")
2627
def test(tmp_path):
2728
if utils.platform != "linux":
2829
pytest.skip("the test is only relevant to the linux build")

test/test_manylinuxXXXX_only.py

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"manylinux_image",
5454
["manylinux1", "manylinux2010", "manylinux2014", "manylinux_2_24", "manylinux_2_28"],
5555
)
56+
@pytest.mark.usefixtures("docker_cleanup")
5657
def test(manylinux_image, tmp_path):
5758
if utils.platform != "linux":
5859
pytest.skip("the container image test is only relevant to the linux build")

test/test_musllinux_X_Y_only.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from __future__ import annotations
2+
3+
import textwrap
4+
5+
import pytest
6+
7+
from . import test_projects, utils
8+
9+
project_with_manylinux_symbols = test_projects.new_c_project(
10+
spam_c_top_level_add=textwrap.dedent(
11+
r"""
12+
#include <stdlib.h>
13+
14+
#if defined(__GLIBC_PREREQ)
15+
#error "Must not run on a glibc linux environment"
16+
#endif
17+
"""
18+
),
19+
spam_c_function_add=textwrap.dedent(
20+
r"""
21+
sts = 0;
22+
"""
23+
),
24+
)
25+
26+
27+
@pytest.mark.parametrize(
28+
"musllinux_image",
29+
["musllinux_1_1", "musllinux_1_2"],
30+
)
31+
@pytest.mark.usefixtures("docker_cleanup")
32+
def test(musllinux_image, tmp_path):
33+
if utils.platform != "linux":
34+
pytest.skip("the container image test is only relevant to the linux build")
35+
36+
project_dir = tmp_path / "project"
37+
project_with_manylinux_symbols.generate(project_dir)
38+
39+
# build the wheels
40+
add_env = {
41+
"CIBW_BUILD": "*-musllinux*",
42+
"CIBW_MUSLLINUX_X86_64_IMAGE": musllinux_image,
43+
"CIBW_MUSLLINUX_I686_IMAGE": musllinux_image,
44+
"CIBW_MUSLLINUX_AARCH64_IMAGE": musllinux_image,
45+
"CIBW_MUSLLINUX_PPC64LE_IMAGE": musllinux_image,
46+
"CIBW_MUSLLINUX_S390X_IMAGE": musllinux_image,
47+
}
48+
49+
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
50+
expected_wheels = utils.expected_wheels(
51+
"spam",
52+
"0.1.0",
53+
manylinux_versions=[],
54+
musllinux_versions=[musllinux_image],
55+
)
56+
assert set(actual_wheels) == set(expected_wheels)

test/utils.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,14 @@ def expected_wheels(
205205
if machine_arch == "x86_64":
206206
architectures.append("i686")
207207

208-
platform_tags = [
209-
".".join(
210-
f"{manylinux_version}_{architecture}"
211-
for manylinux_version in manylinux_versions
212-
)
213-
for architecture in architectures
214-
]
208+
if len(manylinux_versions) > 0:
209+
platform_tags = [
210+
".".join(
211+
f"{manylinux_version}_{architecture}"
212+
for manylinux_version in manylinux_versions
213+
)
214+
for architecture in architectures
215+
]
215216
if len(musllinux_versions) > 0 and not python_abi_tag.startswith("pp"):
216217
platform_tags.extend(
217218
[

unit_test/option_prepare_test.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,15 @@ def test_build_with_override_launches(monkeypatch, tmp_path):
101101
cibw_toml.write_text(
102102
"""
103103
[tool.cibuildwheel]
104-
manylinux-x86_64-image = "manylinux_2_24"
104+
manylinux-x86_64-image = "manylinux_2_28"
105+
musllinux-x86_64-image = "musllinux_1_2"
105106
106-
# Before Python 3.10, use manylinux2014
107+
# Before Python 3.10, use manylinux2014, musllinux_1_1
107108
[[tool.cibuildwheel.overrides]]
108109
select = "cp3?-*"
109110
manylinux-x86_64-image = "manylinux2014"
110111
manylinux-i686-image = "manylinux2014"
112+
musllinux-x86_64-image = "musllinux_1_1"
111113
112114
[[tool.cibuildwheel.overrides]]
113115
select = "cp36-manylinux_x86_64"
@@ -122,7 +124,7 @@ def test_build_with_override_launches(monkeypatch, tmp_path):
122124

123125
build_in_container = typing.cast(mock.Mock, linux.build_in_container)
124126

125-
assert build_in_container.call_count == 6
127+
assert build_in_container.call_count == 7
126128

127129
kwargs = build_in_container.call_args_list[0][1]
128130
assert "quay.io/pypa/manylinux2014_x86_64" in kwargs["container"]["image"]
@@ -146,7 +148,7 @@ def test_build_with_override_launches(monkeypatch, tmp_path):
146148
assert kwargs["options"].build_options("cp37-manylinux_x86_64").before_all == ""
147149

148150
kwargs = build_in_container.call_args_list[2][1]
149-
assert "quay.io/pypa/manylinux_2_24_x86_64" in kwargs["container"]["image"]
151+
assert "quay.io/pypa/manylinux_2_28_x86_64" in kwargs["container"]["image"]
150152
assert kwargs["container"]["cwd"] == PurePosixPath("/project")
151153
assert not kwargs["container"]["simulate_32_bit"]
152154
identifiers = {x.identifier for x in kwargs["platform_configs"]}
@@ -169,10 +171,19 @@ def test_build_with_override_launches(monkeypatch, tmp_path):
169171

170172
identifiers = {x.identifier for x in kwargs["platform_configs"]}
171173
assert identifiers == {
172-
f"{x}-musllinux_x86_64" for x in ALL_IDS for x in ALL_IDS if "pp" not in x
174+
f"{x}-musllinux_x86_64" for x in ALL_IDS & {"cp36", "cp37", "cp38", "cp39"} if "pp" not in x
173175
}
174176

175177
kwargs = build_in_container.call_args_list[5][1]
178+
assert "quay.io/pypa/musllinux_1_2_x86_64" in kwargs["container"]["image"]
179+
assert kwargs["container"]["cwd"] == PurePosixPath("/project")
180+
assert not kwargs["container"]["simulate_32_bit"]
181+
identifiers = {x.identifier for x in kwargs["platform_configs"]}
182+
assert identifiers == {
183+
f"{x}-musllinux_x86_64" for x in ALL_IDS - {"cp36", "cp37", "cp38", "cp39"} if "pp" not in x
184+
}
185+
186+
kwargs = build_in_container.call_args_list[6][1]
176187
assert "quay.io/pypa/musllinux_1_1_i686" in kwargs["container"]["image"]
177188
assert kwargs["container"]["cwd"] == PurePosixPath("/project")
178189
assert kwargs["container"]["simulate_32_bit"]

0 commit comments

Comments
 (0)