Brian Silverman | 7d89e28 | 2021-11-17 17:36:54 -0800 | [diff] [blame] | 1 | # Copyright 2018 The Bazel Authors. |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | |
| 15 | load( |
| 16 | "//toolchain/internal:common.bzl", |
| 17 | _supported_os_arch_keys = "supported_os_arch_keys", |
| 18 | ) |
| 19 | load( |
| 20 | "//toolchain/internal:configure.bzl", |
| 21 | _llvm_config_impl = "llvm_config_impl", |
| 22 | ) |
| 23 | load( |
| 24 | "//toolchain/internal:repo.bzl", |
| 25 | _llvm_repo_impl = "llvm_repo_impl", |
| 26 | ) |
| 27 | |
| 28 | _common_attrs = { |
| 29 | "llvm_version": attr.string( |
| 30 | mandatory = True, |
| 31 | doc = "One of the supported versions of LLVM, e.g. 12.0.0", |
| 32 | ), |
| 33 | } |
| 34 | |
| 35 | _llvm_repo_attrs = dict(_common_attrs) |
| 36 | _llvm_repo_attrs.update({ |
| 37 | "distribution": attr.string( |
| 38 | default = "auto", |
| 39 | doc = ("LLVM pre-built binary distribution filename, must be one " + |
| 40 | "listed on http://releases.llvm.org/download.html for the version " + |
| 41 | "specified in the llvm_version attribute. A special value of " + |
| 42 | "'auto' tries to detect the version based on host OS."), |
| 43 | ), |
| 44 | "llvm_mirror": attr.string( |
| 45 | doc = "Base URL for an LLVM release mirror." + |
| 46 | "\n\n" + |
| 47 | "This mirror must follow the same structure as the official LLVM release " + |
| 48 | "sources (`releases.llvm.org` for versions <= 9, `llvm/llvm-project` GitHub " + |
| 49 | "releases for newer versions)." + |
| 50 | "\n\n" + |
| 51 | "If provided, this mirror will be given precedence over the official LLVM release " + |
| 52 | "sources (see: " + |
| 53 | "https://github.com/grailbio/bazel-toolchain/toolchain/internal/llvm_distributions.bzl).", |
| 54 | ), |
| 55 | "alternative_llvm_sources": attr.string_list( |
| 56 | doc = "Patterns for alternative LLVM release sources. Unlike URLs specified for `llvm_mirror` " + |
| 57 | "these do not have to follow the same structure as the official LLVM release sources." + |
| 58 | "\n\n" + |
| 59 | "Patterns may include `{llvm_version}` (which will be substituted for the full LLVM " + |
| 60 | "version, i.e. 13.0.0) and `{basename}` (which will be replaced with the filename " + |
| 61 | "used by the official LLVM release sources for a particular distribution; i.e. " + |
| 62 | "`llvm-13.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz`)." + |
| 63 | "\n\n" + |
| 64 | "As with `llvm_mirror`, these sources will take precedence over the official LLVM " + |
| 65 | "release sources.", |
| 66 | ), |
| 67 | "netrc": attr.string( |
| 68 | mandatory = False, |
| 69 | doc = "Path to the netrc file for authenticated LLVM URL downloads.", |
| 70 | ), |
| 71 | "auth_patterns": attr.string_dict( |
| 72 | mandatory = False, |
| 73 | doc = "An optional dict mapping host names to custom authorization patterns.", |
| 74 | ), |
| 75 | "_llvm_release_name": attr.label( |
| 76 | default = "//toolchain/tools:llvm_release_name.py", |
| 77 | allow_single_file = True, |
| 78 | doc = "Python module to output LLVM release name for the current OS.", |
| 79 | ), |
| 80 | }) |
| 81 | |
| 82 | _llvm_config_attrs = dict(_common_attrs) |
| 83 | _llvm_config_attrs.update({ |
| 84 | "toolchain_roots": attr.string_dict( |
| 85 | mandatory = True, |
| 86 | # TODO: Ideally, we should be taking a filegroup label here instead of a package path, but |
| 87 | # we ultimately need to subset the files to be more selective in what we include in the |
| 88 | # sandbox for which operations, and it is not straightforward to subset a filegroup. |
| 89 | doc = ("System or package path, for each host OS and arch pair you want to support " + |
| 90 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 91 | "to be used as the LLVM toolchain distributions. An empty key can be used to " + |
| 92 | "specify a fallback default for all hosts, e.g. with the llvm_toolchain_repo rule. " + |
| 93 | "If the value begins with exactly one forward slash '/', then the value is " + |
| 94 | "assumed to be a system path and the toolchain is configured to use absolute " + |
| 95 | "paths. Else, the value will be assumed to be a bazel package containing the " + |
| 96 | "filegroup targets as in BUILD.llvm_repo."), |
| 97 | ), |
Brian Silverman | 4c7235a | 2021-11-17 19:04:37 -0800 | [diff] [blame] | 98 | "target_toolchain_roots": attr.string_dict( |
| 99 | mandatory = True, |
| 100 | # TODO: Ideally, we should be taking a filegroup label here instead of a package path, but |
| 101 | # we ultimately need to subset the files to be more selective in what we include in the |
| 102 | # sandbox for which operations, and it is not straightforward to subset a filegroup. |
| 103 | doc = ("System or package path, for each target OS and arch pair you want to support " + |
| 104 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 105 | "to be used as the LLVM toolchain distributions. " + |
| 106 | "If the value begins with exactly one forward slash '/', then the value is " + |
| 107 | "assumed to be a system path and the toolchain is configured to use absolute " + |
| 108 | "paths. Else, the value will be assumed to be a bazel package containing the " + |
| 109 | "filegroup targets as in BUILD.llvm_repo."), |
| 110 | ), |
Brian Silverman | 7d89e28 | 2021-11-17 17:36:54 -0800 | [diff] [blame] | 111 | "sysroot": attr.string_dict( |
| 112 | mandatory = False, |
| 113 | doc = ("System path or fileset, for each target OS and arch pair you want to support " + |
| 114 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 115 | "used to indicate the set of files that form the sysroot for the compiler. " + |
| 116 | "If the value begins with exactly one forward slash '/', then the value is " + |
| 117 | "assumed to be a system path. Else, the value will be assumed to be a label " + |
| 118 | "containing the files and the sysroot path will be taken as the path to the " + |
| 119 | "package of this label."), |
| 120 | ), |
| 121 | "cxx_builtin_include_directories": attr.string_list_dict( |
| 122 | mandatory = False, |
| 123 | doc = ("Additional builtin include directories to be added to the default system " + |
| 124 | "directories, for each target OS and arch pair you want to support " + |
| 125 | "({}); ".format(", ".join(_supported_os_arch_keys())) + |
| 126 | "see documentation for bazel's create_cc_toolchain_config_info."), |
| 127 | ), |
Brian Silverman | 4c7235a | 2021-11-17 19:04:37 -0800 | [diff] [blame] | 128 | "standard_libraries": attr.string_dict( |
| 129 | mandatory = False, |
| 130 | doc = ("The C++ standard library to use, " + |
| 131 | "for each target OS and arch pair you want to support " + |
| 132 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 133 | "used to find this version in the sysroot or host system. " + |
| 134 | "If set to \"libc++\" \"libstdc++\", that will be passed to clang directly. " + |
| 135 | "If set to \"libstdc++-N\", then explicit paths for major version N of " + |
| 136 | "libstdc++ will be passed to clang."), |
| 137 | ), |
| 138 | "additional_target_compatible_with": attr.string_list_dict( |
| 139 | mandatory = False, |
| 140 | doc = ("Additional target_compatible_with values, " + |
| 141 | "for each target OS and arch pair you want to support " + |
| 142 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 143 | "in addition to the @platforms//os and @platforms//cpu entries " + |
| 144 | "added automatically."), |
| 145 | ), |
| 146 | "conlyopts": attr.string_list_dict( |
| 147 | mandatory = False, |
| 148 | doc = ("Extra flags for compiling C (not C++) files, " + |
| 149 | "for each target OS and arch pair you want to support " + |
| 150 | "({}), ".format(", ".join(_supported_os_arch_keys())) + "."), |
| 151 | ), |
| 152 | "cxxopts": attr.string_list_dict( |
| 153 | mandatory = False, |
| 154 | doc = ("Extra flags for compiling C++ (not C) files, " + |
| 155 | "for each target OS and arch pair you want to support " + |
| 156 | "({}), ".format(", ".join(_supported_os_arch_keys())) + "."), |
| 157 | ), |
| 158 | "copts": attr.string_list_dict( |
| 159 | mandatory = False, |
| 160 | doc = ("Extra flags for compiling C, C++, and assembly files, " + |
| 161 | "for each target OS and arch pair you want to support " + |
| 162 | "({}), ".format(", ".join(_supported_os_arch_keys())) + "."), |
| 163 | ), |
| 164 | "opt_copts": attr.string_list_dict( |
| 165 | mandatory = False, |
| 166 | doc = ("Extra flags for compiling C, C++, and assembly files, " + |
| 167 | "for each target OS and arch pair you want to support " + |
| 168 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 169 | "used only with -c opt."), |
| 170 | ), |
| 171 | "dbg_copts": attr.string_list_dict( |
| 172 | mandatory = False, |
| 173 | doc = ("Extra flags for compiling C, C++, and assembly files, " + |
| 174 | "for each target OS and arch pair you want to support " + |
| 175 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 176 | "used only with -c dbg."), |
| 177 | ), |
Brian Silverman | 1e7c897 | 2022-02-03 23:15:41 -0800 | [diff] [blame] | 178 | "fastbuild_copts": attr.string_list_dict( |
| 179 | mandatory = False, |
| 180 | doc = ("Extra flags for compiling C, C++, and assembly files, " + |
| 181 | "for each target OS and arch pair you want to support " + |
| 182 | "({}), ".format(", ".join(_supported_os_arch_keys())) + |
| 183 | "used only with -c fastbuild."), |
| 184 | ), |
Brian Silverman | 4c7235a | 2021-11-17 19:04:37 -0800 | [diff] [blame] | 185 | "linkopts": attr.string_list_dict( |
| 186 | mandatory = False, |
| 187 | doc = ("Extra flags to pass to the linker, " + |
| 188 | "for each target OS and arch pair you want to support " + |
| 189 | "({}), ".format(", ".join(_supported_os_arch_keys())) + "."), |
| 190 | ), |
| 191 | "static_libstdcxx": attr.bool( |
| 192 | default = True, |
| 193 | doc = "Link the C++ standard library statically. Note that this applies " + |
| 194 | "to all C++ standard libraries, like the -static-libstdc++ clang flag.", |
| 195 | ), |
Brian Silverman | 7d89e28 | 2021-11-17 17:36:54 -0800 | [diff] [blame] | 196 | "absolute_paths": attr.bool( |
| 197 | default = False, |
| 198 | doc = "Use absolute paths in the toolchain. Avoids sandbox overhead.", |
| 199 | ), |
| 200 | "_cc_toolchain_config_bzl": attr.label( |
| 201 | default = "//toolchain:cc_toolchain_config.bzl", |
| 202 | ), |
| 203 | }) |
| 204 | |
| 205 | llvm = repository_rule( |
| 206 | attrs = _llvm_repo_attrs, |
| 207 | local = False, |
| 208 | implementation = _llvm_repo_impl, |
| 209 | ) |
| 210 | |
| 211 | toolchain = repository_rule( |
| 212 | attrs = _llvm_config_attrs, |
| 213 | local = True, |
| 214 | configure = True, |
| 215 | implementation = _llvm_config_impl, |
| 216 | ) |
| 217 | |
| 218 | def llvm_toolchain(name, **kwargs): |
| 219 | if not kwargs.get("toolchain_roots"): |
| 220 | llvm_args = { |
| 221 | k: v |
| 222 | for k, v in kwargs.items() |
| 223 | if (k not in _llvm_config_attrs.keys()) or (k in _common_attrs.keys()) |
| 224 | } |
| 225 | llvm(name = name + "_llvm", **llvm_args) |
| 226 | kwargs.update(toolchain_roots = {"": "@%s_llvm//" % name}) |
| 227 | |
| 228 | toolchain_args = { |
| 229 | k: v |
| 230 | for k, v in kwargs.items() |
| 231 | if (k not in _llvm_repo_attrs.keys()) or (k in _common_attrs.keys()) |
| 232 | } |
| 233 | toolchain(name = name, **toolchain_args) |