diff --git a/cibuildwheel/frontend.py b/cibuildwheel/frontend.py
index 8e6a2897f..79796a1be 100644
--- a/cibuildwheel/frontend.py
+++ b/cibuildwheel/frontend.py
@@ -37,14 +37,19 @@ def options_summary(self) -> str | dict[str, str]:
def _get_verbosity_flags(level: int, frontend: BuildFrontendName) -> list[str]:
- if frontend == "pip":
- if level > 0:
- return ["-" + level * "v"]
- if level < 0:
+ if level < 0:
+ if frontend == "pip":
return ["-" + -level * "q"]
- elif not 0 <= level < 2:
+
msg = f"build_verbosity {level} is not supported for {frontend} frontend. Ignoring."
log.warning(msg)
+
+ if level > 0:
+ if frontend == "pip":
+ return ["-" + level * "v"]
+ if level > 1:
+ return ["-" + (level - 1) * "v"]
+
return []
diff --git a/docs/options.md b/docs/options.md
index 0c4ade208..fe2adad84 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -1760,9 +1760,27 @@ export CIBW_DEBUG_TRACEBACK=TRUE
```
### `CIBW_BUILD_VERBOSITY` {: #build-verbosity}
-> Increase/decrease the output of pip wheel
-
-A number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required. Has no effect on the `build` backend, which produces verbose output by default.
+> Increase/decrease the output of the build
+
+This setting controls `-v`/`-q` flags to the build frontend. Since there is
+no communication between the build backend and the build frontend, build
+messages from the build backend will always be shown with `1`; higher levels
+will not produce more logging about the build itself. Other levels only affect
+the build frontend output, which is usually things like resolving and
+downloading dependencies. The settings are:
+
+| | build | pip | desc |
+|-------------|-------|--------|----------------------------------|
+| -2 | N/A | `-qq` | even more quiet, where supported |
+| -1 | N/A | `-q` | quiet mode, where supported |
+| 0 (default) | | | default for build tool |
+| 1 | | `-v` | print backend output |
+| 2 | `-v` | `-vv` | print log messages e.g. resolving info |
+| 3 | `-vv` | `-vvv` | print even more debug info |
+
+Settings that are not supported for a specific frontend will log a warning.
+The default build frontend is `build`, which does show build backend output by
+default.
Platform-specific environment variables are also available:
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX` | `CIBW_BUILD_VERBOSITY_IOS` | `CIBW_BUILD_VERBOSITY_PYODIDE`
@@ -1772,7 +1790,7 @@ Platform-specific environment variables are also available:
!!! tab examples "Environment variables"
```yaml
- # Increase pip debugging output
+ # Ensure that the build backend output is present
CIBW_BUILD_VERBOSITY: 1
```
@@ -1780,7 +1798,7 @@ Platform-specific environment variables are also available:
```toml
[tool.cibuildwheel]
- # Increase pip debugging output
+ # Ensure that the build backend output is present
build-verbosity = 1
```
diff --git a/unit_test/options_test.py b/unit_test/options_test.py
index 143f7fdc0..bcf242916 100644
--- a/unit_test/options_test.py
+++ b/unit_test/options_test.py
@@ -1,12 +1,16 @@
import os
import platform as platform_module
import textwrap
+import unittest.mock
from pathlib import Path
+from typing import Literal
import pytest
from cibuildwheel import errors
from cibuildwheel.bashlex_eval import local_environment_executor
+from cibuildwheel.frontend import BuildFrontendConfig, get_build_frontend_extra_flags
+from cibuildwheel.logger import Logger
from cibuildwheel.options import (
CommandLineArguments,
Options,
@@ -570,3 +574,47 @@ def test_deprecated_image(
assert f"{resolved_image!r}" in captured.err
else:
assert "Deprecated image" not in captured.err
+
+
+@pytest.mark.parametrize(
+ ("frontend", "verbosity", "result"),
+ [
+ ("pip", 3, ["-Ca", "-Cb", "-1", "-vvv"]),
+ ("pip", 2, ["-Ca", "-Cb", "-1", "-vv"]),
+ ("pip", -1, ["-Ca", "-Cb", "-1", "-q"]),
+ ("build", 0, ["-Ca", "-Cb", "-1"]),
+ ("build", 1, ["-Ca", "-Cb", "-1"]),
+ ("build", 2, ["-Ca", "-Cb", "-1", "-v"]),
+ ("build", 3, ["-Ca", "-Cb", "-1", "-vv"]),
+ ("build[uv]", 3, ["-Ca", "-Cb", "-1", "-vv"]),
+ ],
+)
+def test_get_build_frontend_extra_flags(
+ frontend: Literal["pip", "build", "build[uv]"],
+ verbosity: int,
+ result: list[str],
+ monkeypatch: pytest.MonkeyPatch,
+) -> None:
+ mock_warning = unittest.mock.MagicMock()
+ monkeypatch.setattr(Logger, "warning", mock_warning)
+ build_frontend = BuildFrontendConfig(frontend, ["-1"])
+ args = get_build_frontend_extra_flags(
+ build_frontend=build_frontend, verbosity_level=verbosity, config_settings="a b"
+ )
+
+ assert args == result
+ mock_warning.assert_not_called()
+
+
+@pytest.mark.parametrize("frontend", ["build", "build[uv]"])
+def test_get_build_frontend_extra_flags_warning(
+ frontend: Literal["build", "build[uv]"], monkeypatch: pytest.MonkeyPatch
+) -> None:
+ mock_warning = unittest.mock.MagicMock()
+ monkeypatch.setattr(Logger, "warning", mock_warning)
+ build_frontend = BuildFrontendConfig(frontend, ["-1"])
+ args = get_build_frontend_extra_flags(
+ build_frontend=build_frontend, verbosity_level=-1, config_settings="a b"
+ )
+ assert args == ["-Ca", "-Cb", "-1"]
+ mock_warning.assert_called_once()