diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 5ca9c1049..7f14ee81f 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -76,7 +76,7 @@ def main() -> None: on this machine. Set this option to build an architecture via emulation, for example, using binfmt_misc and QEMU. Default: auto. - Choices: auto, {} + Choices: auto, native, all, {} '''.format(", ".join(a.name for a in Architecture))) parser.add_argument('--output-dir', default=os.environ.get('CIBW_OUTPUT_DIR', 'wheelhouse'), diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index 499b987df..f0062e25c 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -16,7 +16,7 @@ import toml from .environment import ParsedEnvironment -from .typing import PathOrStr, PlatformName +from .typing import PathOrStr, PlatformName, assert_never if sys.version_info < (3, 9): from importlib_resources import files @@ -169,6 +169,10 @@ def parse_config(config: str, platform: PlatformName) -> 'Set[Architecture]': for arch_str in re.split(r'[\s,]+', config): if arch_str == 'auto': result |= Architecture.auto_archs(platform=platform) + elif arch_str == 'native': + result.add(Architecture(platform_module.machine())) + elif arch_str == 'all': + result |= Architecture.all_archs(platform=platform) else: result.add(Architecture(arch_str)) return result @@ -184,6 +188,17 @@ def auto_archs(platform: PlatformName) -> 'Set[Architecture]': result.add(Architecture.x86) return result + @staticmethod + def all_archs(platform: PlatformName) -> 'Set[Architecture]': + if platform == 'linux': + return {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x} + elif platform == 'macos': + return {Architecture.x86_64} + elif platform == 'windows': + return {Architecture.x86, Architecture.AMD64} + else: + assert_never(platform) + class BuildOptions(NamedTuple): package_dir: Path @@ -255,23 +270,17 @@ def detect_ci_provider() -> Optional[CIProvider]: PRETTY_NAMES = {'linux': 'Linux', 'macos': 'macOS', 'windows': 'Windows'} -ALLOWED_ARCHITECTURES = { - 'linux': {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x}, - 'macos': {Architecture.x86_64}, - 'windows': {Architecture.AMD64, Architecture.x86}, -} - def allowed_architectures_check( - name: PlatformName, + platform: PlatformName, options: BuildOptions, ) -> None: - allowed_architectures = ALLOWED_ARCHITECTURES[name] + allowed_architectures = Architecture.all_archs(platform) - msg = f'{PRETTY_NAMES[name]} only supports {sorted(allowed_architectures)} at the moment.' + msg = f'{PRETTY_NAMES[platform]} only supports {sorted(allowed_architectures)} at the moment.' - if name != 'linux': + if platform != 'linux': msg += ' If you want to set emulation architectures on Linux, use CIBW_ARCHS_LINUX instead.' if not options.architectures <= allowed_architectures: diff --git a/docs/options.md b/docs/options.md index e7a9f3baa..7b2398a70 100644 --- a/docs/options.md +++ b/docs/options.md @@ -163,11 +163,17 @@ emulation, such as that provided by [docker/setup-qemu-action][setup-qemu-action or [tonistiigi/binfmt][binfmt], to build architectures other than those your machine natively supports. -Options: `auto` `x86_64` `i686` `aarch64` `ppc64le` `s390x` +Options: `auto` `native` `all` `x86_64` `i686` `aarch64` `ppc64le` `s390x` Default: `auto`, meaning the native archs supported on the build machine. For example, on an `x86_64` machine, `auto` expands to `x86_64` and `i686`. +`native` will only build on the exact architecture you currently are on; it will +not add `i686` for `x86_64`. + +`all` will expand to all known architectures; remember to use build selectors +to limit builds for each job; this list could grow in the future. + [setup-qemu-action]: https://github.com/docker/setup-qemu-action [binfmt]: https://hub.docker.com/r/tonistiigi/binfmt diff --git a/unit_test/main_tests/main_platform_test.py b/unit_test/main_tests/main_platform_test.py index e01526eac..9b7c06fef 100644 --- a/unit_test/main_tests/main_platform_test.py +++ b/unit_test/main_tests/main_platform_test.py @@ -110,3 +110,33 @@ def test_archs_platform_specific(platform, intercepted_build_args, monkeypatch): assert build_options.architectures == {Architecture.x86} elif platform == 'macos': assert build_options.architectures == {Architecture.x86_64} + + +def test_archs_platform_native(platform, intercepted_build_args, monkeypatch): + monkeypatch.setattr(platform_module, 'machine', lambda: 'x86_64') + monkeypatch.setenv('CIBW_ARCHS', 'native') + + main() + build_options = intercepted_build_args.args[0] + + if platform == 'linux': + assert build_options.architectures == {Architecture.x86_64} + elif platform == 'windows': + assert build_options.architectures == {Architecture.x86_64} + elif platform == 'macos': + assert build_options.architectures == {Architecture.x86_64} + + +def test_archs_platform_all(platform, intercepted_build_args, monkeypatch): + monkeypatch.setattr(platform_module, 'machine', lambda: 'x86_64') + monkeypatch.setenv('CIBW_ARCHS', 'all') + + main() + build_options = intercepted_build_args.args[0] + + if platform == 'linux': + assert build_options.architectures == {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x} + elif platform == 'windows': + assert build_options.architectures == {Architecture.x86, Architecture.AMD64} + elif platform == 'macos': + assert build_options.architectures == {Architecture.x86_64}