44import re
55import sys
66import sysconfig
7+ from collections .abc import Sequence
78from pathlib import Path
89from typing import Mapping
910
1718from .generator import set_environment_for_gen
1819from .sysconfig import get_platform , get_python_include_dir , get_python_library
1920
20- __all__ : list [str ] = ["Builder" ]
21+ __all__ : list [str ] = ["Builder" , "get_archs" , "archs_to_tags" ]
2122
2223DIR = Path (__file__ ).parent .resolve ()
2324
@@ -26,45 +27,53 @@ def __dir__() -> list[str]:
2627 return __all__
2728
2829
29- @ dataclasses . dataclass
30- class Builder :
31- settings : ScikitBuildSettings
32- config : CMaker
30+ # TODO: cross-compile support for other platforms
31+ def get_archs ( env : Mapping [ str , str ], cmake_args : Sequence [ str ] = ()) -> list [ str ] :
32+ """
33+ Takes macOS platform settings and returns a list of platforms.
3334
34- # TODO: cross-compile support for other platforms
35- def get_archs (self ) -> list [str ]:
36- """
37- Takes macOS platform settings and returns a list of platforms.
35+ Example (macOS):
36+ ARCHFLAGS="-arch x86_64" -> ["x86_64"]
37+ ARCHFLAGS="-arch x86_64 -arch arm64" -> ["x86_64", "arm64"]
3838
39- Example (macOS):
40- ARCHFLAGS="-arch x86_64" -> ["x86_64"]
41- ARCHFLAGS="-arch x86_64 -arch arm64" -> ["x86_64", "arm64"]
39+ Returns an empty list otherwise or if ARCHFLAGS is not set.
40+ """
4241
43- Returns an empty list otherwise or if ARCHFLAGS is not set.
44- """
42+ if sys .platform .startswith ("darwin" ):
43+ for cmake_arg in cmake_args :
44+ if "CMAKE_SYSTEM_PROCESSOR" in cmake_arg :
45+ return [cmake_arg .split ("=" )[1 ]]
46+ archs = re .findall (r"-arch (\S+)" , env .get ("ARCHFLAGS" , "" ))
47+ return archs
48+ if sys .platform .startswith ("win" ) and get_platform (env ) == "win-arm64" :
49+ return ["win_arm64" ]
50+
51+ return []
52+
53+
54+ def archs_to_tags (archs : list [str ]) -> list [str ]:
55+ """
56+ Convert a list of architectures to a list of tags (e.g. "universal2").
57+ """
58+ if sys .platform .startswith ("darwin" ) and set (archs ) == {"arm64" , "x86_64" }:
59+ return ["universal2" ]
60+ return archs
4561
46- if sys .platform .startswith ("darwin" ):
47- archs = re .findall (r"-arch (\S+)" , self .config .env .get ("ARCHFLAGS" , "" ))
48- return archs
49- if (
50- sys .platform .startswith ("win" )
51- and get_platform (self .config .env ) == "win-arm64"
52- ):
53- return ["win_arm64" ]
5462
55- return []
63+ @dataclasses .dataclass
64+ class Builder :
65+ settings : ScikitBuildSettings
66+ config : CMaker
5667
57- def get_arch_tags (self ) -> list [str ]:
68+ def get_cmake_args (self ) -> list [str ]:
5869 """
59- This function returns tags suitable for use in wheels. The main
60- difference between this method and get_archs() is that this returns
61- universal2 instead of separate tags for x86_64 and arm64.
70+ Get CMake args from the settings and environment.
6271 """
72+ # Adding CMake arguments set as environment variable
73+ # (needed e.g. to build for ARM OSX on conda-forge)
74+ env_cmake_args = filter (None , self .config .env .get ("CMAKE_ARGS" , "" ).split (" " ))
6375
64- archs = self .get_archs ()
65- if sys .platform .startswith ("darwin" ) and set (archs ) == {"arm64" , "x86_64" }:
66- return ["universal2" ]
67- return archs
76+ return [* self .settings .cmake .args , * env_cmake_args ]
6877
6978 def configure (
7079 self ,
@@ -76,7 +85,6 @@ def configure(
7685 limited_abi : bool | None = None ,
7786 ) -> None :
7887 cmake_defines = dict (defines )
79- cmake_args : list [str ] = []
8088
8189 # Add site-packages to the prefix path for CMake
8290 site_packages = Path (sysconfig .get_path ("purelib" ))
@@ -151,18 +159,9 @@ def configure(
151159
152160 self .config .init_cache (cache_config )
153161
154- # Add the pre-defined or passed CMake args
155- cmake_args += self .settings .cmake .args
156-
157- # Adding CMake arguments set as environment variable
158- # (needed e.g. to build for ARM OSX on conda-forge)
159- cmake_args += [
160- item for item in self .config .env .get ("CMAKE_ARGS" , "" ).split (" " ) if item
161- ]
162-
163162 if sys .platform .startswith ("darwin" ):
164163 # Cross-compile support for macOS - respect ARCHFLAGS if set
165- archs = self . get_archs ()
164+ archs = get_archs (self . config . env )
166165 if archs :
167166 cmake_defines ["CMAKE_OSX_ARCHITECTURES" ] = ";" .join (archs )
168167
@@ -171,7 +170,7 @@ def configure(
171170
172171 self .config .configure (
173172 defines = cmake_defines ,
174- cmake_args = cmake_args ,
173+ cmake_args = self . get_cmake_args () ,
175174 )
176175
177176 def build (self , build_args : list [str ]) -> None :
0 commit comments