Repository: pypa/cibuildwheel

Issue:
`--config-settings` is passed as `--config-setting`
### Description

Whenever I try to use the feature to pass `--config-settings` (either through environment variable or `pyproject.toml`), I am met with a `no such option: --config-setting` error in the logs.

A cursory look at the pip documentation seems to suggest the argument name actually is `--config-settings`:
https://pip.pypa.io/en/stable/cli/pip_wheel/#cmdoption-config-settings

It looks like the options that should be passed as `--config-settings` are actually being passed as `--config-setting` (missing the `s`):

https://github.com/pypa/cibuildwheel/blob/acdbe87e3d002598b10435bb6f17bae758418ba8/cibuildwheel/util.py#L213

### Build log

_No response_

### CI config

_No response_

Discussion:

Patch:
diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py
index acf00667..f5d8710e 100644
--- a/cibuildwheel/linux.py
+++ b/cibuildwheel/linux.py
@@ -240,7 +240,9 @@ def build_in_container(
             container.call(["mkdir", "-p", built_wheel_dir])
 
             verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
-            extra_flags = split_config_settings(build_options.config_settings)
+            extra_flags = split_config_settings(
+                build_options.config_settings, build_options.build_frontend
+            )
 
             if build_options.build_frontend == "pip":
                 extra_flags += verbosity_flags
diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py
index a94caa66..3bb1324d 100644
--- a/cibuildwheel/macos.py
+++ b/cibuildwheel/macos.py
@@ -374,7 +374,9 @@ def build(options: Options, tmp_path: Path) -> None:
                 built_wheel_dir.mkdir()
 
                 verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
-                extra_flags = split_config_settings(build_options.config_settings)
+                extra_flags = split_config_settings(
+                    build_options.config_settings, build_options.build_frontend
+                )
 
                 if build_options.build_frontend == "pip":
                     extra_flags += verbosity_flags
diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py
index c0af8182..72cff326 100644
--- a/cibuildwheel/util.py
+++ b/cibuildwheel/util.py
@@ -208,9 +208,10 @@ def get_build_verbosity_extra_flags(level: int) -> list[str]:
         return []
 
 
-def split_config_settings(config_settings: str) -> list[str]:
+def split_config_settings(config_settings: str, frontend: Literal["pip", "build"]) -> list[str]:
     config_settings_list = shlex.split(config_settings)
-    return [f"--config-setting={setting}" for setting in config_settings_list]
+    s = "s" if frontend == "pip" else ""
+    return [f"--config-setting{s}={setting}" for setting in config_settings_list]
 
 
 def read_python_configs(config: PlatformName) -> list[dict[str, str]]:
diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py
index 9182f046..cb83a324 100644
--- a/cibuildwheel/windows.py
+++ b/cibuildwheel/windows.py
@@ -411,7 +411,9 @@ def build(options: Options, tmp_path: Path) -> None:
                 built_wheel_dir.mkdir()
 
                 verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
-                extra_flags = split_config_settings(build_options.config_settings)
+                extra_flags = split_config_settings(
+                    build_options.config_settings, build_options.build_frontend
+                )
 
                 if build_options.build_frontend == "pip":
                     extra_flags += verbosity_flags


Test patch:
diff --git a/unit_test/main_tests/main_options_test.py b/unit_test/main_tests/main_options_test.py
index 80f446a0..6cda8967 100644
--- a/unit_test/main_tests/main_options_test.py
+++ b/unit_test/main_tests/main_options_test.py
@@ -283,12 +283,18 @@ def test_config_settings(platform_specific, platform, intercepted_build_args, mo
 
     assert build_options.config_settings == config_settings
 
-    assert split_config_settings(config_settings) == [
+    assert split_config_settings(config_settings, "build") == [
         "--config-setting=setting=value",
         "--config-setting=setting=value2",
         "--config-setting=other=something else",
     ]
 
+    assert split_config_settings(config_settings, "pip") == [
+        "--config-settings=setting=value",
+        "--config-settings=setting=value2",
+        "--config-settings=other=something else",
+    ]
+
 
 @pytest.mark.parametrize(
     "selector",