|
14 | 14 | # See the License for the specific language governing permissions and |
15 | 15 | # limitations under the License. |
16 | 16 |
|
| 17 | +import argparse |
17 | 18 | import os |
18 | 19 | import subprocess |
19 | 20 | import sys |
20 | 21 |
|
| 22 | +# add scripts dir to Python path so we can import _build_helper |
| 23 | +sys.path.insert(0, os.path.abspath("scripts")) |
21 | 24 |
|
22 | | -def run( |
23 | | - use_oneapi=True, |
24 | | - c_compiler=None, |
25 | | - cxx_compiler=None, |
26 | | - level_zero=True, |
27 | | - compiler_root=None, |
28 | | - bin_llvm=None, |
29 | | - doxyrest_dir=None, |
30 | | - verbose=False, |
31 | | - cmake_opts="", |
32 | | -): |
33 | | - IS_LIN = False |
34 | | - |
35 | | - if "linux" in sys.platform: |
36 | | - IS_LIN = True |
37 | | - elif sys.platform in ["win32", "cygwin"]: |
38 | | - pass |
39 | | - else: |
40 | | - assert False, sys.platform + " not supported" |
41 | | - |
42 | | - if not IS_LIN: |
43 | | - raise RuntimeError( |
44 | | - "This scripts only supports coverage collection on Linux" |
45 | | - ) |
46 | | - setup_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
47 | | - cmake_args = [ |
48 | | - sys.executable, |
49 | | - "setup.py", |
50 | | - "develop", |
51 | | - "--build-type=Release", |
52 | | - "--generator=Ninja", |
53 | | - "--", |
54 | | - "-DCMAKE_C_COMPILER:PATH=" + c_compiler, |
55 | | - "-DCMAKE_CXX_COMPILER:PATH=" + cxx_compiler, |
56 | | - "-DDPCTL_ENABLE_L0_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), |
57 | | - "-DDPCTL_GENERATE_DOCS=ON", |
58 | | - ] |
59 | | - |
60 | | - if verbose: |
61 | | - cmake_args.append("-DCMAKE_VERBOSE_MAKEFILE=ON") |
62 | | - |
63 | | - if doxyrest_dir: |
64 | | - cmake_args.append("-DDPCTL_ENABLE_DOXYREST=ON") |
65 | | - cmake_args.append("-DDoxyrest_DIR=" + doxyrest_dir) |
66 | | - |
67 | | - if cmake_opts: |
68 | | - cmake_args += cmake_opts.split() |
69 | | - |
70 | | - env = dict() |
71 | | - if bin_llvm: |
72 | | - env = { |
73 | | - "PATH": ":".join((os.environ.get("PATH", ""), bin_llvm)), |
74 | | - } |
75 | | - env.update({k: v for k, v in os.environ.items() if k != "PATH"}) |
76 | | - # Install dpctl package |
77 | | - subprocess.check_call(cmake_args, shell=False, cwd=setup_dir, env=env) |
78 | | - # Get the path for the build directory |
79 | | - build_dir = ( |
80 | | - subprocess.check_output( |
81 | | - ["find", "_skbuild", "-name", "cmake-build"], |
82 | | - cwd=setup_dir, |
83 | | - ) |
84 | | - .decode("utf-8") |
85 | | - .strip("\n") |
86 | | - ) |
87 | | - # Generate docs |
88 | | - subprocess.check_call( |
89 | | - ["cmake", "--build", ".", "--target", "Sphinx"], cwd=build_dir |
90 | | - ) |
91 | | - generated_doc_dir = ( |
92 | | - subprocess.check_output( |
93 | | - ["find", "_skbuild", "-name", "index.html"], cwd=setup_dir |
94 | | - ) |
95 | | - .decode("utf-8") |
96 | | - .strip("\n") |
97 | | - ) |
98 | | - print("Generated documentation placed under ", generated_doc_dir) |
| 25 | +from _build_helper import ( # noqa: E402 |
| 26 | + build_extension, |
| 27 | + clean_build_dir, |
| 28 | + err, |
| 29 | + get_output, |
| 30 | + install_editable, |
| 31 | + make_cmake_args, |
| 32 | + resolve_compilers, |
| 33 | + run, |
| 34 | + warn, |
| 35 | +) |
99 | 36 |
|
100 | 37 |
|
101 | | -if __name__ == "__main__": |
102 | | - import argparse |
| 38 | +def parse_args(): |
| 39 | + p = argparse.ArgumentParser(description="Build dpctl and generate coverage") |
103 | 40 |
|
104 | | - parser = argparse.ArgumentParser( |
105 | | - description="Driver to build dpctl and generate coverage" |
| 41 | + p.add_argument( |
| 42 | + "--c-compiler", default=None, help="Path or name of C compiler" |
| 43 | + ) |
| 44 | + p.add_argument( |
| 45 | + "--cxx-compiler", default=None, help="Path or name of C++ compiler" |
106 | 46 | ) |
107 | | - driver = parser.add_argument_group(title="Coverage driver arguments") |
108 | | - driver.add_argument("--c-compiler", help="Name of C compiler", default=None) |
109 | | - driver.add_argument( |
110 | | - "--cxx-compiler", help="Name of C++ compiler", default=None |
| 47 | + p.add_argument( |
| 48 | + "--compiler-root", |
| 49 | + type=str, |
| 50 | + default=None, |
| 51 | + help="Path to compiler installation root", |
111 | 52 | ) |
112 | | - driver.add_argument( |
113 | | - "--not-oneapi", |
114 | | - help="Is one-API installation", |
| 53 | + p.add_argument( |
| 54 | + "--oneapi", |
115 | 55 | dest="oneapi", |
116 | | - action="store_false", |
| 56 | + action="store_true", |
| 57 | + help="Use default oneAPI compiler layout", |
117 | 58 | ) |
118 | | - driver.add_argument( |
119 | | - "--compiler-root", type=str, help="Path to compiler home directory" |
| 59 | + |
| 60 | + p.add_argument( |
| 61 | + "--verbose", |
| 62 | + dest="verbose", |
| 63 | + action="store_true", |
| 64 | + help="Enable verbose makefile output", |
120 | 65 | ) |
121 | | - driver.add_argument( |
| 66 | + |
| 67 | + p.add_argument( |
122 | 68 | "--no-level-zero", |
123 | | - help="Enable Level Zero support", |
124 | | - dest="level_zero", |
125 | | - action="store_false", |
| 69 | + dest="no_level_zero", |
| 70 | + action="store_true", |
| 71 | + default=False, |
| 72 | + help="Disable Level Zero backend (deprecated: use --target-level-zero " |
| 73 | + "OFF)", |
| 74 | + ) |
| 75 | + p.add_argument( |
| 76 | + "--target-level-zero", |
| 77 | + action="store_true", |
| 78 | + help="Enable Level Zero backend explicitly", |
126 | 79 | ) |
127 | | - driver.add_argument( |
128 | | - "--bin-llvm", help="Path to folder where llvm-cov can be found" |
| 80 | + |
| 81 | + p.add_argument( |
| 82 | + "--generator", type=str, default="Ninja", help="CMake generator" |
| 83 | + ) |
| 84 | + p.add_argument( |
| 85 | + "--cmake-executable", |
| 86 | + type=str, |
| 87 | + default=None, |
| 88 | + help="Path to CMake executable used by build", |
| 89 | + ) |
| 90 | + |
| 91 | + p.add_argument( |
| 92 | + "--cmake-opts", |
| 93 | + type=str, |
| 94 | + default="", |
| 95 | + help="Additional options to pass directly to CMake", |
129 | 96 | ) |
130 | | - driver.add_argument( |
| 97 | + |
| 98 | + p.add_argument( |
131 | 99 | "--doxyrest-root", |
132 | 100 | help=( |
133 | 101 | "Path to Doxyrest installation to use to generate Sphinx docs" |
134 | 102 | + "for libsyclinterface" |
135 | 103 | ), |
136 | 104 | ) |
137 | | - driver.add_argument( |
138 | | - "--verbose", |
139 | | - help="Build using vebose makefile mode", |
140 | | - dest="verbose", |
| 105 | + |
| 106 | + p.add_argument( |
| 107 | + "--clean", |
141 | 108 | action="store_true", |
| 109 | + help="Remove build dir before rebuild (default: False)", |
142 | 110 | ) |
143 | | - driver.add_argument( |
144 | | - "--cmake-opts", |
145 | | - help="Options to pass through to cmake", |
146 | | - dest="cmake_opts", |
147 | | - default="", |
148 | | - type=str, |
| 111 | + |
| 112 | + return p.parse_args() |
| 113 | + |
| 114 | + |
| 115 | +def main(): |
| 116 | + is_linux = "linux" in sys.platform |
| 117 | + if not is_linux: |
| 118 | + err(f"{sys.platform} not supported", "gen_docs") |
| 119 | + args = parse_args() |
| 120 | + setup_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 121 | + |
| 122 | + c_compiler, cxx_compiler = resolve_compilers( |
| 123 | + args.oneapi, |
| 124 | + args.c_compiler, |
| 125 | + args.cxx_compiler, |
| 126 | + args.compiler_root, |
149 | 127 | ) |
150 | 128 |
|
151 | | - args = parser.parse_args() |
| 129 | + if args.clean: |
| 130 | + clean_build_dir(setup_dir) |
152 | 131 |
|
153 | | - if args.oneapi: |
154 | | - args.c_compiler = "icx" |
155 | | - args.cxx_compiler = "icpx" |
156 | | - args.compiler_root = None |
157 | | - icx_path = subprocess.check_output(["which", "icx"]) |
158 | | - bin_dir = os.path.dirname(icx_path) |
159 | | - args.bin_llvm = os.path.join(bin_dir.decode("utf-8"), "compiler") |
| 132 | + if args.no_level_zero and args.target_level_zero: |
| 133 | + err( |
| 134 | + "Cannot combine --no-level-zero and --target-level-zero", |
| 135 | + "gen_coverage", |
| 136 | + ) |
| 137 | + |
| 138 | + # Level Zero state (on unless explicitly disabled) |
| 139 | + if args.no_level_zero: |
| 140 | + level_zero_enabled = False |
| 141 | + elif args.target_level_zero: |
| 142 | + level_zero_enabled = True |
160 | 143 | else: |
161 | | - args_to_validate = [ |
162 | | - "c_compiler", |
163 | | - "cxx_compiler", |
164 | | - "compiler_root", |
165 | | - "bin_llvm", |
166 | | - ] |
167 | | - for p in args_to_validate: |
168 | | - arg = getattr(args, p, None) |
169 | | - if not isinstance(arg, str): |
170 | | - opt_name = p.replace("_", "-") |
171 | | - raise RuntimeError( |
172 | | - f"Option {opt_name} must be provided is " |
173 | | - "using non-default DPC++ layout" |
174 | | - ) |
175 | | - if not os.path.exists(arg): |
176 | | - raise RuntimeError(f"Path {arg} must exist") |
| 144 | + level_zero_enabled = True |
177 | 145 |
|
178 | | - run( |
179 | | - use_oneapi=args.oneapi, |
180 | | - c_compiler=args.c_compiler, |
181 | | - cxx_compiler=args.cxx_compiler, |
182 | | - level_zero=args.level_zero, |
183 | | - compiler_root=args.compiler_root, |
184 | | - bin_llvm=args.bin_llvm, |
185 | | - doxyrest_dir=args.doxyrest_root, |
| 146 | + cmake_args = make_cmake_args( |
| 147 | + c_compiler=c_compiler, |
| 148 | + cxx_compiler=cxx_compiler, |
| 149 | + level_zero=level_zero_enabled, |
186 | 150 | verbose=args.verbose, |
187 | | - cmake_opts=args.cmake_opts, |
188 | 151 | ) |
| 152 | + |
| 153 | + cmake_args += " -DDPCTL_GENERATE_DOCS=ON" |
| 154 | + |
| 155 | + if args.doxyrest_root: |
| 156 | + cmake_args += " -DDPCTL_ENABLE_DOXYREST=ON" |
| 157 | + cmake_args += f" -DDoxyrest_DIR={args.doxyrest_root}" |
| 158 | + |
| 159 | + env = os.environ.copy() |
| 160 | + |
| 161 | + if "CMAKE_ARGS" in env and env["CMAKE_ARGS"].strip(): |
| 162 | + warn("Ignoring pre-existing CMAKE_ARGS in environment", "gen_docs") |
| 163 | + del env["CMAKE_ARGS"] |
| 164 | + |
| 165 | + env["CMAKE_ARGS"] = cmake_args |
| 166 | + |
| 167 | + print(f"[gen_docs] Using CMake args:\n {env['CMAKE_ARGS']}") |
| 168 | + |
| 169 | + build_extension( |
| 170 | + setup_dir, |
| 171 | + env, |
| 172 | + cmake_executable=args.cmake_executable, |
| 173 | + generator=args.generator, |
| 174 | + build_type="Release", |
| 175 | + ) |
| 176 | + install_editable(setup_dir, env) |
| 177 | + cmake_build_dir = get_output( |
| 178 | + ["find", "_skbuild", "-name", "cmake-build"], cwd=setup_dir |
| 179 | + ) |
| 180 | + |
| 181 | + print(f"[gen_docs] Found CMake build dir: {cmake_build_dir}") |
| 182 | + |
| 183 | + run( |
| 184 | + ["cmake", "--build", ".", "--target", "Sphinx"], |
| 185 | + cwd=cmake_build_dir, |
| 186 | + ) |
| 187 | + |
| 188 | + generated_doc_dir = ( |
| 189 | + subprocess.check_output( |
| 190 | + ["find", "_skbuild", "-name", "index.html"], cwd=setup_dir |
| 191 | + ) |
| 192 | + .decode("utf-8") |
| 193 | + .strip("\n") |
| 194 | + ) |
| 195 | + print("Generated documentation placed under ", generated_doc_dir) |
| 196 | + |
| 197 | + print("[gen_docs] Done") |
| 198 | + |
| 199 | + |
| 200 | +if __name__ == "__main__": |
| 201 | + main() |
0 commit comments