Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 1 | # 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-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 7 | # Directory of overlay files relative to WORKSPACE |
| 8 | DEFAULT_OVERLAY_PATH = "llvm-project-overlay" |
| 9 | |
| 10 | DEFAULT_TARGETS = [ |
| 11 | "AArch64", |
| 12 | "AMDGPU", |
| 13 | "ARM", |
Itai Zukerman | 3ff451c | 2021-07-28 20:27:05 | [diff] [blame] | 14 | "AVR", |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 15 | "BPF", |
| 16 | "Hexagon", |
| 17 | "Lanai", |
NAKAMURA Takumi | 1bdb295 | 2023-01-11 14:15:20 | [diff] [blame] | 18 | "LoongArch", |
Itai Zukerman | 3ff451c | 2021-07-28 20:27:05 | [diff] [blame] | 19 | "Mips", |
| 20 | "MSP430", |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 21 | "NVPTX", |
| 22 | "PowerPC", |
| 23 | "RISCV", |
| 24 | "Sparc", |
NAKAMURA Takumi | 68fdc09 | 2025-01-21 22:58:05 | [diff] [blame] | 25 | "SPIRV", |
Itai Zukerman | 3ff451c | 2021-07-28 20:27:05 | [diff] [blame] | 26 | "SystemZ", |
NAKAMURA Takumi | 6f43477 | 2022-05-26 13:37:14 | [diff] [blame] | 27 | "VE", |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 28 | "WebAssembly", |
| 29 | "X86", |
Itai Zukerman | 3ff451c | 2021-07-28 20:27:05 | [diff] [blame] | 30 | "XCore", |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 31 | ] |
| 32 | |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 33 | def _overlay_directories(repository_ctx): |
Aaron Siddhartha Mondal | 762c709 | 2023-05-07 13:34:15 | [diff] [blame] | 34 | src_path = repository_ctx.path(Label("@llvm-raw//:WORKSPACE")).dirname |
Christian Sigg | 81d5412 | 2021-08-18 07:14:42 | [diff] [blame] | 35 | 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-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 38 | |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 39 | 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 Sigg | 81d5412 | 2021-08-18 07:14:42 | [diff] [blame] | 50 | script_path, |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 51 | "--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 Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 71 | def _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 Smiley | 4b077ed | 2024-04-04 22:10:52 | [diff] [blame] | 79 | "LLVM_VERSION_SUFFIX": None, |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 80 | } |
| 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 Wu | 75cb138 | 2023-01-16 12:13:20 | [diff] [blame] | 92 | |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 93 | # `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 Wu | 75cb138 | 2023-01-16 12:13:20 | [diff] [blame] | 103 | |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 104 | # 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 Wu | 75cb138 | 2023-01-16 12:13:20 | [diff] [blame] | 110 | |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 111 | # Skip if `CMAKE_CXX_STANDARD` is set with |
| 112 | # `LLVM_REQUIRED_CXX_STANDARD`. |
| 113 | # Then `v` will not be desired form, like "${...} CACHE" |
Jordan Rupprecht | 10ecdee | 2024-06-03 17:19:50 | [diff] [blame] | 114 | if c[k] != None: |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 115 | continue |
Haojian Wu | 75cb138 | 2023-01-16 12:13:20 | [diff] [blame] | 116 | |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 117 | # 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 Smiley | 4b077ed | 2024-04-04 22:10:52 | [diff] [blame] | 129 | 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 Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 136 | return c |
| 137 | |
| 138 | def _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 Wu | 45ab848 | 2023-01-16 11:57:57 | [diff] [blame] | 148 | repository_ctx.file(filepath, content = fci + fcd + fct) |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 149 | |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 150 | def _llvm_configure_impl(repository_ctx): |
| 151 | _overlay_directories(repository_ctx) |
| 152 | |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 153 | llvm_cmake = "llvm/CMakeLists.txt" |
| 154 | vars = _extract_cmake_settings( |
| 155 | repository_ctx, |
| 156 | llvm_cmake, |
| 157 | ) |
| 158 | |
Benjamin Kramer | 36a2752 | 2024-03-11 17:21:19 | [diff] [blame] | 159 | # 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 Rupprecht | 10ecdee | 2024-06-03 17:19:50 | [diff] [blame] | 164 | version = {k: v for k, v in version.items() if v != None} |
Benjamin Kramer | 36a2752 | 2024-03-11 17:21:19 | [diff] [blame] | 165 | vars.update(version) |
| 166 | |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 167 | _write_dict_to_file( |
| 168 | repository_ctx, |
Haojian Wu | 45ab848 | 2023-01-16 11:57:57 | [diff] [blame] | 169 | filepath = "vars.bzl", |
| 170 | header = "# Generated from {}\n\n".format(llvm_cmake), |
| 171 | vars = vars, |
NAKAMURA Takumi | f72601a | 2023-01-08 11:39:09 | [diff] [blame] | 172 | ) |
| 173 | |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 174 | # Create a starlark file with the requested LLVM targets. |
Christian Sigg | ef21831 | 2025-02-18 10:24:15 | [diff] [blame] | 175 | llvm_targets = repository_ctx.attr.targets |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 176 | repository_ctx.file( |
| 177 | "llvm/targets.bzl", |
Christian Sigg | ef21831 | 2025-02-18 10:24:15 | [diff] [blame] | 178 | 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-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 188 | executable = False, |
| 189 | ) |
| 190 | |
| 191 | llvm_configure = repository_rule( |
| 192 | implementation = _llvm_configure_impl, |
| 193 | local = True, |
| 194 | configure = True, |
| 195 | attrs = { |
Geoffrey Martin-Noble | 4aeb2e6 | 2021-05-18 22:42:25 | [diff] [blame] | 196 | "targets": attr.string_list(default = DEFAULT_TARGETS), |
| 197 | }, |
| 198 | ) |