|
16 | 16 |
|
17 | 17 | import argparse |
18 | 18 | import os |
19 | | -import shutil |
20 | | -import subprocess |
21 | 19 | import sys |
22 | 20 |
|
23 | | - |
24 | | -def run(cmd, env=None, cwd=None): |
25 | | - print("+", " ".join(cmd)) |
26 | | - subprocess.check_call(cmd, env=env, cwd=cwd or os.getcwd()) |
27 | | - |
28 | | - |
29 | | -def _warn(msg: str): |
30 | | - print(f"[build_locally][error] {msg}", file=sys.stderr) |
31 | | - |
32 | | - |
33 | | -def _err(msg: str): |
34 | | - print(f"[build_locally][error] {msg}", file=sys.stderr) |
| 21 | +from ._build_helper import ( |
| 22 | + build_extensions, |
| 23 | + clean_build_dir, |
| 24 | + install_editable, |
| 25 | + err, |
| 26 | + make_cmake_args, |
| 27 | + resolve_compilers, |
| 28 | + warn, |
| 29 | +) |
35 | 30 |
|
36 | 31 |
|
37 | 32 | def parse_args(): |
@@ -142,137 +137,73 @@ def parse_args(): |
142 | 137 | return p.parse_args() |
143 | 138 |
|
144 | 139 |
|
145 | | -def resolve_compilers(args): |
146 | | - is_linux = "linux" in sys.platform |
147 | | - |
148 | | - if args.oneapi or ( |
149 | | - args.c_compiler is None |
150 | | - and args.cxx_compiler is None |
151 | | - and args.compiler_root is None |
152 | | - ): |
153 | | - args.c_compiler = "icx" |
154 | | - args.cxx_compiler = "icpx" if is_linux else "icx" |
155 | | - args.compiler_root = None |
156 | | - return |
157 | | - |
158 | | - cr = args.compiler_root |
159 | | - if isinstance(cr, str) and os.path.exists(cr): |
160 | | - if args.c_compiler is None: |
161 | | - args.c_compiler = "icx" |
162 | | - if args.cxx_compiler is None: |
163 | | - args.cxx_compiler = "icpx" if is_linux else "icx" |
164 | | - else: |
165 | | - raise RuntimeError( |
166 | | - "'compiler-root' option must be set when using non-default DPC++ " |
167 | | - "layout" |
168 | | - ) |
169 | | - |
170 | | - for opt_name in ("c_compiler", "cxx_compiler"): |
171 | | - arg = getattr(args, opt_name) |
172 | | - if not arg: |
173 | | - continue |
174 | | - if not os.path.exists(arg): |
175 | | - probe = os.path.join(cr, arg) |
176 | | - if os.path.exists(probe): |
177 | | - setattr(args, opt_name, probe) |
178 | | - continue |
179 | | - if not os.path.exists(getattr(args, opt_name)): |
180 | | - raise RuntimeError( |
181 | | - f"{opt_name.replace('_', '-')} value {arg} not found" |
182 | | - ) |
183 | | - |
184 | | - |
185 | 140 | def main(): |
186 | 141 | if sys.platform not in ["cygwin", "win32", "linux"]: |
187 | | - _err(f"{sys.platform} not supported") |
| 142 | + err(f"{sys.platform} not supported") |
188 | 143 | args = parse_args() |
189 | 144 | setup_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
190 | 145 | build_dir = os.path.join(setup_dir, args.build_dir) |
191 | 146 |
|
192 | | - resolve_compilers(args) |
| 147 | + c_compiler, cxx_compiler, compiler_root = resolve_compilers( |
| 148 | + args.oneapi, args.c_compiler, args.cxx_compiler, args.compiler_root |
| 149 | + ) |
193 | 150 |
|
194 | 151 | # clean build dir if --clean set |
195 | | - if args.clean and os.path.exists(build_dir): |
196 | | - print(f"[build_locally] Cleaning build directory: {build_dir}") |
197 | | - shutil.rmtree(build_dir) |
| 152 | + if args.clean: |
| 153 | + clean_build_dir(build_dir) |
198 | 154 |
|
199 | | - env = os.environ.copy() |
| 155 | + if args.no_level_zero and args.target_level_zero: |
| 156 | + err("Cannot combine --no-level-zero and --target-level-zero") |
200 | 157 |
|
201 | | - # ignore pre-existing CMAKE_ARGS for determinism in build driver |
202 | | - if "CMAKE_ARGS" in env and env["CMAKE_ARGS"].strip(): |
203 | | - _warn("Ignoring pre-existing CMAKE_ARGS in environment") |
204 | | - del env["CMAKE_ARGS"] |
| 158 | + # Level Zero state (on unless explicitly disabled) |
| 159 | + if args.no_level_zero: |
| 160 | + level_zero_enabled = False |
| 161 | + elif args.target_level_zero: |
| 162 | + level_zero_enabled = True |
| 163 | + else: |
| 164 | + level_zero_enabled = True |
205 | 165 |
|
206 | | - cmake_defs = [] |
| 166 | + cmake_args = make_cmake_args( |
| 167 | + build_type=args.build_type, |
| 168 | + c_compiler=c_compiler, |
| 169 | + cxx_compiler=cxx_compiler, |
| 170 | + level_zero=level_zero_enabled, |
| 171 | + glogs=args.glog, |
| 172 | + generator=args.generator, |
| 173 | + verbose=args.verbose, |
| 174 | + other_opts=args.cmake_opts, |
| 175 | + ) |
207 | 176 |
|
208 | 177 | # handle architecture conflicts |
209 | 178 | if args.target_hip is not None and not args.target_hip.strip(): |
210 | | - _err("--target-hip requires an explicit architecture") |
211 | | - |
212 | | - if args.no_level_zero and args.target_level_zero: |
213 | | - _err("Cannot combine --no-level-zero and --target-level-zero") |
| 179 | + err("--target-hip requires an explicit architecture") |
214 | 180 |
|
215 | 181 | # CUDA/HIP targets |
216 | 182 | if args.target_cuda: |
217 | | - cmake_defs.append(f"-DDPCTL_TARGET_CUDA={args.target_cuda}") |
| 183 | + cmake_args.append(f"-DDPCTL_TARGET_CUDA={args.target_cuda}") |
218 | 184 | if args.target_hip: |
219 | | - cmake_defs.append(f"-DDPCTL_TARGET_HIP={args.target_hip}") |
| 185 | + cmake_args.append(f"-DDPCTL_TARGET_HIP={args.target_hip}") |
220 | 186 |
|
221 | | - # Level Zero state (on unless explicitly disabled) |
222 | | - if args.no_level_zero: |
223 | | - level_zero_enabled = False |
224 | | - elif args.target_level_zero: |
225 | | - level_zero_enabled = True |
226 | | - else: |
227 | | - level_zero_enabled = True |
228 | | - cmake_defs.append( |
| 187 | + cmake_args.append( |
229 | 188 | "-DDPCTL_ENABLE_L0_PROGRAM_CREATION=" |
230 | 189 | f"{'ON' if level_zero_enabled else 'OFF'}" |
231 | 190 | ) |
232 | 191 |
|
233 | | - # compilers and generator |
234 | | - if args.c_compiler: |
235 | | - cmake_defs.append(f"-DCMAKE_C_COMPILER:PATH={args.c_compiler}") |
236 | | - if args.cxx_compiler: |
237 | | - cmake_defs.append(f"-DCMAKE_CXX_COMPILER:PATH={args.cxx_compiler}") |
238 | | - if args.generator: |
239 | | - cmake_defs.append(f"-G{args.generator}") |
240 | | - |
241 | | - cmake_defs.append( |
242 | | - f"-DDPCTL_ENABLE_GLOG:BOOL={'ON' if args.glog else 'OFF'}" |
243 | | - ) |
244 | | - cmake_defs.append(f"-DCMAKE_BUILD_TYPE={args.build_type}") |
245 | | - if args.verbose: |
246 | | - cmake_defs.append("-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON") |
| 192 | + env = os.environ.copy() |
247 | 193 |
|
248 | | - if args.cmake_opts: |
249 | | - cmake_defs.extend(args.cmake_opts.split()) |
| 194 | + # ignore pre-existing CMAKE_ARGS for determinism in build driver |
| 195 | + if "CMAKE_ARGS" in env and env["CMAKE_ARGS"].strip(): |
| 196 | + warn("Ignoring pre-existing CMAKE_ARGS in environment") |
| 197 | + del env["CMAKE_ARGS"] |
250 | 198 |
|
251 | | - env["CMAKE_ARGS"] = " ".join(cmake_defs) |
252 | | - print(f"[build_locally] CMake args:\n {' '.join(cmake_defs)}") |
| 199 | + env["CMAKE_ARGS"] = " ".join(cmake_args) |
| 200 | + print(f"[build_locally] CMake args:\n {' '.join(cmake_args)}") |
253 | 201 |
|
254 | 202 | print("[build_locally] Building extensions in-place...") |
255 | | - run( |
256 | | - [sys.executable, "setup.py", "build_ext", "--inplace"], |
257 | | - env=env, |
258 | | - cwd=setup_dir, |
259 | | - ) |
260 | 203 |
|
| 204 | + build_extensions(setup_dir, env) |
261 | 205 | if not args.skip_editable: |
262 | | - print("[build_locally] Installing dpctl in editable mode") |
263 | | - run( |
264 | | - [ |
265 | | - sys.executable, |
266 | | - "-m", |
267 | | - "pip", |
268 | | - "install", |
269 | | - "-e", |
270 | | - ".", |
271 | | - "--no-build-isolation", |
272 | | - ], |
273 | | - env=env, |
274 | | - cwd=setup_dir, |
275 | | - ) |
| 206 | + install_editable(setup_dir, env) |
276 | 207 | else: |
277 | 208 | print("[build_locally] Skipping editable install (--skip-editable)") |
278 | 209 |
|
|
0 commit comments