blob: f27e3875e24d14b29ad4b820360620ec3815f59a [file] [log] [blame]
Brian Silverman7d89e282021-11-17 17:36:54 -08001# 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
15load(
16 "//toolchain/internal:common.bzl",
17 _supported_os_arch_keys = "supported_os_arch_keys",
18)
19load(
20 "//toolchain/internal:configure.bzl",
21 _llvm_config_impl = "llvm_config_impl",
22)
23load(
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 Silverman4c7235a2021-11-17 19:04:37 -080098 "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 Silverman7d89e282021-11-17 17:36:54 -0800111 "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 Silverman4c7235a2021-11-17 19:04:37 -0800128 "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 ),
178 "linkopts": attr.string_list_dict(
179 mandatory = False,
180 doc = ("Extra flags to pass to the linker, " +
181 "for each target OS and arch pair you want to support " +
182 "({}), ".format(", ".join(_supported_os_arch_keys())) + "."),
183 ),
184 "static_libstdcxx": attr.bool(
185 default = True,
186 doc = "Link the C++ standard library statically. Note that this applies " +
187 "to all C++ standard libraries, like the -static-libstdc++ clang flag.",
188 ),
Brian Silverman7d89e282021-11-17 17:36:54 -0800189 "absolute_paths": attr.bool(
190 default = False,
191 doc = "Use absolute paths in the toolchain. Avoids sandbox overhead.",
192 ),
193 "_cc_toolchain_config_bzl": attr.label(
194 default = "//toolchain:cc_toolchain_config.bzl",
195 ),
196})
197
198llvm = repository_rule(
199 attrs = _llvm_repo_attrs,
200 local = False,
201 implementation = _llvm_repo_impl,
202)
203
204toolchain = repository_rule(
205 attrs = _llvm_config_attrs,
206 local = True,
207 configure = True,
208 implementation = _llvm_config_impl,
209)
210
211def llvm_toolchain(name, **kwargs):
212 if not kwargs.get("toolchain_roots"):
213 llvm_args = {
214 k: v
215 for k, v in kwargs.items()
216 if (k not in _llvm_config_attrs.keys()) or (k in _common_attrs.keys())
217 }
218 llvm(name = name + "_llvm", **llvm_args)
219 kwargs.update(toolchain_roots = {"": "@%s_llvm//" % name})
220
221 toolchain_args = {
222 k: v
223 for k, v in kwargs.items()
224 if (k not in _llvm_repo_attrs.keys()) or (k in _common_attrs.keys())
225 }
226 toolchain(name = name, **toolchain_args)