Require / Provide
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.