66from setuptools import setup , Extension
77from setuptools .command .build_ext import build_ext
88
9+ PLAT_TO_CMAKE = {
10+ "win32" : "Win32" ,
11+ "win-amd64" : "x64" ,
12+ "win-arm32" : "ARM" ,
13+ "win-arm64" : "ARM64" ,
14+ }
15+
916
1017class CMakeExtension (Extension ):
1118 def __init__ (self , name : str , sourcedir : str = "" ) -> None :
@@ -18,14 +25,32 @@ def build_extension(self, ext: CMakeExtension) -> None:
1825 ext_fullpath = Path .cwd () / self .get_ext_fullpath (ext .name )
1926 extdir = ext_fullpath .parent .resolve ()
2027
28+ cmake_generator = os .environ .get ("CMAKE_GENERATOR" , "" )
29+
2130 cmake_args = [
2231 f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={ extdir } { os .sep } " ,
2332 f"-DPython_EXECUTABLE={ sys .executable } " ,
24- f"-DCMAKE_BUILD_TYPE=Release" ,
2533 ]
2634
2735 build_args = ["--config" , "Release" ]
2836
37+ if sys .platform == "win32" :
38+ # MSVC: set architecture and output directory per-config
39+ single_config = any (
40+ x in cmake_generator for x in ("NMake" , "Ninja" )
41+ )
42+ contains_arch = any (
43+ x in cmake_generator for x in ("ARM" , "Win64" )
44+ )
45+ if not single_config and not contains_arch :
46+ cmake_args += ["-A" , PLAT_TO_CMAKE [self .plat_name ]]
47+ if not single_config :
48+ cmake_args += [
49+ f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE={ extdir } { os .sep } " ,
50+ ]
51+ else :
52+ cmake_args += ["-DCMAKE_BUILD_TYPE=Release" ]
53+
2954 if "CMAKE_BUILD_PARALLEL_LEVEL" not in os .environ :
3055 if hasattr (self , "parallel" ) and self .parallel :
3156 build_args += [f"-j{ self .parallel } " ]
0 commit comments