@@ -48,68 +48,90 @@ def get_requires_for_build_wheel(
48
48
49
49
def _bootstrap_build (temp_path : str , config_settings : dict [str , list [str ] | str ] | None = None ) -> str :
50
50
import hashlib
51
+ import platform
51
52
import re
52
53
import shutil
53
54
import subprocess
54
55
import tarfile
55
56
import urllib .request
57
+ import zipfile
56
58
from pathlib import Path
57
59
58
60
env = os .environ .copy ()
59
61
temp_path_ = Path (temp_path )
60
62
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"
70
92
raise ValueError (msg )
71
- env ["MAKE" ] = make_path
72
- make_path = env ["MAKE" ]
93
+ kind = kinds [machine ]
73
94
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 )
78
95
79
96
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 ]
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 ]
82
99
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 ():
100
+ archive_name = source_url .rsplit ("/" , maxsplit = 1 )[1 ]
101
+ archive_path = archive_dir / archive_name
102
+ if not archive_path .exists ():
87
103
with urllib .request .urlopen (source_url ) as response :
88
- source_tarball .write_bytes (response .read ())
104
+ archive_path .write_bytes (response .read ())
89
105
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} "
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} "
93
109
raise ValueError (msg )
94
110
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 )
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
+ bootstrap_args = [f"--prefix={ prefix_path } " , "--no-qt-gui" , "--no-debugger" , "--parallel={parallel}" ]
123
+ previous_cwd = Path ().absolute ()
124
+ os .chdir (bootstrap_path .parent )
125
+ try :
126
+ subprocess .run ([bootstrap_path , * bootstrap_args ], env = env , check = True )
127
+ subprocess .run ([make_path , "-j" , f"{ parallel } " ], env = env , check = True )
128
+ subprocess .run ([make_path , "install" ], env = env , check = True )
129
+ finally :
130
+ os .chdir (previous_cwd )
131
+ else :
132
+ assert archive_name .endswith (".zip" )
133
+ with zipfile .ZipFile (archive_path ) as zip_ :
134
+ zip_ .extractall (path = prefix_path )
113
135
114
136
return str (prefix_path / "bin" / "cmake" )
115
137
@@ -124,7 +146,7 @@ def build_wheel(
124
146
try :
125
147
return _orig .build_wheel (wheel_directory , config_settings , metadata_directory )
126
148
except CMakeNotFoundError :
127
- if os .name != "posix" :
149
+ if os .name not in { "posix" , "nt" } :
128
150
raise
129
151
# Let's try bootstrapping CMake
130
152
import tempfile
0 commit comments