diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index c9134e7e..e0f4add2 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -110,6 +110,29 @@ def get_build_steps( yield from steps.values() +def check_all_python_exist( + *, platform_configs: list[PythonConfiguration], container: OCIContainer +) -> None: + exist = True + messages = [] + for config in platform_configs: + python_path = config.path / "bin" / "python" + try: + container.call(["test", "-x", python_path]) + except subprocess.CalledProcessError: + messages.append( + f" '{python_path}' executable doesn't exist in image '{container.image}' to build '{config.identifier}'." + ) + exist = False + if not exist: + message = "\n".join(messages) + print( + f"cibuildwheel:\n{message}", + file=sys.stderr, + ) + sys.exit(1) + + def build_in_container( *, options: Options, @@ -120,6 +143,8 @@ def build_in_container( ) -> None: container_output_dir = PurePosixPath("/output") + check_all_python_exist(platform_configs=platform_configs, container=container) + log.step("Copying project into container...") container.copy_into(Path.cwd(), container_project_path) diff --git a/test/test_linux_python.py b/test/test_linux_python.py new file mode 100644 index 00000000..7b642916 --- /dev/null +++ b/test/test_linux_python.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +import platform +import subprocess + +import pytest + +from . import test_projects, utils + + +def test_python_exist(tmp_path, capfd): + if utils.platform != "linux": + pytest.skip("the test is only relevant to the linux build") + machine = platform.machine() + if machine not in ["x86_64", "i686"]: + pytest.skip( + "this test is currently only possible on x86_64/i686 due to availability of alternative images" + ) + + project_dir = tmp_path / "project" + basic_project = test_projects.new_c_project() + basic_project.generate(project_dir) + + with pytest.raises(subprocess.CalledProcessError): + utils.cibuildwheel_run( + project_dir, + add_env={ + "CIBW_MANYLINUX_X86_64_IMAGE": "manylinux2010", + "CIBW_MANYLINUX_I686_IMAGE": "manylinux2010", + "CIBW_BUILD": "cp3{10,11}-manylinux*", + }, + ) + + captured = capfd.readouterr() + print("out", captured.out) + print("err", captured.err) + assert f" to build 'cp310-manylinux_{machine}'." not in captured.err + message = ( + "'/opt/python/cp311-cp311/bin/python' executable doesn't exist" + f" in image 'quay.io/pypa/manylinux2010_{machine}:2022-08-05-4535177'" + f" to build 'cp311-manylinux_{machine}'." + ) + assert message in captured.err