This is a generalised mechanism for rules to provide specialised dependencies to other
rules. The most obvious example is proto_library
, which generates code for
multiple languages, usually only one of which is actually needed by each dependency
We could break it up into multiple parts explicitly, but ideally we want to maintain
the illusion that there's one rule by the name given in the BUILD file and have all other
rules depend only on that. However it's pretty suboptimal to have your
python_library
have to wait for the C++ and Java generated code to compile.
This is solved by the proto_library
rule declaring the following property:
provides = {
'py': ':python_dependency',
'java': ':java_dependency',
'cc': ':cc_dependency',
}
And then the python_library
rule is annotated with
requires = ['py'],
Individually neither has any effect, but when a rule with a particular require
depends on another with a matching provide
, its dependency is matched directly
to the one specified by the providing rule. This means that it can skip other dependencies
that it doesn't care about and be matched only to the ones it does.
The consequence of this - skipping the actual declared dependency - can be a bit
nonobvious so should be invoked sparingly. Typically the rule declaring
provides
should be a no-op collecting rule such as filegroup
and the various provided rules shouldn't normally be needed together. Different languages
are the most common example here (and indeed this feature was nearly named
language
at one point).
The requires
stanza is also responsible for colouring the interactive build
output. Currently the available colours are hardcoded but one of these days they might
become configurable.