Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some questions about bazel concept

Tags:

bazel

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?

like image 955
dingrui Avatar asked Nov 08 '19 13:11

dingrui


People also ask

What is Bazel used for?

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.

What are rules in Bazel?

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.

What is a Bazel target?

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.

What is Bazel build tool?

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.


1 Answers

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.

like image 105
Jin Avatar answered Oct 30 '22 15:10

Jin