Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cibuildwheel/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,19 @@ class AuditCommandFailedError(FatalError):
def __init__(self, message: str) -> None:
super().__init__(message)
self.return_code = 9


class BuildProducedNoWheelError(FatalError):
def __init__(self) -> None:
message = textwrap.dedent(
"""
Build failed because the build frontend completed successfully but
did not produce a wheel.

This usually indicates a problem with your project configuration or
build backend. Check your project configuration, or run cibuildwheel
with CIBW_BUILD_VERBOSITY=1 to view build logs.
"""
)
super().__init__(message)
self.return_code = 10
8 changes: 6 additions & 2 deletions cibuildwheel/platforms/android.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,10 +410,14 @@ def setup_android_env(
# * a key=value string, without quotes
for i, token in enumerate(shlex.split(env_output)):
if i % 2 == 0:
assert token == "export", token
if token != "export":
msg = f"Unexpected output from android.py env: expected 'export', got {token!r}"
raise errors.FatalError(msg)
else:
key, sep, value = token.partition("=")
assert sep == "=", token
if sep != "=":
msg = f"Unexpected output from android.py env: expected 'key=value', got {token!r}"
raise errors.FatalError(msg)
android_env[key] = value

# localized_vars cleared the CFLAGS and CXXFLAGS in the sysconfigdata, but most
Expand Down
13 changes: 12 additions & 1 deletion cibuildwheel/platforms/ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ def build_python_config(config_dict: dict[str, str]) -> dict[str, str]:
matching = [
config for config in macos_python_configs if config["identifier"] == macos_identifier
]
if not matching:
msg = (
f"Internal error: no macOS configuration found matching "
f"{macos_identifier!r}, needed to build the iOS configuration "
f"{config_dict['identifier']!r}. The bundled build-platforms.toml "
f"resources are inconsistent."
)
raise errors.FatalError(msg)
return matching[0]

# Load the platform configuration
Expand Down Expand Up @@ -560,7 +568,10 @@ def build(options: Options, tmp_path: Path) -> None:
case _:
assert_never(build_frontend)

built_wheel = next(built_wheel_dir.glob("*.whl"))
try:
built_wheel = next(built_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.BuildProducedNoWheelError() from None

if built_wheel.name.endswith("none-any.whl"):
raise errors.NonPlatformWheelError()
Expand Down
5 changes: 4 additions & 1 deletion cibuildwheel/platforms/linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,10 @@ def build_in_container(
case _:
assert_never(build_frontend)

built_wheel = container.glob(built_wheel_dir, "*.whl")[0]
try:
built_wheel = container.glob(built_wheel_dir, "*.whl")[0]
except IndexError:
raise errors.BuildProducedNoWheelError() from None

repaired_wheel_dir = temp_dir / "repaired_wheel"
container.call(["rm", "-rf", repaired_wheel_dir])
Expand Down
5 changes: 4 additions & 1 deletion cibuildwheel/platforms/macos.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,10 @@ def build(options: Options, tmp_path: Path) -> None:
case _:
assert_never(build_frontend)

built_wheel = next(built_wheel_dir.glob("*.whl"))
try:
built_wheel = next(built_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.BuildProducedNoWheelError() from None

repaired_wheel_dir.mkdir()

Expand Down
10 changes: 8 additions & 2 deletions cibuildwheel/platforms/pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,10 @@ def build(options: Options, tmp_path: Path) -> None:
*extra_flags,
env=env,
)
built_wheel = next(built_wheel_dir.glob("*.whl"))
try:
built_wheel = next(built_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.BuildProducedNoWheelError() from None

if built_wheel.name.endswith("none-any.whl"):
raise errors.NonPlatformWheelError()
Expand All @@ -471,7 +474,10 @@ def build(options: Options, tmp_path: Path) -> None:
else:
shutil.move(str(built_wheel), repaired_wheel_dir)

repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
try:
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.RepairStepProducedNoWheelError() from None

if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
Expand Down
5 changes: 4 additions & 1 deletion cibuildwheel/platforms/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,10 @@ def build(options: Options, tmp_path: Path) -> None:
case _:
assert_never(build_frontend)

built_wheel = next(built_wheel_dir.glob("*.whl"))
try:
built_wheel = next(built_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.BuildProducedNoWheelError() from None

# repair the wheel
repaired_wheel_dir.mkdir()
Expand Down
Loading