Bazel School: Rules

Hello World

ctx ctx.actions

# hello_world.bzl
def _hello_world(ctx):
    out = ctx.actions.declare_file(ctx.attr.name)
    ctx.actions.write(out, "Hello world!\n")
    return DefaultInfo(
        files = depset([out]),
    )

hello_world = rule(
    _hello_world,
)
# BUILD
load(":hello_world.bzl", "hello_world")

hello_world(name = "hello.txt")
bazel build :hello.txt
# INFO: Analysed target //:hello.txt (4 packages loaded, 20 targets configured).
# INFO: Found 1 target...
# Target //:hello.txt up-to-date:
#     bazel-bin/hello.txt
# INFO: 0 processes.
# INFO: Build completed successfully, 2 total actions
# 
cat bazel-bin/hello.txt
# Hello world!

Attributes

attr

# examples.bzl
def _attrs_example(ctx):
    content = ctx.attr.template.format(**ctx.attr.vars)
    out = ctx.actions.declare_file(ctx.attr.name)
    ctx.actions.write(out, content)
    return DefaultInfo(
        files = depset([out]),
    )

attrs_example = rule(
    _attrs_example,
    attrs = {
        "template": attr.string(mandatory = True),
        "vars": attr.string_dict(),
    },
)
# BUILD
load(":examples.bzl", "attrs_example")

TEMPLATE = "{name} caught the {object}\n"

attrs_example(
    name = "lassie.txt",
    template = TEMPLATE,
    vars = {
        "name": "Lassie",
        "object": "ball",
    },
)

attrs_example(
    name = "tama.txt",
    template = TEMPLATE,
    vars = {
        "name": "Tama",
        "object": "mouse",
    },
)
bazel build :lassie.txt :tama.txt
# INFO: Analysed 2 targets (4 packages loaded, 21 targets configured).
# INFO: Found 2 targets...
# Target //:lassie.txt up-to-date:
#   bazel-bin/lassie.txt
# Target //:tama.txt up-to-date:
#   bazel-bin/tama.txt
# INFO: 0 processes.
# INFO: Build completed successfully, 3 total actions
# 
cat bazel-bin/lassie.txt
# Lassie caught the ball
cat bazel-bin/tama.txt
# Tama caught the mouse

Subprocesses

# examples.bzl
def _exec_example(ctx):
    out = ctx.actions.declare_file(ctx.attr.name)
    ctx.actions.run(
        executable = "dd",
        arguments = [
            "if=/dev/zero",
            "of={}".format(out.path),
            "bs={}".format(ctx.attr.block_size),
            "count={}".format(ctx.attr.count),
        ],
        outputs = [out],
        mnemonic = "CopyFile",
        progress_message = "Copying {} zeros".format(ctx.attr.count * ctx.attr.block_size),
    )
    return DefaultInfo(
        files = depset([out]),
    )

exec_example = rule(
    _exec_example,
    attrs = {
        "block_size": attr.int(default = 1),
        "count": attr.int(mandatory = True),
    },
)
# BUILD
load("//:examples.bzl", "exec_example")

exec_example(
    name = "a_thousand_zeros",
    count = 1000,
)
bazel build :a_thousand_zeros
# INFO: Analysed target //:a_thousand_zeros (3 packages loaded, 20 targets configured).
# INFO: Found 1 target...
# INFO: From Copying 1000 zeros:
# 1000+0 records in
# 1000+0 records out
# 1000 bytes transferred in 0.001651 secs (605676 bytes/sec)
# Target //:a_thousand_zeros up-to-date:
#     bazel-bin/a_thousand_zeros
# INFO: 1 process: 1 darwin-sandbox.
# INFO: Build completed successfully, 2 total actions

Dependencies

File

# examples.bzl
def _files_example(ctx):
    outs = []
    for src_file in ctx.files.srcs:
        out = ctx.actions.declare_file(ctx.attr.name + "/" + src_file.basename)
        outs.append(out)
        ctx.actions.run(
            executable = "cp",
            arguments = [src_file.path, out.path],
            outputs = [out],
            inputs = [src_file],
            mnemonic = "CopyFile",
            progress_message = "Copying {}".format(src_file.path),
        )
    return DefaultInfo(
        files = depset(outs),
    )

files_example = rule(
    _files_example,
    attrs = {
        "srcs": attr.label_list(
            allow_files = True,
            allow_empty = False,
            mandatory = True,
        ),
    },
)
# BUILD
load("//:examples.bzl", "files_example")

files_example(
    name = "copied",
    srcs = [":lassie.txt", ":tama.txt"],
)
    
bazel build :copied
# INFO: Analysed target //:copied (4 packages loaded, 22 targets configured).
# INFO: Found 1 target...
# Target //:copied up-to-date:
#   bazel-bin/copied/lassie.txt
#   bazel-bin/copied/tama.txt
# INFO: 2 processes: 2 darwin-sandbox.
# INFO: Build completed successfully, 5 total actions
# 
cat bazel-bin/copied/lassie.txt
# Lassie caught the ball

Providers

Macros

Directory Outputs

Test Rules