cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 1 | // Copyright 2018 The Bazel Authors. All rights reserved. |
| 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 | package com.google.devtools.build.lib.skylarkbuildapi; |
| 16 | |
| 17 | import com.google.devtools.build.lib.cmdline.Label; |
| 18 | import com.google.devtools.build.lib.events.Location; |
juliexxia | 692d148 | 2018-11-29 09:24:44 -0800 | [diff] [blame] | 19 | import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi.BuildSettingApi; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 20 | import com.google.devtools.build.lib.skylarkinterface.Param; |
| 21 | import com.google.devtools.build.lib.skylarkinterface.ParamType; |
| 22 | import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; |
| 23 | import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor; |
| 24 | import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 25 | import com.google.devtools.build.lib.syntax.BaseFunction; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 26 | import com.google.devtools.build.lib.syntax.EvalException; |
| 27 | import com.google.devtools.build.lib.syntax.FuncallExpression; |
cparsons | 1832ed3 | 2018-11-13 14:15:32 -0800 | [diff] [blame] | 28 | import com.google.devtools.build.lib.syntax.Runtime.NoneType; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 29 | import com.google.devtools.build.lib.syntax.SkylarkDict; |
| 30 | import com.google.devtools.build.lib.syntax.SkylarkList; |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 31 | import com.google.devtools.build.lib.syntax.StarlarkFunction; |
laurentlb | 6659b4c | 2019-02-18 07:23:36 -0800 | [diff] [blame] | 32 | import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier; |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 33 | import com.google.devtools.build.lib.syntax.StarlarkThread; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 34 | |
| 35 | /** |
| 36 | * Interface for a global Skylark library containing rule-related helper and registration functions. |
| 37 | */ |
| 38 | @SkylarkGlobalLibrary |
| 39 | public interface SkylarkRuleFunctionsApi<FileApiT extends FileApi> { |
| 40 | |
brandjon | c54bb0b | 2018-09-10 10:21:26 -0700 | [diff] [blame] | 41 | static final String PROVIDES_DOC = |
| 42 | "A list of providers that the implementation function must return." |
| 43 | + "" |
| 44 | + "<p>It is an error if the implementation function omits any of the types of providers " |
| 45 | + "listed here from its return value. However, the implementation function may return " |
| 46 | + "additional providers not listed here." |
| 47 | + "" |
| 48 | + "<p>Each element of the list is an <code>*Info</code> object returned by " |
| 49 | + "<a href='globals.html#provider'><code>provider()</code></a>, except that a legacy " |
| 50 | + "provider is represented by its string name instead."; |
| 51 | |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 52 | @SkylarkCallable( |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 53 | name = "provider", |
| 54 | doc = |
| 55 | "Creates a declared provider 'constructor'. The return value of this " |
| 56 | + "function can be used to create \"struct-like\" values. Example:<br>" |
| 57 | + "<pre class=\"language-python\">data = provider()\n" |
| 58 | + "d = data(x = 2, y = 3)\n" |
| 59 | + "print(d.x + d.y) # prints 5</pre>", |
| 60 | parameters = { |
| 61 | @Param( |
| 62 | name = "doc", |
| 63 | type = String.class, |
| 64 | named = true, |
| 65 | defaultValue = "''", |
| 66 | doc = |
| 67 | "A description of the provider that can be extracted by documentation generating" |
| 68 | + " tools."), |
| 69 | @Param( |
| 70 | name = "fields", |
| 71 | doc = |
| 72 | "If specified, restricts the set of allowed fields. <br>Possible values are:<ul> " |
| 73 | + " <li> list of fields:<br> <pre" |
| 74 | + " class=\"language-python\">provider(fields = ['a', 'b'])</pre><p> <li>" |
| 75 | + " dictionary field name -> documentation:<br> <pre" |
| 76 | + " class=\"language-python\">provider(\n" |
| 77 | + " fields = { 'a' : 'Documentation for a', 'b' : 'Documentation for b'" |
| 78 | + " })</pre></ul>All fields are optional.", |
| 79 | allowedTypes = { |
| 80 | @ParamType(type = SkylarkList.class, generic1 = String.class), |
| 81 | @ParamType(type = SkylarkDict.class) |
| 82 | }, |
| 83 | noneable = true, |
| 84 | named = true, |
| 85 | positional = false, |
| 86 | defaultValue = "None") |
| 87 | }, |
nharmata | bbf6473 | 2019-08-02 09:16:57 -0700 | [diff] [blame] | 88 | useLocation = true) |
| 89 | public ProviderApi provider(String doc, Object fields, Location location) throws EvalException; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 90 | |
| 91 | @SkylarkCallable( |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 92 | name = "rule", |
| 93 | doc = |
| 94 | "Creates a new rule, which can be called from a BUILD file or a macro to create targets." |
| 95 | + "<p>Rules must be assigned to global variables in a .bzl file; the name of the " |
| 96 | + "global variable is the rule's name." |
| 97 | + "<p>Test rules are required to have a name ending in <code>_test</code>, while all " |
| 98 | + "other rules must not have this suffix. (This restriction applies only to rules, " |
| 99 | + "not to their targets.)", |
| 100 | parameters = { |
| 101 | @Param( |
| 102 | name = "implementation", |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 103 | type = StarlarkFunction.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 104 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 105 | doc = |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 106 | "the Starlark function implementing this rule, must have exactly one parameter: " |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 107 | + "<a href=\"ctx.html\">ctx</a>. The function is called during the analysis " |
| 108 | + "phase for each instance of the rule. It can access the attributes " |
| 109 | + "provided by the user. It must create actions to generate all the declared " |
| 110 | + "outputs."), |
| 111 | @Param( |
| 112 | name = "test", |
| 113 | type = Boolean.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 114 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 115 | defaultValue = "False", |
| 116 | doc = |
| 117 | "Whether this rule is a test rule, that is, whether it may be the subject of a " |
| 118 | + "<code>blaze test</code> command. All test rules are automatically " |
| 119 | + "considered <a href='#rule.executable'>executable</a>; it is unnecessary " |
| 120 | + "(and discouraged) to explicitly set <code>executable = True</code> for a " |
| 121 | + "test rule. See the " |
| 122 | + "<a href='../rules.$DOC_EXT#executable-rules-and-test-rules'>Rules page</a> " |
| 123 | + "for more information."), |
| 124 | @Param( |
| 125 | name = "attrs", |
| 126 | type = SkylarkDict.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 127 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 128 | noneable = true, |
| 129 | defaultValue = "None", |
| 130 | doc = |
| 131 | "dictionary to declare all the attributes of the rule. It maps from an attribute " |
| 132 | + "name to an attribute object (see <a href=\"attr.html\">attr</a> module). " |
| 133 | + "Attributes starting with <code>_</code> are private, and can be used to " |
| 134 | + "add an implicit dependency on a label. The attribute <code>name</code> is " |
| 135 | + "implicitly added and must not be specified. Attributes " |
| 136 | + "<code>visibility</code>, <code>deprecation</code>, <code>tags</code>, " |
| 137 | + "<code>testonly</code>, and <code>features</code> are implicitly added and " |
| 138 | + "cannot be overridden."), |
| 139 | // TODO(bazel-team): need to give the types of these builtin attributes |
| 140 | @Param( |
| 141 | name = "outputs", |
cparsons | 1832ed3 | 2018-11-13 14:15:32 -0800 | [diff] [blame] | 142 | allowedTypes = { |
| 143 | @ParamType(type = SkylarkDict.class), |
| 144 | @ParamType(type = NoneType.class), |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 145 | @ParamType(type = StarlarkFunction.class) // a function defined in Starlark |
cparsons | 1832ed3 | 2018-11-13 14:15:32 -0800 | [diff] [blame] | 146 | }, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 147 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 148 | callbackEnabled = true, |
| 149 | noneable = true, |
| 150 | defaultValue = "None", |
cparsons | 36c70a6 | 2019-06-07 09:31:14 -0700 | [diff] [blame] | 151 | valueWhenDisabled = "None", |
| 152 | disableWithFlag = FlagIdentifier.INCOMPATIBLE_NO_RULE_OUTPUTS_PARAM, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 153 | doc = |
Googler | e29ddda | 2019-09-04 17:09:29 -0700 | [diff] [blame] | 154 | "This parameter has been deprecated. Migrate rules to use" |
| 155 | + " <code>OutputGroupInfo</code> or <code>attr.output</code> instead. <p>A" |
| 156 | + " schema for defining predeclared outputs. Unlike <a" |
| 157 | + " href='attr.html#output'><code>output</code></a> and <a" |
| 158 | + " href='attr.html#output_list'><code>output_list</code></a> attributes, the" |
| 159 | + " user does not specify the labels for these files. See the <a" |
| 160 | + " href='../rules.$DOC_EXT#files'>Rules page</a> for more on predeclared" |
| 161 | + " outputs.<p>The value of this argument is either a dictionary or a callback" |
| 162 | + " function that produces a dictionary. The callback works similar to" |
| 163 | + " computed dependency attributes: The function's parameter names are matched" |
| 164 | + " against the rule's attributes, so for example if you pass <code>outputs =" |
| 165 | + " _my_func</code> with the definition <code>def _my_func(srcs, deps):" |
| 166 | + " ...</code>, the function has access to the attributes <code>srcs</code>" |
| 167 | + " and <code>deps</code>. Whether the dictionary is specified directly or via" |
| 168 | + " a function, it is interpreted as follows.<p>Each entry in the dictionary" |
| 169 | + " creates a predeclared output where the key is an identifier and the value" |
| 170 | + " is a string template that determines the output's label. In the rule's" |
| 171 | + " implementation function, the identifier becomes the field name used to" |
| 172 | + " access the output's <a href='File.html'><code>File</code></a> in <a" |
| 173 | + " href='ctx.html#outputs'><code>ctx.outputs</code></a>. The output's label" |
| 174 | + " has the same package as the rule, and the part after the package is" |
| 175 | + " produced by substituting each placeholder of the form" |
| 176 | + " <code>\"%{ATTR}\"</code> with a string formed from the value of the" |
| 177 | + " attribute <code>ATTR</code>:<ul><li>String-typed attributes are" |
| 178 | + " substituted verbatim.<li>Label-typed attributes become the part of the" |
| 179 | + " label after the package, minus the file extension. For example, the label" |
| 180 | + " <code>\"//pkg:a/b.c\"</code> becomes <code>\"a/b\"</code>.<li>Output-typed" |
| 181 | + " attributes become the part of the label after the package, including the" |
| 182 | + " file extension (for the above example, <code>\"a/b.c\"</code>).<li>All" |
| 183 | + " list-typed attributes (for example, <code>attr.label_list</code>) used in" |
| 184 | + " placeholders are required to have <i>exactly one element</i>. Their" |
| 185 | + " conversion is the same as their non-list version" |
| 186 | + " (<code>attr.label</code>).<li>Other attribute types may not appear in" |
| 187 | + " placeholders.<li>The special non-attribute placeholders" |
| 188 | + " <code>%{dirname}</code> and <code>%{basename}</code> expand to those parts" |
| 189 | + " of the rule's label, excluding its package. For example, in" |
| 190 | + " <code>\"//pkg:a/b.c\"</code>, the dirname is <code>a</code> and the" |
| 191 | + " basename is <code>b.c</code>.</ul><p>In practice, the most common" |
| 192 | + " substitution placeholder is <code>\"%{name}\"</code>. For example, for a" |
| 193 | + " target named \"foo\", the outputs dict <code>{\"bin\":" |
| 194 | + " \"%{name}.exe\"}</code> predeclares an output named <code>foo.exe</code>" |
| 195 | + " that is accessible in the implementation function as" |
| 196 | + " <code>ctx.outputs.bin</code>."), |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 197 | @Param( |
| 198 | name = "executable", |
| 199 | type = Boolean.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 200 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 201 | defaultValue = "False", |
| 202 | doc = |
| 203 | "Whether this rule is considered executable, that is, whether it may be the " |
| 204 | + "subject of a <code>blaze run</code> command. See the " |
| 205 | + "<a href='../rules.$DOC_EXT#executable-rules-and-test-rules'>Rules page</a> " |
| 206 | + "for more information."), |
| 207 | @Param( |
| 208 | name = "output_to_genfiles", |
| 209 | type = Boolean.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 210 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 211 | defaultValue = "False", |
| 212 | doc = |
| 213 | "If true, the files will be generated in the genfiles directory instead of the " |
| 214 | + "bin directory. Unless you need it for compatibility with existing rules " |
| 215 | + "(e.g. when generating header files for C++), do not set this flag."), |
| 216 | @Param( |
| 217 | name = "fragments", |
| 218 | type = SkylarkList.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 219 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 220 | generic1 = String.class, |
| 221 | defaultValue = "[]", |
| 222 | doc = |
| 223 | "List of names of configuration fragments that the rule requires " |
| 224 | + "in target configuration."), |
| 225 | @Param( |
| 226 | name = "host_fragments", |
| 227 | type = SkylarkList.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 228 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 229 | generic1 = String.class, |
| 230 | defaultValue = "[]", |
| 231 | doc = |
| 232 | "List of names of configuration fragments that the rule requires " |
| 233 | + "in host configuration."), |
| 234 | @Param( |
| 235 | name = "_skylark_testable", |
| 236 | type = Boolean.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 237 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 238 | defaultValue = "False", |
| 239 | doc = |
| 240 | "<i>(Experimental)</i><br/><br/>" |
| 241 | + "If true, this rule will expose its actions for inspection by rules that " |
| 242 | + "depend on it via an <a href=\"globals.html#Actions\">Actions</a> " |
| 243 | + "provider. The provider is also available to the rule itself by calling " |
| 244 | + "<a href=\"ctx.html#created_actions\">ctx.created_actions()</a>." |
| 245 | + "<br/><br/>" |
| 246 | + "This should only be used for testing the analysis-time behavior of " |
laurentlb | 7dcad73 | 2018-10-25 05:17:20 -0700 | [diff] [blame] | 247 | + "Starlark rules. This flag may be removed in the future."), |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 248 | @Param( |
| 249 | name = "toolchains", |
| 250 | type = SkylarkList.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 251 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 252 | generic1 = String.class, |
| 253 | defaultValue = "[]", |
| 254 | doc = |
| 255 | "<i>(Experimental)</i><br/><br/>" |
| 256 | + "If set, the set of toolchains this rule requires. Toolchains will be " |
| 257 | + "found by checking the current platform, and provided to the rule " |
| 258 | + "implementation via <code>ctx.toolchain</code>."), |
| 259 | @Param( |
| 260 | name = "doc", |
| 261 | type = String.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 262 | named = true, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 263 | defaultValue = "''", |
| 264 | doc = |
| 265 | "A description of the rule that can be extracted by documentation generating " |
| 266 | + "tools."), |
| 267 | @Param( |
| 268 | name = "provides", |
| 269 | type = SkylarkList.class, |
| 270 | named = true, |
| 271 | positional = false, |
| 272 | defaultValue = "[]", |
| 273 | doc = PROVIDES_DOC), |
| 274 | @Param( |
| 275 | name = "execution_platform_constraints_allowed", |
| 276 | type = Boolean.class, |
| 277 | named = true, |
| 278 | positional = false, |
John Cater | 35dd05a | 2019-05-24 03:14:01 -0700 | [diff] [blame] | 279 | defaultValue = "True", |
John Cater | 5688793 | 2019-04-26 05:27:07 -0700 | [diff] [blame] | 280 | disableWithFlag = |
| 281 | FlagIdentifier.INCOMPATIBLE_DISALLOW_RULE_EXECUTION_PLATFORM_CONSTRAINTS_ALLOWED, |
| 282 | valueWhenDisabled = "True", |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 283 | doc = |
| 284 | "If true, a special attribute named <code>exec_compatible_with</code> of " |
| 285 | + "label-list type is added, which must not already exist in " |
| 286 | + "<code>attrs</code>. Targets may use this attribute to specify additional " |
| 287 | + "constraints on the execution platform beyond those given in the " |
John Cater | 5688793 | 2019-04-26 05:27:07 -0700 | [diff] [blame] | 288 | + "<code>exec_compatible_with</code> argument to <code>rule()</code>. " |
| 289 | + "This will be deprecated and removed in the near future, and all rules will " |
| 290 | + "be able to use <code>exec_compatible_with</code>."), |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 291 | @Param( |
| 292 | name = "exec_compatible_with", |
| 293 | type = SkylarkList.class, |
| 294 | generic1 = String.class, |
| 295 | named = true, |
| 296 | positional = false, |
| 297 | defaultValue = "[]", |
| 298 | doc = |
| 299 | "A list of constraints on the execution platform that apply to all targets of " |
| 300 | + "this rule type."), |
| 301 | @Param( |
| 302 | name = "analysis_test", |
| 303 | allowedTypes = { |
| 304 | @ParamType(type = Boolean.class), |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 305 | }, |
| 306 | named = true, |
| 307 | positional = false, |
cparsons | ed2e469 | 2019-10-23 07:33:58 -0700 | [diff] [blame] | 308 | defaultValue = "False", |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 309 | doc = |
cparsons | ed2e469 | 2019-10-23 07:33:58 -0700 | [diff] [blame] | 310 | "If true, then this rule is treated as an analysis test. <p>Note: Analysis test" |
| 311 | + " rules are primarily defined using infrastructure provided in core Starlark" |
| 312 | + " libraries. See <a href=\"../testing.html#for-testing-rules\">Testing</a>" |
| 313 | + " for guidance. <p>If a rule is defined as an analysis test rule, it becomes" |
| 314 | + " allowed to use configuration transitions defined using <a" |
| 315 | + " href=\"#analysis_test_transition\">analysis_test_transition</a> on its" |
| 316 | + " attributes, but opts into some restrictions: <ul><li>Targets of this rule" |
| 317 | + " are limited in the number of transitive dependencies they may have." |
| 318 | + " <li>The rule is considered a test rule (as if <code>test=True</code> were" |
cparsons | eddc9bc | 2019-10-23 10:24:20 -0700 | [diff] [blame^] | 319 | + " set). This supercedes the value of <code>test</code></li> <li>The rule" |
| 320 | + " implementation function may not register actions." |
| 321 | + " Instead, it must register a pass/fail result via providing <a" |
cparsons | ed2e469 | 2019-10-23 07:33:58 -0700 | [diff] [blame] | 322 | + " href='AnalysisTestResultInfo.html'>AnalysisTestResultInfo</a>.</li></ul>"), |
juliexxia | 1f332e0 | 2018-10-31 14:20:55 -0700 | [diff] [blame] | 323 | @Param( |
| 324 | name = "build_setting", |
| 325 | type = BuildSettingApi.class, |
| 326 | noneable = true, |
| 327 | defaultValue = "None", |
| 328 | named = true, |
| 329 | positional = false, |
juliexxia | 671f647 | 2019-01-10 06:56:20 -0800 | [diff] [blame] | 330 | enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_BUILD_SETTING_API, |
| 331 | valueWhenDisabled = "None", |
juliexxia | 1f332e0 | 2018-10-31 14:20:55 -0700 | [diff] [blame] | 332 | doc = |
juliexxia | 4cf4555 | 2019-05-29 15:16:23 -0700 | [diff] [blame] | 333 | "If set, describes what kind of " |
| 334 | + "<a href = '../config.$DOC_EXT#user-defined-build-settings'><code>build " |
| 335 | + "setting</code></a> this rule is. See the " |
| 336 | + "<a href='config.html'><code>config</code></a> module. If this is " |
cparsons | ed2e469 | 2019-10-23 07:33:58 -0700 | [diff] [blame] | 337 | + "set, a mandatory attribute named \"build_setting_default\" is automatically " |
juliexxia | 1f332e0 | 2018-10-31 14:20:55 -0700 | [diff] [blame] | 338 | + "added to this rule, with a type corresponding to the value passed in here."), |
juliexxia | deb028e | 2019-01-05 17:19:21 -0800 | [diff] [blame] | 339 | @Param( |
| 340 | name = "cfg", |
| 341 | type = Object.class, |
| 342 | noneable = true, |
| 343 | defaultValue = "None", |
| 344 | named = true, |
| 345 | positional = false, |
juliexxia | deb028e | 2019-01-05 17:19:21 -0800 | [diff] [blame] | 346 | doc = |
| 347 | "If set, points to the configuration transition the rule will " |
| 348 | + "apply to its own configuration before analysis.") |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 349 | }, |
| 350 | useAst = true, |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 351 | useStarlarkThread = true) |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 352 | public BaseFunction rule( |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 353 | StarlarkFunction implementation, |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 354 | Boolean test, |
| 355 | Object attrs, |
| 356 | Object implicitOutputs, |
| 357 | Boolean executable, |
| 358 | Boolean outputToGenfiles, |
| 359 | SkylarkList<?> fragments, |
| 360 | SkylarkList<?> hostFragments, |
| 361 | Boolean skylarkTestable, |
John Cater | 236fdeb | 2018-06-18 11:42:41 -0700 | [diff] [blame] | 362 | SkylarkList<?> toolchains, |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 363 | String doc, |
| 364 | SkylarkList<?> providesArg, |
John Cater | d79e977 | 2018-06-14 02:24:57 -0700 | [diff] [blame] | 365 | Boolean executionPlatformConstraintsAllowed, |
| 366 | SkylarkList<?> execCompatibleWith, |
cparsons | 55781c9 | 2018-10-17 12:03:08 -0700 | [diff] [blame] | 367 | Object analysisTest, |
juliexxia | 1f332e0 | 2018-10-31 14:20:55 -0700 | [diff] [blame] | 368 | Object buildSetting, |
juliexxia | deb028e | 2019-01-05 17:19:21 -0800 | [diff] [blame] | 369 | Object cfg, |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 370 | FuncallExpression ast, |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 371 | StarlarkThread thread) |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 372 | throws EvalException; |
| 373 | |
| 374 | @SkylarkCallable( |
| 375 | name = "aspect", |
| 376 | doc = |
| 377 | "Creates a new aspect. The result of this function must be stored in a global value. " |
| 378 | + "Please see the <a href=\"../aspects.md\">introduction to Aspects</a> for more " |
| 379 | + "details.", |
| 380 | parameters = { |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 381 | @Param( |
| 382 | name = "implementation", |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 383 | type = StarlarkFunction.class, |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 384 | named = true, |
| 385 | doc = |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 386 | "A Starlark function that implements this aspect, with exactly two parameters: " |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 387 | + "<a href=\"Target.html\">Target</a> (the target to which the aspect is " |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 388 | + "applied) and <a href=\"ctx.html\">ctx</a> (the rule context which the target" |
| 389 | + "is created from). Attributes of the target are available via the " |
| 390 | + "<code>ctx.rule</code> field. This function is evaluated during the " |
| 391 | + "analysis phase for each application of an aspect to a target."), |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 392 | @Param( |
| 393 | name = "attr_aspects", |
| 394 | type = SkylarkList.class, |
| 395 | named = true, |
| 396 | generic1 = String.class, |
| 397 | defaultValue = "[]", |
| 398 | doc = |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 399 | "List of attribute names. The aspect propagates along dependencies specified in " |
| 400 | + " the attributes of a target with these names. Common values here include " |
| 401 | + "<code>deps</code> and <code>exports</code>. The list can also contain a " |
| 402 | + "single string <code>\"*\"</code> to propagate along all dependencies of a " |
| 403 | + "target."), |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 404 | @Param( |
| 405 | name = "attrs", |
| 406 | type = SkylarkDict.class, |
| 407 | named = true, |
| 408 | noneable = true, |
| 409 | defaultValue = "None", |
| 410 | doc = |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 411 | "A dictionary declaring all the attributes of the aspect. It maps from an " |
| 412 | + "attribute name to an attribute object, like `attr.label` or `attr.string` " |
| 413 | + "(see <a href=\"attr.html\">attr</a> module). Aspect attributes are " |
cparsons | 59ea3ee | 2019-10-02 21:25:36 -0700 | [diff] [blame] | 414 | + "available to implementation function as fields of <code>ctx</code> " |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 415 | + "parameter. " |
| 416 | + "" |
| 417 | + "<p>Implicit attributes starting with <code>_</code> must have default " |
| 418 | + "values, and have type <code>label</code> or <code>label_list</code>. " |
| 419 | + "" |
| 420 | + "<p>Explicit attributes must have type <code>string</code>, and must use " |
| 421 | + "the <code>values</code> restriction. Explicit attributes restrict the " |
| 422 | + "aspect to only be used with rules that have attributes of the same " |
| 423 | + "name, type, and valid values according to the restriction."), |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 424 | @Param( |
| 425 | name = "required_aspect_providers", |
| 426 | type = SkylarkList.class, |
| 427 | named = true, |
| 428 | defaultValue = "[]", |
| 429 | doc = |
dslomov | 731a211 | 2019-09-03 09:46:27 -0700 | [diff] [blame] | 430 | "This attribute allows this aspect to inspect other aspects. The value must be a " |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 431 | + "list of providers, or a list of lists of providers. For example, " |
dslomov | 731a211 | 2019-09-03 09:46:27 -0700 | [diff] [blame] | 432 | + "<code>[FooInfo, BarInfo, [BazInfo, QuxInfo]]</code> is a " |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 433 | + "valid value." |
| 434 | + "" |
| 435 | + "<p>A single list of providers will automatically be converted to a list " |
| 436 | + "containing one list of providers. That is, " |
| 437 | + "<code>[FooInfo, BarInfo]</code> will automatically be converted to " |
| 438 | + "<code>[[FooInfo, BarInfo]]</code>. " |
| 439 | + "" |
| 440 | + "<p>To make another aspect (e.g. <code>other_aspect</code>) visible to this " |
| 441 | + "aspect, <code>other_aspect</code> must provide all providers from at least " |
| 442 | + "one of the lists. In the example of " |
| 443 | + "<code>[FooInfo, BarInfo, [BazInfo, QuxInfo]]</code>, this aspect can only " |
cparsons | 59ea3ee | 2019-10-02 21:25:36 -0700 | [diff] [blame] | 444 | + "see <code>other_aspect</code> if and only if <code>other_aspect</code> " |
Jingwen Chen | 3f119a7 | 2019-08-27 09:09:59 -0700 | [diff] [blame] | 445 | + "provides <code>FooInfo</code> *or* <code>BarInfo</code> *or* both " |
| 446 | + "<code>BazInfo</code> *and* <code>QuxInfo</code>."), |
cparsons | 2b27ec87 | 2019-04-18 10:26:58 -0700 | [diff] [blame] | 447 | @Param( |
| 448 | name = "provides", |
| 449 | type = SkylarkList.class, |
| 450 | named = true, |
| 451 | defaultValue = "[]", |
| 452 | doc = PROVIDES_DOC), |
| 453 | @Param( |
| 454 | name = "fragments", |
| 455 | type = SkylarkList.class, |
| 456 | named = true, |
| 457 | generic1 = String.class, |
| 458 | defaultValue = "[]", |
| 459 | doc = |
| 460 | "List of names of configuration fragments that the aspect requires " |
| 461 | + "in target configuration."), |
| 462 | @Param( |
| 463 | name = "host_fragments", |
| 464 | type = SkylarkList.class, |
| 465 | named = true, |
| 466 | generic1 = String.class, |
| 467 | defaultValue = "[]", |
| 468 | doc = |
| 469 | "List of names of configuration fragments that the aspect requires " |
| 470 | + "in host configuration."), |
| 471 | @Param( |
| 472 | name = "toolchains", |
| 473 | type = SkylarkList.class, |
| 474 | named = true, |
| 475 | generic1 = String.class, |
| 476 | defaultValue = "[]", |
| 477 | doc = |
| 478 | "<i>(Experimental)</i><br/><br/>" |
| 479 | + "If set, the set of toolchains this rule requires. Toolchains will be " |
| 480 | + "found by checking the current platform, and provided to the rule " |
| 481 | + "implementation via <code>ctx.toolchain</code>."), |
| 482 | @Param( |
| 483 | name = "doc", |
| 484 | type = String.class, |
| 485 | named = true, |
| 486 | defaultValue = "''", |
| 487 | doc = |
| 488 | "A description of the aspect that can be extracted by documentation generating " |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 489 | + "tools."), |
| 490 | @Param( |
| 491 | name = "apply_to_generating_rules", |
| 492 | type = Boolean.class, |
| 493 | named = true, |
| 494 | positional = false, |
| 495 | defaultValue = "False", |
| 496 | enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ASPECT_OUTPUT_PROPAGATION, |
| 497 | valueWhenDisabled = "False", |
| 498 | doc = |
| 499 | "If true, the aspect will, when applied to an output file, instead apply to the " |
| 500 | + "output file's generating rule. " |
| 501 | + "<p>For example, suppose an aspect propagates transitively through attribute " |
| 502 | + "`deps` and it is applied to target `alpha`. Suppose `alpha` has " |
| 503 | + "`deps = [':beta_output']`, where `beta_output` is a declared output of " |
| 504 | + "a target `beta`. Suppose `beta` has a target `charlie` as one of its " |
| 505 | + "`deps`. If `apply_to_generating_rules=True` for the aspect, then the aspect " |
| 506 | + "will propagate through `alpha`, `beta`, and `charlie`. If False, then the " |
| 507 | + "aspect will propagate only to `alpha`. </p><p>False by default.</p>") |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 508 | }, |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 509 | useStarlarkThread = true, |
Googler | 7fa0dd2 | 2019-09-24 20:07:53 -0700 | [diff] [blame] | 510 | useAst = true) |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 511 | public SkylarkAspectApi aspect( |
Googler | d78a091 | 2019-09-04 15:13:10 -0700 | [diff] [blame] | 512 | StarlarkFunction implementation, |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 513 | SkylarkList<?> attributeAspects, |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 514 | Object attrs, |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 515 | SkylarkList<?> requiredAspectProvidersArg, |
| 516 | SkylarkList<?> providesArg, |
| 517 | SkylarkList<?> fragments, |
| 518 | SkylarkList<?> hostFragments, |
John Cater | 236fdeb | 2018-06-18 11:42:41 -0700 | [diff] [blame] | 519 | SkylarkList<?> toolchains, |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 520 | String doc, |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 521 | Boolean applyToGeneratingRules, |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 522 | FuncallExpression ast, |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 523 | StarlarkThread thread) |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 524 | throws EvalException; |
| 525 | |
| 526 | @SkylarkCallable( |
| 527 | name = "Label", |
dannark | fbfd2c0 | 2019-01-14 20:51:39 -0800 | [diff] [blame] | 528 | doc = |
| 529 | "Creates a Label referring to a BUILD target. Use " |
| 530 | + "this function only when you want to give a default value for the label " |
| 531 | + "attributes. The argument must refer to an absolute label. " |
| 532 | + "Example: <br><pre class=language-python>Label(\"//tools:default\")</pre>", |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 533 | parameters = { |
dannark | fbfd2c0 | 2019-01-14 20:51:39 -0800 | [diff] [blame] | 534 | @Param( |
| 535 | name = "label_string", |
| 536 | type = String.class, |
| 537 | legacyNamed = true, |
| 538 | doc = "the label string."), |
| 539 | @Param( |
| 540 | name = "relative_to_caller_repository", |
| 541 | type = Boolean.class, |
| 542 | defaultValue = "False", |
| 543 | named = true, |
| 544 | positional = false, |
| 545 | doc = |
| 546 | "Deprecated. Do not use. " |
| 547 | + "When relative_to_caller_repository is True and the calling thread is a " |
| 548 | + "rule's implementation function, then a repo-relative label //foo:bar is " |
| 549 | + "resolved relative to the rule's repository. For calls to Label from any " |
| 550 | + "other thread, or calls in which the relative_to_caller_repository flag is " |
| 551 | + "False, a repo-relative label is resolved relative to the file in which the " |
| 552 | + "Label() call appears.") |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 553 | }, |
| 554 | useLocation = true, |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 555 | useStarlarkThread = true) |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 556 | @SkylarkConstructor(objectType = Label.class) |
| 557 | public Label label( |
Googler | a3421e2 | 2019-09-26 06:48:32 -0700 | [diff] [blame] | 558 | String labelString, Boolean relativeToCallerRepository, Location loc, StarlarkThread thread) |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 559 | throws EvalException; |
cparsons | 30d877a | 2018-05-07 05:58:01 -0700 | [diff] [blame] | 560 | } |