diff --git a/mesonpy/__init__.py b/mesonpy/__init__.py index 4c64a309c..f79c54b6b 100644 --- a/mesonpy/__init__.py +++ b/mesonpy/__init__.py @@ -646,9 +646,17 @@ def __init__( if sysconfig.get_platform().startswith('macosx-'): archflags = os.environ.get('ARCHFLAGS', '').strip() if archflags: - arch, *other = filter(None, (x.strip() for x in archflags.split('-arch'))) + + # parse the ARCHFLAGS environment variable + parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False) + parser.add_argument('-arch', action='append') + args, unknown = parser.parse_known_args(archflags.split()) + if unknown: + raise ConfigError(f'Unknown flag specified in $ARCHFLAGS={archflags!r}') + arch, *other = set(args.arch) if other: raise ConfigError(f'Multi-architecture builds are not supported but $ARCHFLAGS={archflags!r}') + macver, _, nativearch = platform.mac_ver() if arch != nativearch: x = os.environ.setdefault('_PYTHON_HOST_PLATFORM', f'macosx-{macver}-{arch}') diff --git a/tests/test_project.py b/tests/test_project.py index 3f27e6ff5..db56136d6 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -211,3 +211,36 @@ def test_compiler(venv, package_detect_compiler, tmp_path): venv.pip('install', os.fspath(tmp_path / wheel)) compiler = venv.python('-c', 'import detect_compiler; print(detect_compiler.compiler())').strip() assert compiler == 'msvc' + + +@pytest.mark.skipif(sys.platform != 'darwin', reason='macOS specific test') +@pytest.mark.parametrize('archflags', [ + '-arch x86_64', + '-arch arm64', + '-arch arm64 -arch arm64', +]) +def test_archflags_envvar_parsing(package_purelib_and_platlib, monkeypatch, archflags): + try: + monkeypatch.setenv('ARCHFLAGS', archflags) + arch = archflags.split()[-1] + with mesonpy._project(): + assert mesonpy._tags.Tag().platform.endswith(arch) + finally: + # revert environment variable setting done by the in-process build + os.environ.pop('_PYTHON_HOST_PLATFORM', None) + + +@pytest.mark.skipif(sys.platform != 'darwin', reason='macOS specific test') +@pytest.mark.parametrize('archflags', [ + '-arch arm64 -arch x86_64', + '-arch arm64 -DFOO=1', +]) +def test_archflags_envvar_parsing_invalid(package_purelib_and_platlib, monkeypatch, archflags): + try: + monkeypatch.setenv('ARCHFLAGS', archflags) + with pytest.raises(mesonpy.ConfigError): + with mesonpy._project(): + pass + finally: + # revert environment variable setting done by the in-process build + os.environ.pop('_PYTHON_HOST_PLATFORM', None)