bazelbuild / bazel-skylib

Common useful functions and rules for Bazel
https://bazel.build/
Apache License 2.0
391 stars 180 forks source link

`run_binary` does not expand `$(RULEDIR)` in args #438

Open nak3 opened 1 year ago

nak3 commented 1 year ago

Example:

WORKSPACE:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "bazel_skylib",
    sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
        "https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
    ],
)

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")

bazel_skylib_workspace()

BUILD:

load("@bazel_skylib//rules:run_binary.bzl", "run_binary")

sh_binary(
    name = "generate_file",
    srcs = ["generate_file.sh"],
)

run_binary(
    name = "run_b",
    srcs = [],
    outs = ["out.txt"],
    args = [
        "$(RULEDIR)",
    ],
    tool = ":generate_file",
)

generate_file.sh:

#!/bin/bash

touch $1/out.txt

Running bazel build //:run_b will then result in an error message:

$ bazel build //:run_b
INFO: Analyzed target //:run_b (0 packages loaded, 3 targets configured).
INFO: Found 1 target...
ERROR: /home/knakayam/dev/playground/misc/bazel/BUILD:8:11: RunBinary out.txt failed: (Exit 1): generate_file failed: error executing command (from target //:run_b) bazel-out/k8-opt-exec-2B5CBBC6/bin/generate_file '$(RULEDIR)'

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
touch: cannot touch '$(RULEDIR)/out.txt': No such file or directory
Target //:run_b failed to build
Use --verbose_failures to see the command lines of failed build steps.

This is because $(RULEDIR) is not expanded in args. Using genrule instead of run_binary can solve the problem.

genrule(
    name = "run_g",
    srcs = [],
    outs = ["out.txt"],
    cmd = "$(location :generate_file) $(RULEDIR)",
    tools = [":generate_file"],
)

genrule documetation says:

genrule - https://bazel.build/reference/be/general

If you only need to run a single tool, consider using run_binary instead.

but run_binary cannot be considered only when running a single tool.