|  | 
| 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 . import build_helper as bh | 
| 35 | 22 | 
 | 
| 36 | 23 | 
 | 
| 37 | 24 | def parse_args(): | 
| @@ -142,137 +129,73 @@ def parse_args(): | 
| 142 | 129 |     return p.parse_args() | 
| 143 | 130 | 
 | 
| 144 | 131 | 
 | 
| 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 | 132 | def main(): | 
| 186 | 133 |     if sys.platform not in ["cygwin", "win32", "linux"]: | 
| 187 |  | -        _err(f"{sys.platform} not supported") | 
|  | 134 | +        bh.err(f"{sys.platform} not supported") | 
| 188 | 135 |     args = parse_args() | 
| 189 | 136 |     setup_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 
| 190 | 137 |     build_dir = os.path.join(setup_dir, args.build_dir) | 
| 191 | 138 | 
 | 
| 192 |  | -    resolve_compilers(args) | 
|  | 139 | +    c_compiler, cxx_compiler, compiler_root = bh.resolve_compilers( | 
|  | 140 | +        args.oneapi, args.c_compiler, args.cxx_compiler, args.compiler_root | 
|  | 141 | +    ) | 
| 193 | 142 | 
 | 
| 194 | 143 |     # 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) | 
|  | 144 | +    if args.clean: | 
|  | 145 | +        bh.clean_build_dir(build_dir) | 
| 198 | 146 | 
 | 
| 199 |  | -    env = os.environ.copy() | 
|  | 147 | +    if args.no_level_zero and args.target_level_zero: | 
|  | 148 | +        bh.err("Cannot combine --no-level-zero and --target-level-zero") | 
| 200 | 149 | 
 | 
| 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"] | 
|  | 150 | +    # Level Zero state (on unless explicitly disabled) | 
|  | 151 | +    if args.no_level_zero: | 
|  | 152 | +        level_zero_enabled = False | 
|  | 153 | +    elif args.target_level_zero: | 
|  | 154 | +        level_zero_enabled = True | 
|  | 155 | +    else: | 
|  | 156 | +        level_zero_enabled = True | 
| 205 | 157 | 
 | 
| 206 |  | -    cmake_defs = [] | 
|  | 158 | +    cmake_args = bh.make_cmake_args( | 
|  | 159 | +        build_type=args.build_type, | 
|  | 160 | +        c_compiler=c_compiler, | 
|  | 161 | +        cxx_compiler=cxx_compiler, | 
|  | 162 | +        level_zero=level_zero_enabled, | 
|  | 163 | +        glogs=args.glog, | 
|  | 164 | +        generator=args.generator, | 
|  | 165 | +        verbose=args.verbose, | 
|  | 166 | +        other_opts=args.cmake_opts, | 
|  | 167 | +    ) | 
| 207 | 168 | 
 | 
| 208 | 169 |     # handle architecture conflicts | 
| 209 | 170 |     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") | 
|  | 171 | +        bh.err("--target-hip requires an explicit architecture") | 
| 214 | 172 | 
 | 
| 215 | 173 |     # CUDA/HIP targets | 
| 216 | 174 |     if args.target_cuda: | 
| 217 |  | -        cmake_defs.append(f"-DDPCTL_TARGET_CUDA={args.target_cuda}") | 
|  | 175 | +        cmake_args.append(f"-DDPCTL_TARGET_CUDA={args.target_cuda}") | 
| 218 | 176 |     if args.target_hip: | 
| 219 |  | -        cmake_defs.append(f"-DDPCTL_TARGET_HIP={args.target_hip}") | 
|  | 177 | +        cmake_args.append(f"-DDPCTL_TARGET_HIP={args.target_hip}") | 
| 220 | 178 | 
 | 
| 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( | 
|  | 179 | +    cmake_args.append( | 
| 229 | 180 |         "-DDPCTL_ENABLE_L0_PROGRAM_CREATION=" | 
| 230 | 181 |         f"{'ON' if level_zero_enabled else 'OFF'}" | 
| 231 | 182 |     ) | 
| 232 | 183 | 
 | 
| 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") | 
|  | 184 | +    env = os.environ.copy() | 
| 247 | 185 | 
 | 
| 248 |  | -    if args.cmake_opts: | 
| 249 |  | -        cmake_defs.extend(args.cmake_opts.split()) | 
|  | 186 | +    # ignore pre-existing CMAKE_ARGS for determinism in build driver | 
|  | 187 | +    if "CMAKE_ARGS" in env and env["CMAKE_ARGS"].strip(): | 
|  | 188 | +        bh.warn("Ignoring pre-existing CMAKE_ARGS in environment") | 
|  | 189 | +        del env["CMAKE_ARGS"] | 
| 250 | 190 | 
 | 
| 251 |  | -    env["CMAKE_ARGS"] = " ".join(cmake_defs) | 
| 252 |  | -    print(f"[build_locally] CMake args:\n {' '.join(cmake_defs)}") | 
|  | 191 | +    env["CMAKE_ARGS"] = " ".join(cmake_args) | 
|  | 192 | +    print(f"[build_locally] CMake args:\n {' '.join(cmake_args)}") | 
| 253 | 193 | 
 | 
| 254 | 194 |     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 | 195 | 
 | 
|  | 196 | +    bh.build_extensions(setup_dir, env) | 
| 261 | 197 |     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 |  | -        ) | 
|  | 198 | +        bh.install_editable(setup_dir, env) | 
| 276 | 199 |     else: | 
| 277 | 200 |         print("[build_locally] Skipping editable install (--skip-editable)") | 
| 278 | 201 | 
 | 
|  | 
0 commit comments