Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 1 | Rules |
| 2 | ===== |
| 3 | |
Laurent Le Brun | c18dadc | 2015-03-31 19:38:30 +0000 | [diff] [blame] | 4 | **Status: Experimental**. Expect some breaking changes in the API. |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 5 | |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 6 | Rule creation |
| 7 | ------------- |
| 8 | |
| 9 | In a Skylark extension, use the `rule` function to create a new rule and store |
| 10 | it in a global variable. [See example](cookbook.md#empty). |
| 11 | |
| 12 | Attributes |
| 13 | ---------- |
| 14 | |
Laurent Le Brun | 9ba067d | 2015-05-22 13:55:23 +0000 | [diff] [blame] | 15 | An attribute is a rule argument, such as `srcs` or `deps`. You must list |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 16 | the attributes and their type when you define a rule. |
| 17 | |
| 18 | ```python |
| 19 | sum = rule( |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 20 | implementation=impl, |
| 21 | attrs = { |
| 22 | "number": attr.int(default = 1), |
| 23 | "deps": attr.label_list(), |
| 24 | }, |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 25 | ) |
| 26 | ``` |
| 27 | |
| 28 | If an attribute starts with `_`, it is private and users cannot set it. It |
| 29 | is useful in particular for label attributes (your rule will have an |
| 30 | implicit dependency on this label). |
| 31 | |
Laurent Le Brun | 8d4ffc4 | 2015-06-24 15:21:50 +0000 | [diff] [blame] | 32 | The following attributes are implicitly added to every rule: `deprecation`, |
| 33 | `features`, `name`, `tags`, `testonly`, `visibility`. Test rules also have the |
| 34 | following attributes: `args`, `flaky`, `local`, `shard_count`, `size`, `timeout`. |
Laurent Le Brun | 6d450dc | 2015-05-06 17:18:17 +0000 | [diff] [blame] | 35 | |
| 36 | To access an attribute, use `ctx.attr.<attribute_name>`. The name and the |
| 37 | package of a rule are available with `ctx.label.name` and `ctx.label.package`. |
| 38 | |
Laurent Le Brun | d7bd77a | 2015-03-13 19:01:03 +0000 | [diff] [blame] | 39 | [See example.](cookbook.md#attr) |
| 40 | |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 41 | The rule implementation function |
| 42 | -------------------------------- |
| 43 | |
| 44 | Every rule has to have an implementation function. This contains the actual |
| 45 | logic of the rule and is executed strictly in the Analysis Phase. The function |
| 46 | has exactly one input parameter, `ctx` and it may return |
| 47 | the [runfiles](#runfiles) and [providers](#providers) |
| 48 | of the rule. The input parameter `ctx` can be used to access attribute values, |
| 49 | outputs and dependent targets and files. It also has some helper functions. |
David Chen | 24f2d99 | 2015-08-17 17:25:46 +0000 | [diff] [blame] | 50 | See [the library](lib/ctx.html) for more context. Example: |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 51 | |
| 52 | ```python |
| 53 | def impl(ctx): |
| 54 | ... |
| 55 | return struct( |
| 56 | runfiles = ..., |
| 57 | my_provider = ..., |
| 58 | ... |
| 59 | ) |
| 60 | |
| 61 | my_rule = rule( |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 62 | implementation=impl, |
| 63 | ... |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 64 | ) |
| 65 | ``` |
| 66 | |
| 67 | Files |
| 68 | ----- |
| 69 | |
| 70 | There are two kinds of files: files stored in the file system and generated |
| 71 | files. For each generated file, there must be one and only one generating |
| 72 | action, and each action must generate one ore more output files. Otherwise |
| 73 | Bazel will throw an error. |
| 74 | |
| 75 | Targets |
| 76 | ------- |
| 77 | |
| 78 | Every build rule corresponds to exactly one target. A target can create |
| 79 | [actions](#actions), can have dependencies (which can be files or |
Laszlo Csomor | 7fad36a | 2015-03-25 17:05:04 +0000 | [diff] [blame] | 80 | other build rules), [output files](#output-files) (generated by |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 81 | its actions) and [providers](#providers). |
| 82 | |
| 83 | A target `y` is depending on target `x` if `y` has a label or label list type |
| 84 | attribute where `x` is declared: |
| 85 | |
| 86 | ```python |
| 87 | my_rule( |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 88 | name = "x", |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 89 | ) |
| 90 | |
| 91 | my_rule( |
| 92 | name = "y", |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 93 | deps = [":x"], |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 94 | ) |
| 95 | ``` |
| 96 | |
| 97 | In the above case it's possible to access targets declared in `my_rule.deps`: |
| 98 | |
| 99 | ```python |
| 100 | def impl(ctx): |
Laurent Le Brun | b732062 | 2015-05-20 11:38:56 +0000 | [diff] [blame] | 101 | for dep in ctx.attr.deps: |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 102 | # Do something with dep |
| 103 | ... |
| 104 | |
| 105 | my_rule = rule( |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 106 | implementation=impl, |
| 107 | attrs = { |
| 108 | "deps": attr.label_list(), |
| 109 | }, |
| 110 | ... |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 111 | ) |
| 112 | ``` |
| 113 | |
David Chen | 3f16b56 | 2015-07-23 15:04:50 +0000 | [diff] [blame] | 114 | <a name="output-files"></a> |
| 115 | Output files |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 116 | ------------ |
| 117 | |
| 118 | A target can declare output files, which must be generated by the target's |
| 119 | actions. There are three ways to create output files in Skylark: |
| 120 | |
| 121 | * If the rule is marked `executable`, it creates an output file of the same name |
| 122 | as the rule's. [See example](cookbook.md#outputs-executable) |
| 123 | |
| 124 | * The rule can declare default `outputs`, which are always generated. |
| 125 | [See example](cookbook.md#outputs-default) |
| 126 | |
| 127 | * The rule can have output or output list type attributes. In that case the |
| 128 | output files come from the actual attribute values. |
| 129 | [See example](cookbook.md#outputs-custom) |
| 130 | |
| 131 | All output files must have exactly one generating action. See the |
David Chen | 24f2d99 | 2015-08-17 17:25:46 +0000 | [diff] [blame] | 132 | [library](lib/ctx.html#outputs) for more context. |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 133 | |
Laurent Le Brun | c7dd1b1 | 2015-06-15 13:53:34 +0000 | [diff] [blame] | 134 | Default outputs |
| 135 | --------------- |
| 136 | |
| 137 | Every rule has a set of default outputs. This is used: |
| 138 | |
| 139 | * When the user runs `bazel build` on your target. Bazel will build the default |
| 140 | outputs of the rule. |
| 141 | |
| 142 | * When the target is used as a dependency to another rule. A rule can access |
David Chen | 24f2d99 | 2015-08-17 17:25:46 +0000 | [diff] [blame] | 143 | the default outputs by using [target.files](lib/Target.html#files). |
Laurent Le Brun | c7dd1b1 | 2015-06-15 13:53:34 +0000 | [diff] [blame] | 144 | This is the case for example if you use a rule in the `srcs` attribute of a |
| 145 | `genrule`. |
| 146 | |
| 147 | To decide what goes in the default outputs of a rule, use the `files` provider. |
| 148 | If unspecified, it will contain all the declared outputs. |
| 149 | |
| 150 | ```python |
| 151 | def _impl(ctx): |
| 152 | # ... |
| 153 | return struct(files = set([file1, file2])) |
| 154 | ``` |
| 155 | |
| 156 | This can be useful for exposing files generated with |
David Chen | 24f2d99 | 2015-08-17 17:25:46 +0000 | [diff] [blame] | 157 | [ctx.new_file](lib/ctx.html#new_file). You can also have "implicit |
Laurent Le Brun | c7dd1b1 | 2015-06-15 13:53:34 +0000 | [diff] [blame] | 158 | outputs", i.e. files that are declared in the rule, but not in the default |
| 159 | outputs (like `_deploy.jar` in `java_binary`). |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 160 | |
| 161 | Actions |
| 162 | ------- |
| 163 | |
| 164 | There are three ways to create actions: |
| 165 | |
| 166 | * `ctx.action` |
| 167 | * `ctx.file_action` |
| 168 | * `ctx.template_action` |
| 169 | |
| 170 | Actions take a set (can be empty) of input files and generate a (non-empty) |
| 171 | set of output files. |
| 172 | The set of input and output files must be known during the analysis phase. It |
| 173 | might depend on the value of attributes and information from dependencies, but |
| 174 | it cannot depend on the result of the execution. For example, if your action |
Googler | 5ae8daf | 2015-05-11 14:27:03 +0000 | [diff] [blame] | 175 | runs the unzip command, you must specify which files you expect to be inflated |
| 176 | (before running unzip). |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 177 | |
| 178 | Actions are comparable to pure functions: They should depend only on the |
| 179 | provided inputs, and avoid accessing computer information, username, clock, |
| 180 | network or I/O devices (except for reading inputs and writing outputs). |
| 181 | |
| 182 | **If a command generates a file that is not listed in the outputs**: It is fine. |
| 183 | The file will be ignored and cannot be used by other rules. |
| 184 | |
| 185 | **If a command does not generate a file that is listed in the outputs**: It is an |
| 186 | execution error and the build will fail. This happens for instance when a |
| 187 | compilation fails. |
| 188 | |
| 189 | **If a command generates an unknown number of outputs and you want to keep them |
| 190 | all**, you may group them in a zip file. This way, you will be able to declare |
| 191 | your output. |
| 192 | |
| 193 | **If a command does not list a file it uses as an input**, the action execution |
| 194 | will most likely result in an error. The file is not guaranteed to be available |
| 195 | to the action, so if it **is** there, it's due to a coincidence or error. |
| 196 | |
| 197 | **If a command lists a file as an input, but does not use it**: It is fine. However |
| 198 | it can affect the action execution order resulting in sub-optimal performance. |
| 199 | |
| 200 | Dependencies are resolved by Bazel, which will decide which actions are |
| 201 | executed. It is an error if there is a cycle in the dependency graph. Creating |
| 202 | an action does not guarantee that it will be executed: It depends on whether |
| 203 | its outputs are needed for the build. |
| 204 | |
Laurent Le Brun | fd4615a | 2015-06-26 14:18:11 +0000 | [diff] [blame] | 205 | Configurations |
| 206 | -------------- |
| 207 | |
| 208 | By default, a target is built in the target configuration. For each label |
| 209 | attribute, you can decide whether the dependency should be built in the same |
| 210 | configuration, or in the host configuration. |
| 211 | |
| 212 | In general, sources, dependent libraries and executables that will be needed at |
| 213 | runtime can use the same configuration. |
| 214 | |
| 215 | Tools that are executed as part of the build (e.g. compilers, code generators) |
| 216 | should be built for the host configuration. In this case, specify `cfg=HOST_CFG` |
| 217 | in the attribute. |
| 218 | |
| 219 | `DATA_CFG` is present for legacy reasons and should be used for the `data` |
| 220 | attributes. |
| 221 | |
Florian Weikert | c6fd0b6 | 2015-08-24 13:06:31 +0000 | [diff] [blame] | 222 | <a name="fragments"></a> |
| 223 | Configuration Fragments |
| 224 | -------------- |
| 225 | |
| 226 | Rules may access configuration fragments such as `cpp`, `java` and `jvm`. |
| 227 | However, all required fragments have to be declared in order to avoid access |
| 228 | errors: |
| 229 | |
| 230 | ```python |
| 231 | def impl(ctx): |
| 232 | # Using ctx.fragments.cpp would lead to an error since it was not declared. |
| 233 | x = ctx.fragments.java |
| 234 | ... |
| 235 | |
| 236 | my_rule = rule( |
| 237 | implementation=impl, |
Florian Weikert | 3f8aac9 | 2015-09-07 12:06:02 +0000 | [diff] [blame] | 238 | fragments = ["java"], #Required fragments of the target configuration |
| 239 | host_fragments = ["java"], #Required fragments of the host configuration |
Florian Weikert | c6fd0b6 | 2015-08-24 13:06:31 +0000 | [diff] [blame] | 240 | ... |
| 241 | ) |
| 242 | ``` |
| 243 | |
Florian Weikert | 3f8aac9 | 2015-09-07 12:06:02 +0000 | [diff] [blame] | 244 | `ctx.fragments` only provides configuration fragments for the target |
| 245 | configuration. If you want to access fragments for the host configuration, |
| 246 | please use `ctx.host_fragments` instead. |
| 247 | |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 248 | Providers |
| 249 | --------- |
| 250 | |
| 251 | Providers are used to access information from another rule. A rule depending on |
| 252 | another rule has access to the data the latter provides. These data can be e.g. |
| 253 | output files, the libraries the dependent rule is using to link or compile, or |
| 254 | anything the depending rule should know about. Using providers is the only way |
| 255 | to exchange data between rules. |
| 256 | |
| 257 | A rule can only access data provided by its direct dependencies, not that of |
| 258 | transitive dependencies: if rule `top` depends on `middle` and `middle` depends |
| 259 | on `bottom`, then `middle` is a direct dependency of `top` and `bottom` is a |
| 260 | transitive dependency of `top`. In this scenario `top` can only access data |
| 261 | provided by `middle`. If `middle` also provides the data that `bottom` provided |
| 262 | to it then and only then can `top` access it. |
| 263 | |
| 264 | Only the following data types are allowed to pass using providers: |
| 265 | |
Han-Wen Nienhuys | 0bacd7c | 2015-03-06 15:46:58 +0000 | [diff] [blame] | 266 | * `bool` |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 267 | * `integer` |
| 268 | * `string` |
| 269 | * `file` |
| 270 | * `label` |
| 271 | * `None` |
| 272 | * anything composed of these types and `lists`, `dicts`, `sets` or `structs` |
| 273 | |
| 274 | Providers are created from the return value of the rule implementation function: |
| 275 | |
| 276 | ```python |
| 277 | def dependent_rule_implementation(ctx): |
| 278 | ... |
| 279 | return struct( |
| 280 | transitive_data = set(["a", "b", "c"]) |
| 281 | ) |
| 282 | ``` |
| 283 | |
| 284 | A depending rule might access these data as struct fields of the depending |
| 285 | `target`: |
| 286 | |
| 287 | ```python |
| 288 | def depending_rule_implementation(ctx): |
| 289 | ... |
| 290 | s = set() |
Laurent Le Brun | b732062 | 2015-05-20 11:38:56 +0000 | [diff] [blame] | 291 | for dep_target in ctx.attr.deps: |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 292 | s += dep_target.transitive_data |
| 293 | ... |
| 294 | ``` |
| 295 | |
| 296 | Providers are only available during the analysis phase. Examples of usage: |
| 297 | |
| 298 | * [mandatory providers](cookbook.md#mandatory-providers) |
| 299 | * [optional providers](cookbook.md#optional-providers) |
| 300 | |
| 301 | Runfiles |
| 302 | --------- |
| 303 | |
| 304 | Runfiles are a set of files used by the (often executable) output of a rule |
| 305 | during runtime (as opposed to build time, i.e. when the binary itself is |
| 306 | generated). |
| 307 | Bazel creates a directory tree containing symlinks pointing to the |
| 308 | runfiles during execution, to stage this environment for the binary which can |
| 309 | thus access them during runtime. |
| 310 | |
| 311 | Runfiles can be added manually during rule creation and/or collected |
| 312 | transitively from dependent rules: |
| 313 | |
| 314 | ```python |
| 315 | def rule_implementation(ctx): |
| 316 | ... |
| 317 | transitive_runfiles = set() |
Laurent Le Brun | b732062 | 2015-05-20 11:38:56 +0000 | [diff] [blame] | 318 | for dep in ctx.attr.special_dependencies: |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 319 | transitive_runfiles += dep.transitive_runtime_files |
| 320 | |
| 321 | runfiles = ctx.runfiles( |
| 322 | # Add some files manually. |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 323 | files = [ctx.file.some_data_file], |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 324 | # Add transitive files from dependencies manually. |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 325 | transitive_files = transitive_runfiles, |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 326 | # Collect runfiles from the common locations: transitively from srcs, |
| 327 | # deps and data attributes. |
Googler | 6976e6c | 2015-07-27 17:25:00 +0000 | [diff] [blame] | 328 | collect_default = True, |
Laszlo Csomor | 39fc88c | 2015-03-02 16:22:29 +0000 | [diff] [blame] | 329 | ) |
| 330 | # Add a field named "runfiles" to the return struct in order to actually |
| 331 | # create the symlink tree. |
| 332 | return struct(runfiles = runfiles) |
| 333 | ``` |
| 334 | |
| 335 | Note that non-executable rule outputs can also have runfiles. For example, a |
| 336 | library might need some external files during runtime, and every depending |
| 337 | binary should know about it. |
| 338 | |
| 339 | Also note that if an action uses an executable, the executable's runfiles can |
| 340 | be used when the action executes. |
Laurent Le Brun | 1fb10af | 2015-06-26 14:06:16 +0000 | [diff] [blame] | 341 | |
| 342 | Executable rules |
| 343 | ---------------- |
| 344 | |
| 345 | To make a rule executable, set `executable=True` in the |
David Chen | 24f2d99 | 2015-08-17 17:25:46 +0000 | [diff] [blame] | 346 | [rule function](lib/Globals.html#rule). During the analysis |
Laurent Le Brun | 1fb10af | 2015-06-26 14:06:16 +0000 | [diff] [blame] | 347 | phase, the rule must generate the output file `ctx.outputs.executable`. |
| 348 | [See example](cookbook.md#outputs-executable) |
| 349 | |
| 350 | When the rule is executable, users can run it using `bazel run`. |
| 351 | |
| 352 | Test rules |
| 353 | ---------- |
| 354 | |
| 355 | To create a test rule, set `test=True` in the |
David Chen | 24f2d99 | 2015-08-17 17:25:46 +0000 | [diff] [blame] | 356 | [rule function](lib/Globals.html#rule). The name of the rule must |
Laurent Le Brun | 1fb10af | 2015-06-26 14:06:16 +0000 | [diff] [blame] | 357 | also end with `_test`. Test rules are implicitly executable, which means they |
| 358 | must generate the output file `ctx.outputs.executable`. |
| 359 | |
| 360 | Test rules inherit the following attributes: `args`, `flaky`, `local`, |
| 361 | `shard_count`, `size`, `timeout`. |
| 362 | |
| 363 | Test rules are run using `bazel test`. |