Bazel Rules: Hello, World

2021-12-25 • edited 2021-12-30

Empty Rule #

Canonically, the minimal rule in Bazel is:

def _demo_rule_impl(ctx):
    pass

demo_rule = rule(
    implementation = _demo_rule_impl,
)

In this example, demo_rule is a rule, a specialized callable object created with the rule function. We will be using it from a BUILD file. _demo_rule_impl the implementation function. We prefix it with _ to indicate that it is private and cannot be used in other files.

we need a Bazel workspace to call demo_rule. An empty WORKSPACE file will be sufficient. A BUILD file is required to define a Bazel package for the rule, so let’s create the folder structure:

./
├── empty/
│  ├── BUILD.bazel
│  └── rules.bzl
└── WORKSPACE.bazel

rules.bzl stores our functions and rule definitions. BUILD file loads the rule and defines a target:

load(":rules.bzl", "demo_rule")

demo_rule(name = "empty")

In this case, load refers to rules.bzl as a target belonging to the same package. In other words, we expect rules.bzl to be located in the same directory.

name is the build target label. Given the workspace structure, we can refer to this target in several ways:

  • @//empty:empty is the full canonical name, with @ referring to the main repository, the first empty referring to the package (directory) name, and the second empty referring to the target label;
  • //empty:empty is a common form omitting the reference to the main repo;
  • //empty is a shortcut referring to the target with the same name as the package.
  • :empty could be used from within the package.

We can now build (but not run) the package:

$ bazel build //empty
...
INFO: Found 1 target...
Target //empty:empty up-to-date (nothing to build)
...

The complete code for the example is here.

Hello, World! #

Having done all this work we can now get to the actual ‘Hello, World!’ Bazel defines a print function that is normally used only for debugging. We can modify our implementation function to output a DEBUG string:

def _demo_rule_impl(ctx):
    print("Hello, World!")

Let’s build the target:

$ bazel build //hello
DEBUG: /Users/sb/repo/examples/bazel_rules/hello/rules.bzl:2:10: Hello, World!
...

We can also see from the output that I copied the example to a hello folder and changed the target name to match. The complete code is here.

bazel

Bazel Rules: Create a File