blob: fcc9fc7ecc483648a933928cfa227b3de02f28e8 [file] [log] [blame]
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:251# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5"""Helper macros to configure the LLVM overlay project."""
6
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:257# Directory of overlay files relative to WORKSPACE
8DEFAULT_OVERLAY_PATH = "llvm-project-overlay"
9
10DEFAULT_TARGETS = [
11 "AArch64",
12 "AMDGPU",
13 "ARM",
Itai Zukerman3ff451c2021-07-28 20:27:0514 "AVR",
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2515 "BPF",
16 "Hexagon",
17 "Lanai",
NAKAMURA Takumi1bdb2952023-01-11 14:15:2018 "LoongArch",
Itai Zukerman3ff451c2021-07-28 20:27:0519 "Mips",
20 "MSP430",
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2521 "NVPTX",
22 "PowerPC",
23 "RISCV",
24 "Sparc",
NAKAMURA Takumi68fdc092025-01-21 22:58:0525 "SPIRV",
Itai Zukerman3ff451c2021-07-28 20:27:0526 "SystemZ",
NAKAMURA Takumi6f434772022-05-26 13:37:1427 "VE",
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2528 "WebAssembly",
29 "X86",
Itai Zukerman3ff451c2021-07-28 20:27:0530 "XCore",
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2531]
32
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2533def _overlay_directories(repository_ctx):
Aaron Siddhartha Mondal762c7092023-05-07 13:34:1534 src_path = repository_ctx.path(Label("@llvm-raw//:WORKSPACE")).dirname
Christian Sigg81d54122021-08-18 07:14:4235 bazel_path = src_path.get_child("utils").get_child("bazel")
36 overlay_path = bazel_path.get_child("llvm-project-overlay")
37 script_path = bazel_path.get_child("overlay_directories.py")
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2538
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2539 python_bin = repository_ctx.which("python3")
40 if not python_bin:
41 # Windows typically just defines "python" as python3. The script itself
42 # contains a check to ensure python3.
43 python_bin = repository_ctx.which("python")
44
45 if not python_bin:
46 fail("Failed to find python3 binary")
47
48 cmd = [
49 python_bin,
Christian Sigg81d54122021-08-18 07:14:4250 script_path,
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:2551 "--src",
52 src_path,
53 "--overlay",
54 overlay_path,
55 "--target",
56 ".",
57 ]
58 exec_result = repository_ctx.execute(cmd, timeout = 20)
59
60 if exec_result.return_code != 0:
61 fail(("Failed to execute overlay script: '{cmd}'\n" +
62 "Exited with code {return_code}\n" +
63 "stdout:\n{stdout}\n" +
64 "stderr:\n{stderr}\n").format(
65 cmd = " ".join([str(arg) for arg in cmd]),
66 return_code = exec_result.return_code,
67 stdout = exec_result.stdout,
68 stderr = exec_result.stderr,
69 ))
70
NAKAMURA Takumif72601a2023-01-08 11:39:0971def _extract_cmake_settings(repository_ctx, llvm_cmake):
72 # The list to be written to vars.bzl
73 # `CMAKE_CXX_STANDARD` may be used from WORKSPACE for the toolchain.
74 c = {
75 "CMAKE_CXX_STANDARD": None,
76 "LLVM_VERSION_MAJOR": None,
77 "LLVM_VERSION_MINOR": None,
78 "LLVM_VERSION_PATCH": None,
Keith Smiley4b077ed2024-04-04 22:10:5279 "LLVM_VERSION_SUFFIX": None,
NAKAMURA Takumif72601a2023-01-08 11:39:0980 }
81
82 # It would be easier to use external commands like sed(1) and python.
83 # For portability, the parser should run on Starlark.
84 llvm_cmake_path = repository_ctx.path(Label("//:" + llvm_cmake))
85 for line in repository_ctx.read(llvm_cmake_path).splitlines():
86 # Extract "set ( FOO bar ... "
87 setfoo = line.partition("(")
88 if setfoo[1] != "(":
89 continue
90 if setfoo[0].strip().lower() != "set":
91 continue
Haojian Wu75cb1382023-01-16 12:13:2092
NAKAMURA Takumif72601a2023-01-08 11:39:0993 # `kv` is assumed as \s*KEY\s+VAL\s*\).*
94 # Typical case is like
95 # LLVM_REQUIRED_CXX_STANDARD 17)
96 # Possible case -- It should be ignored.
97 # CMAKE_CXX_STANDARD ${...} CACHE STRING "...")
98 kv = setfoo[2].strip()
99 i = kv.find(" ")
100 if i < 0:
101 continue
102 k = kv[:i]
Haojian Wu75cb1382023-01-16 12:13:20103
NAKAMURA Takumif72601a2023-01-08 11:39:09104 # Prefer LLVM_REQUIRED_CXX_STANDARD instead of CMAKE_CXX_STANDARD
105 if k == "LLVM_REQUIRED_CXX_STANDARD":
106 k = "CMAKE_CXX_STANDARD"
107 c[k] = None
108 if k not in c:
109 continue
Haojian Wu75cb1382023-01-16 12:13:20110
NAKAMURA Takumif72601a2023-01-08 11:39:09111 # Skip if `CMAKE_CXX_STANDARD` is set with
112 # `LLVM_REQUIRED_CXX_STANDARD`.
113 # Then `v` will not be desired form, like "${...} CACHE"
Jordan Rupprecht10ecdee2024-06-03 17:19:50114 if c[k] != None:
NAKAMURA Takumif72601a2023-01-08 11:39:09115 continue
Haojian Wu75cb1382023-01-16 12:13:20116
NAKAMURA Takumif72601a2023-01-08 11:39:09117 # Pick up 1st word as the value.
118 # Note: It assumes unquoted word.
119 v = kv[i:].strip().partition(")")[0].partition(" ")[0]
120 c[k] = v
121
122 # Synthesize `LLVM_VERSION` for convenience.
123 c["LLVM_VERSION"] = "{}.{}.{}".format(
124 c["LLVM_VERSION_MAJOR"],
125 c["LLVM_VERSION_MINOR"],
126 c["LLVM_VERSION_PATCH"],
127 )
128
Keith Smiley4b077ed2024-04-04 22:10:52129 c["PACKAGE_VERSION"] = "{}.{}.{}{}".format(
130 c["LLVM_VERSION_MAJOR"],
131 c["LLVM_VERSION_MINOR"],
132 c["LLVM_VERSION_PATCH"],
133 c["LLVM_VERSION_SUFFIX"],
134 )
135
NAKAMURA Takumif72601a2023-01-08 11:39:09136 return c
137
138def _write_dict_to_file(repository_ctx, filepath, header, vars):
139 # (fci + individual vars) + (fcd + dict items) + (fct)
140 fci = header
141 fcd = "\nllvm_vars={\n"
142 fct = "}\n"
143
144 for k, v in vars.items():
145 fci += '{} = "{}"\n'.format(k, v)
146 fcd += ' "{}": "{}",\n'.format(k, v)
147
Haojian Wu45ab8482023-01-16 11:57:57148 repository_ctx.file(filepath, content = fci + fcd + fct)
NAKAMURA Takumif72601a2023-01-08 11:39:09149
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:25150def _llvm_configure_impl(repository_ctx):
151 _overlay_directories(repository_ctx)
152
NAKAMURA Takumif72601a2023-01-08 11:39:09153 llvm_cmake = "llvm/CMakeLists.txt"
154 vars = _extract_cmake_settings(
155 repository_ctx,
156 llvm_cmake,
157 )
158
Benjamin Kramer36a27522024-03-11 17:21:19159 # Grab version info and merge it with the other vars
160 version = _extract_cmake_settings(
161 repository_ctx,
162 "cmake/Modules/LLVMVersion.cmake",
163 )
Jordan Rupprecht10ecdee2024-06-03 17:19:50164 version = {k: v for k, v in version.items() if v != None}
Benjamin Kramer36a27522024-03-11 17:21:19165 vars.update(version)
166
NAKAMURA Takumif72601a2023-01-08 11:39:09167 _write_dict_to_file(
168 repository_ctx,
Haojian Wu45ab8482023-01-16 11:57:57169 filepath = "vars.bzl",
170 header = "# Generated from {}\n\n".format(llvm_cmake),
171 vars = vars,
NAKAMURA Takumif72601a2023-01-08 11:39:09172 )
173
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:25174 # Create a starlark file with the requested LLVM targets.
Christian Siggef218312025-02-18 10:24:15175 llvm_targets = repository_ctx.attr.targets
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:25176 repository_ctx.file(
177 "llvm/targets.bzl",
Christian Siggef218312025-02-18 10:24:15178 content = "llvm_targets = " + str(llvm_targets),
179 executable = False,
180 )
181
182 # Create a starlark file with the requested BOLT targets.
183 bolt_targets = ["AArch64","X86","RISCV"] # Supported targets.
184 bolt_targets = [t for t in llvm_targets if t in bolt_targets]
185 repository_ctx.file(
186 "bolt/targets.bzl",
187 content = "bolt_targets = " + str(bolt_targets),
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:25188 executable = False,
189 )
190
191llvm_configure = repository_rule(
192 implementation = _llvm_configure_impl,
193 local = True,
194 configure = True,
195 attrs = {
Geoffrey Martin-Noble4aeb2e62021-05-18 22:42:25196 "targets": attr.string_list(default = DEFAULT_TARGETS),
197 },
198)