@@ -48,70 +48,94 @@ def get_requires_for_build_wheel(
4848
4949def _bootstrap_build (temp_path : str , config_settings : dict [str , list [str ] | str ] | None = None ) -> str :
5050 import hashlib
51+ import platform
5152 import re
5253 import shutil
5354 import subprocess
5455 import tarfile
5556 import urllib .request
57+ import zipfile
5658 from pathlib import Path
5759
5860 env = os .environ .copy ()
5961 temp_path_ = Path (temp_path )
6062
61- if "MAKE" not in env :
62- make_path = None
63- make_candidates = ("gmake" , "make" , "smake" )
64- for candidate in make_candidates :
65- make_path = shutil .which (candidate )
66- if make_path is not None :
67- break
68- if make_path is None :
69- msg = f"Could not find a make program. Tried { make_candidates !r} "
63+ archive_dir = temp_path_
64+ if config_settings :
65+ archive_dir = Path (config_settings .get ("cmake.define.CMakePythonDistributions_ARCHIVE_DOWNLOAD_DIR" , archive_dir ))
66+ archive_dir .mkdir (parents = True , exist_ok = True )
67+
68+ if os .name == "posix" :
69+ if "MAKE" not in env :
70+ make_path = None
71+ make_candidates = ("gmake" , "make" , "smake" )
72+ for candidate in make_candidates :
73+ make_path = shutil .which (candidate )
74+ if make_path is not None :
75+ break
76+ if make_path is None :
77+ msg = f"Could not find a make program. Tried { make_candidates !r} "
78+ raise ValueError (msg )
79+ env ["MAKE" ] = make_path
80+ make_path = env ["MAKE" ]
81+ kind = "unix_source"
82+ else :
83+ assert os .name == "nt"
84+ machine = platform .machine ()
85+ kinds = {
86+ "x86" : "win32_binary" ,
87+ "AMD64" : "win64_binary" ,
88+ "ARM64" : "winarm64_binary" ,
89+ }
90+ if machine not in kinds :
91+ msg = f"Could not find CMake required to build on a { machine } system"
7092 raise ValueError (msg )
71- env ["MAKE" ] = make_path
72- make_path = env ["MAKE" ]
93+ kind = kinds [machine ]
7394
74- archive_path = temp_path_
75- if config_settings :
76- archive_path = Path (config_settings .get ("cmake.define.CMakePythonDistributions_ARCHIVE_DOWNLOAD_DIR" , archive_path ))
77- archive_path .mkdir (parents = True , exist_ok = True )
7895
7996 cmake_urls = Path ("CMakeUrls.cmake" ).read_text ()
80- source_url = re .findall (r'set\(unix_source_url\s+"(?P<data>.*)"\)$' , cmake_urls , flags = re .MULTILINE )[0 ]
81- source_sha256 = re .findall (r'set\(unix_source_sha256\s+"(?P<data>.*)"\)$' , cmake_urls , flags = re .MULTILINE )[0 ]
82-
83- tarball_name = source_url .rsplit ("/" , maxsplit = 1 )[1 ]
84- assert tarball_name .endswith (".tar.gz" )
85- source_tarball = archive_path / tarball_name
86- if not source_tarball .exists ():
87- with urllib .request .urlopen (source_url ) as response :
88- source_tarball .write_bytes (response .read ())
89-
90- sha256 = hashlib .sha256 (source_tarball .read_bytes ()).hexdigest ()
91- if source_sha256 .lower () != sha256 .lower ():
92- msg = f"Invalid sha256 for { source_url !r} . Expected { source_sha256 !r} , got { sha256 !r} "
97+ archive_url = re .findall (rf'set\({ kind } _url\s+"(?P<data>.*)"\)$' , cmake_urls , flags = re .MULTILINE )[0 ]
98+ archive_sha256 = re .findall (rf'set\({ kind } _sha256\s+"(?P<data>.*)"\)$' , cmake_urls , flags = re .MULTILINE )[0 ]
99+
100+ archive_name = archive_url .rsplit ("/" , maxsplit = 1 )[1 ]
101+ archive_path = archive_dir / archive_name
102+ if not archive_path .exists ():
103+ with urllib .request .urlopen (archive_url ) as response :
104+ archive_path .write_bytes (response .read ())
105+
106+ sha256 = hashlib .sha256 (archive_path .read_bytes ()).hexdigest ()
107+ if archive_sha256 .lower () != sha256 .lower ():
108+ msg = f"Invalid sha256 for { archive_url !r} . Expected { archive_sha256 !r} , got { sha256 !r} "
93109 raise ValueError (msg )
94110
95- tar_filter_kwargs = {"filter" : "tar" } if hasattr (tarfile , "tar_filter" ) else {}
96- with tarfile .open (source_tarball ) as tar :
97- tar .extractall (path = temp_path_ , ** tar_filter_kwargs )
98-
99- parallel_str = env .get ("CMAKE_BUILD_PARALLEL_LEVEL" , "1" )
100- parallel = max (0 , int (parallel_str ) if parallel_str .isdigit () else 1 ) or os .cpu_count () or 1
101-
102- bootstrap_path = next (temp_path_ .glob ("cmake-*/bootstrap" ))
103- prefix_path = temp_path_ / "cmake-install"
104- bootstrap_args = [f"--prefix={ prefix_path } " , "--no-qt-gui" , "--no-debugger" , "--parallel={parallel}" ]
105- previous_cwd = Path ().absolute ()
106- os .chdir (bootstrap_path .parent )
107- try :
108- subprocess .run ([bootstrap_path , * bootstrap_args ], env = env , check = True )
109- subprocess .run ([make_path , "-j" , f"{ parallel } " ], env = env , check = True )
110- subprocess .run ([make_path , "install" ], env = env , check = True )
111- finally :
112- os .chdir (previous_cwd )
113-
114- return str (prefix_path / "bin" / "cmake" )
111+ if os .name == "posix" :
112+ assert archive_name .endswith (".tar.gz" )
113+ tar_filter_kwargs = {"filter" : "tar" } if hasattr (tarfile , "tar_filter" ) else {}
114+ with tarfile .open (archive_path ) as tar :
115+ tar .extractall (path = temp_path_ , ** tar_filter_kwargs )
116+
117+ parallel_str = env .get ("CMAKE_BUILD_PARALLEL_LEVEL" , "1" )
118+ parallel = max (0 , int (parallel_str ) if parallel_str .isdigit () else 1 ) or os .cpu_count () or 1
119+
120+ bootstrap_path = next (temp_path_ .glob ("cmake-*/bootstrap" ))
121+ prefix_path = temp_path_ / "cmake-install"
122+ cmake_path = prefix_path / "bin" / "cmake"
123+ bootstrap_args = [f"--prefix={ prefix_path } " , "--no-qt-gui" , "--no-debugger" , "--parallel={parallel}" ]
124+ previous_cwd = Path ().absolute ()
125+ os .chdir (bootstrap_path .parent )
126+ try :
127+ subprocess .run ([bootstrap_path , * bootstrap_args ], env = env , check = True )
128+ subprocess .run ([make_path , "-j" , f"{ parallel } " ], env = env , check = True )
129+ subprocess .run ([make_path , "install" ], env = env , check = True )
130+ finally :
131+ os .chdir (previous_cwd )
132+ else :
133+ assert archive_name .endswith (".zip" )
134+ with zipfile .ZipFile (archive_path ) as zip_ :
135+ zip_ .extractall (path = temp_path_ )
136+ cmake_path = next (temp_path_ .glob ("cmake-*/bin/cmake.exe" ))
137+
138+ return str (cmake_path )
115139
116140
117141def build_wheel (
@@ -124,7 +148,7 @@ def build_wheel(
124148 try :
125149 return _orig .build_wheel (wheel_directory , config_settings , metadata_directory )
126150 except CMakeNotFoundError :
127- if os .name != "posix" :
151+ if os .name not in { "posix" , "nt" } :
128152 raise
129153 # Let's try bootstrapping CMake
130154 import tempfile
0 commit comments