diff options
author | Alex Humesky <ahumesky@google.com> | 2016-01-15 15:52:31 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2016-01-15 22:28:50 +0000 |
commit | 8cc0541da1ec912568c8df2fc13a9b72b668cda2 (patch) | |
tree | c40ca184d5cdfafd0c010bf7d6c9638569379b83 /site | |
parent | 25217c0dc90f5f9ade9950d178db30b4ce41cbdd (diff) |
Update skylark docs for grammar and clarity.
--
MOS_MIGRATED_REVID=112248853
Diffstat (limited to 'site')
-rw-r--r-- | site/docs/skylark/rules.md | 104 |
1 files changed, 53 insertions, 51 deletions
diff --git a/site/docs/skylark/rules.md b/site/docs/skylark/rules.md index a45c231542..8004789c50 100644 --- a/site/docs/skylark/rules.md +++ b/site/docs/skylark/rules.md @@ -1,7 +1,7 @@ Rules ===== -**Status: Experimental**. We may do breaking changes in the API, but we will +**Status: Experimental**. We may make breaking changes to the API, but we will help you update your code. Rule creation @@ -11,12 +11,13 @@ In a Skylark extension, use the [rule](lib/globals.html#rule) function to create a new rule and store it in a global variable. [See example](cookbook.md#empty). -A custom rule will behave just like a native rule. It has a mandatory `name` -attribute, you can refer to it with a label and you can see it in `bazel query`. +A custom rule can be used just like a native rule. It has a mandatory `name` +attribute, you can refer to it with a label, and you can see it in +`bazel query`. The rule is analyzed when you explictly build it, or if it is a dependency of the build. In this case, Bazel will execute its `implementation` function. This -function decides what are the outputs of the rule and how to build them (using +function decides what the outputs of the rule are and how to build them (using `actions`). During analysis, no external command can be executed: actions will be run in the execution phase. @@ -24,7 +25,7 @@ Attributes ---------- An attribute is a rule argument, such as `srcs` or `deps`. You must list -the attributes and their type when you define a rule. +the attributes and their types when you define a rule. ```python sum = rule( @@ -54,10 +55,10 @@ Implementation function Every rule requires an `implementation` function. It contains the actual logic of the rule and is executed strictly in the Analysis Phase. The function -has exactly one input parameter, `ctx` and it may return +has exactly one input parameter, `ctx`, and it may return the [runfiles](#runfiles) and [providers](#providers) of the rule. The input parameter `ctx` can be used to access attribute values, -outputs and dependent targets and files. It also has some helper functions. +outputs and dependent targets, and files. It also has some helper functions. See [the library](lib/ctx.html) for more context. Example: ```python @@ -80,8 +81,8 @@ Files There are two kinds of files: files stored in the file system and generated files. For each generated file, there must be one and only one generating -action, and each action must generate one or more output files. Otherwise -Bazel will throw an error. +action, and each action must generate one or more output files. Bazel will throw +an error otherwise. Targets ------- @@ -89,9 +90,9 @@ Targets Every build rule corresponds to exactly one target. A target can create [actions](#actions), can have dependencies (which can be files or other build rules), [output files](#output-files) (generated by -its actions) and [providers](#providers). +its actions), and [providers](#providers). -A target `y` is depending on target `x` if `y` has a label or label list type +A target `y` depends on target `x` if `y` has a label or label list type attribute where `x` is declared: ```python @@ -105,7 +106,7 @@ my_rule( ) ``` -In the above case it's possible to access targets declared in `my_rule.deps`: +In the above case, it's possible to access targets declared in `my_rule.deps`: ```python def impl(ctx): @@ -150,13 +151,13 @@ Every rule has a set of default outputs. This is used: * When the user runs `bazel build` on your target. Bazel will build the default outputs of the rule. -* When the target is used as a dependency to another rule. A rule can access +* When the target is used as a dependency of another rule. A rule can access the default outputs by using [target.files](lib/Target.html#files). - This is the case for example if you use a rule in the `srcs` attribute of a + This is the case, for example, if you use a rule in the `srcs` attribute of a `genrule`. -To decide what goes in the default outputs of a rule, use the `files` provider. -If unspecified, it will contain all the declared outputs. +Use the `files` provider to specify the default outputs of a rule. +If left unspecified, it will contain all the declared outputs. ```python def _impl(ctx): @@ -166,7 +167,7 @@ def _impl(ctx): This can be useful for exposing files generated with [ctx.new_file](lib/ctx.html#new_file). You can also have "implicit -outputs", i.e. files that are declared in the rule, but not in the default +outputs", i.e., files that are declared in the rule, but not in the default outputs (like `_deploy.jar` in `java_binary`). Actions @@ -178,7 +179,7 @@ There are three ways to create actions: * [ctx.file_action](lib/ctx.html#file_action), to write a string to a file. * [ctx.template_action](lib/ctx.html#template_action), to generate a file from a template. -Actions take a set (can be empty) of input files and generate a (non-empty) +Actions take a set (which can be empty) of input files and generate a (non-empty) set of output files. The set of input and output files must be known during the analysis phase. It might depend on the value of attributes and information from dependencies, but @@ -188,25 +189,26 @@ runs the unzip command, you must specify which files you expect to be inflated Actions are comparable to pure functions: They should depend only on the provided inputs, and avoid accessing computer information, username, clock, -network or I/O devices (except for reading inputs and writing outputs). +network, or I/O devices (except for reading inputs and writing outputs). -**If a command generates a file that is not listed in the outputs**: It is fine. -The file will be ignored and cannot be used by other rules. +**If an action generates a file that is not listed in its outputs**: This is +fine, but the file will be ignored and cannot be used by other rules. -**If a command does not generate a file that is listed in the outputs**: It is an -execution error and the build will fail. This happens for instance when a +**If an action does not generate a file that is listed in its outputs**: This is +an execution error and the build will fail. This happens for instance when a compilation fails. -**If a command generates an unknown number of outputs and you want to keep them +**If an action generates an unknown number of outputs and you want to keep them all**, you may group them in a zip file. This way, you will be able to declare your output. -**If a command does not list a file it uses as an input**, the action execution +**If an action does not list a file it uses as an input**, the action execution will most likely result in an error. The file is not guaranteed to be available -to the action, so if it **is** there, it's due to a coincidence or error. +to the action, so if it **is** there, it's due to coincidence or error. -**If a command lists a file as an input, but does not use it**: It is fine. However -it can affect the action execution order resulting in sub-optimal performance. +**If an action lists a file as an input, but does not use it**: This is fine. +However, it can affect action execution order, resulting in sub-optimal +performance. Dependencies are resolved by Bazel, which will decide which actions are executed. It is an error if there is a cycle in the dependency graph. Creating @@ -220,14 +222,14 @@ By default, a target is built in the target configuration. For each label attribute, you can decide whether the dependency should be built in the same configuration, or in the host configuration. -In general, sources, dependent libraries and executables that will be needed at +In general, sources, dependent libraries, and executables that will be needed at runtime can use the same configuration. -Tools that are executed as part of the build (e.g. compilers, code generators) +Tools that are executed as part of the build (e.g., compilers, code generators) should be built for the host configuration. In this case, specify `cfg=HOST_CFG` in the attribute. -`DATA_CFG` is present for legacy reasons and should be used for the `data` +`DATA_CFG` is present for legacy reasons and should be used for `data` attributes. <a name="fragments"></a> @@ -235,7 +237,7 @@ Configuration Fragments -------------- Rules may access configuration fragments such as `cpp`, `java` and `jvm`. -However, all required fragments have to be declared in order to avoid access +However, all required fragments must be declared in order to avoid access errors: ```python @@ -254,25 +256,25 @@ my_rule = rule( `ctx.fragments` only provides configuration fragments for the target configuration. If you want to access fragments for the host configuration, -please use `ctx.host_fragments` instead. +use `ctx.host_fragments` instead. Providers --------- -Providers are used to access information from another rule. A rule depending on +Providers are used to access information from other rules. A rule depending on another rule has access to the data the latter provides. These data can be e.g. output files, the libraries the dependent rule is using to link or compile, or anything the depending rule should know about. Using providers is the only way to exchange data between rules. A rule can only access data provided by its direct dependencies, not that of -transitive dependencies: if rule `top` depends on `middle` and `middle` depends +transitive dependencies: if rule `top` depends on `middle`, and `middle` depends on `bottom`, then `middle` is a direct dependency of `top` and `bottom` is a transitive dependency of `top`. In this scenario `top` can only access data provided by `middle`. If `middle` also provides the data that `bottom` provided -to it then and only then can `top` access it. +to it, then and only then can `top` access it. -Only the following data types are allowed to pass using providers: +The following data types can be passed using providers: * `bool` * `integer` @@ -285,18 +287,18 @@ Only the following data types are allowed to pass using providers: Providers are created from the return value of the rule implementation function: ```python -def dependent_rule_implementation(ctx): +def rule_implementation(ctx): ... return struct( transitive_data=set(["a", "b", "c"]) ) ``` -A depending rule might access these data as struct fields of the depending -`target`: +A dependent rule might access these data as struct fields of the `target` being +dependened upon: ```python -def depending_rule_implementation(ctx): +def dependent_rule_implementation(ctx): ... s = set() for dep_target in ctx.attr.deps: @@ -316,12 +318,12 @@ Runfiles Runfiles are a set of files used by the (often executable) output of a rule during runtime (as opposed to build time, i.e. when the binary itself is generated). -Bazel creates a directory tree containing symlinks pointing to the -runfiles during execution, to stage this environment for the binary which can -thus access them during runtime. +During execution, Bazel creates a directory tree containing symlinks pointing to +the runfiles, staging the environment for the binary so it can access the +runfiles during runtime. Runfiles can be added manually during rule creation and/or collected -transitively from dependent rules: +transitively from the rule's dependencies: ```python def rule_implementation(ctx): @@ -345,8 +347,8 @@ def rule_implementation(ctx): ``` Note that non-executable rule outputs can also have runfiles. For example, a -library might need some external files during runtime, and every depending -binary should know about it. +library might need some external files during runtime, and every dependent +binary should know about them. Also note that if an action uses an executable, the executable's runfiles can be used when the action executes. @@ -354,16 +356,18 @@ be used when the action executes. Executable rules ---------------- +An executable rule is a rule that users can run using `bazel run`. + To make a rule executable, set `executable=True` in the [rule function](lib/globals.html#rule). During the analysis phase, the rule must generate the output file `ctx.outputs.executable`. [See example](cookbook.md#outputs-executable) -When the rule is executable, users can run it using `bazel run`. - Test rules ---------- +Test rules are run using `bazel test`. + To create a test rule, set `test=True` in the [rule function](lib/globals.html#rule). The name of the rule must also end with `_test`. Test rules are implicitly executable, which means they @@ -371,5 +375,3 @@ must generate the output file `ctx.outputs.executable`. Test rules inherit the following attributes: `args`, `flaky`, `local`, `shard_count`, `size`, `timeout`. - -Test rules are run using `bazel test`. |