Search code examples
bazelbazel-rulesbazel-aspect

Bazel: why lint failed for variable reference?


I had this genrule in BUILD file, but bazel build failed for the error of:

in cmd attribute of genrule rule //example:create_version_pom: $(BUILD_TAG) not defined

genrule(
    name = "create_version_pom",
    srcs = ["pom_template.xml"],
    outs = ["version_pom.xml"],
    cmd = "sed 's/BUILD_TAG/$(BUILD_TAG)/g' $< > $@",
)

What's the reason, and how to fix it please?


Solution

  • The cmd attribute of genrule will do variable expansion for Bazel build variables before the command is executed. The $< and $@ variables for the input file and the output file are some of the pre-defined variables. Variables can be defined with --define, e.g.:

    $ cat BUILD
    genrule(
      name = "genfoo",
      outs = ["foo"],
      cmd = "echo $(bar) > $@",
    )
    
    $ bazel build foo --define=bar=123
    INFO: Analyzed target //:foo (5 packages loaded, 8 targets configured).
    INFO: Found 1 target...
    Target //:foo up-to-date:
      bazel-bin/foo
    INFO: Elapsed time: 0.310s, Critical Path: 0.01s
    INFO: 2 processes: 1 internal, 1 linux-sandbox.
    INFO: Build completed successfully, 2 total actions
    
    $ cat bazel-bin/foo
    123
    

    So to have $(BUILD_TAG) work in the genrule, you'll want to pass
    --define=BUILD_TAG=the_build_tag

    Unless it's that you want BUILD_TAG replaced with literally $(BUILD_TAG), in which case the $ needs to be escaped with another $: $$(BUILD_TAG).

    See
    https://docs.bazel.build/versions/main/be/general.html#genrule.cmd
    https://docs.bazel.build/versions/main/be/make-variables.html

    Note that Bazel also has a mechanism for "build stamping" for bringing information like build time and version numbers into the build:
    https://docs.bazel.build/versions/main/user-manual.html#workspace_status
    https://docs.bazel.build/versions/main/command-line-reference.html#flag--embed_label

    Using --workspace_status_command and --embed_label are a little more complicated though.