I am learning Bazel and confused by many basic concepts.
load("//bazel/rules:build_tools.bzl", "build_tools_deps")
build_tools_deps() //build_tools_deps is macro or rules?
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
gazelle_dependencies() //what about the @ mean exactly? where is the bazel_gazelle ?
native.new_git_repository(...) //what about the native mean?
What definition is called a function? what definition is a rule?
Bazel is a tool that automates software builds and tests. Supported build tasks include running compilers and linkers to produce executable programs and libraries, and assembling deployable packages for Android, iOS and other target environments.
A rule defines a series of actions that Bazel performs on inputs to produce a set of outputs, which are referenced in providers returned by the rule's implementation function.
target-name is the name of the target within the package. The name of a rule is the value of the name attribute in the rule's declaration in a BUILD file; the name of a file is its pathname relative to the directory containing the BUILD file.
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle. It uses a human-readable, high-level build language. Bazel supports projects in multiple languages and builds outputs for multiple platforms. Bazel supports large codebases across multiple repositories, and large numbers of users.
A macro is a regular Starlark function that wraps (and expands to) rules.
def my_macro(name = ..., ...):
native.cc_library(...)
android_library(...)
native.genrule(...)
Think of macros as a way to chain and group several rules together, which allows you to pipe the output of some rules into the input of others. At this level, you don't think about how a rule is implemented, but what kinds of inputs and outputs they are associated with.
On the other hand, a rule's declaration is done using the rule()
function. cc_library
, android_library
and genrule
are all rules. The rule implementation is abstracted in a regular function that accepts a single parameter for the rule context (ctx
).
my_rule = rule(
attrs = { ... },
implementation = _my_rule_impl,
)
def _my_rule_impl(ctx):
outfile = ctx.actions.declare_file(...)
ctx.actions.run(...)
return [DefaultInfo(files = depset([outfile]))]
Think of actions as a way to chain and group several command lines together, which works at the level of individual files and running your executables to transform them (ctx.actions.run
with exectuable
, args
, inputs
and outputs
arguments). Within a rule implementation, you can extract information from rule attributes (ctx.attr
), or from dependencies through providers (e.g. ctx.attr.deps[0][DefaultInfo].files
)
Note that rules can only be called in BUILD files, not WORKSPACE files.
@
is the notation for a repository namespace. @bazel_gazelle
is an external repository fetched in the WORKSPACE by a repository rule (not a regular rule), typically http_archive
or git_repository
. This repository rule can also be called from a macro, like my_macro
above or build_tools_deps
in your example.
native.<rule name>
means that the rule is implemented in Java within Bazel and built into the binary, and not in Starlark.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With