Search code examples
bazelbazel-query

Use `bazel query` inside a build file


I am using Bazel with Golang, but the question is no Go-specific. I have a common go directory structure:

cmd/
├── mycommand/
│   ├── BUILD.bazel
│   ├── main.go
│   └── somefolder
│       └── other.go
├── othercommand/
│   ├── BUILD.bazel
│   └── main.go
pkg/
└── mypackage/
    ├── BUILD.bazel
    └── init.go
BUILD.bazel
WORKSPACE

... and I'd like to reference targets under the cmd folder. I have a bazel query that will give me the list of those targets:

bazel query 'kind("go_binary", deps(//cmd/...))'
  • //cmd/mycommand:mycommand
  • //cmd/othercommand:othercommand

The question: How can I include this query in a BUILD.bazel file, something like the following:

pkg_tar(
    name = "release",
    srcs = kind("go_binary", deps(//cmd/...)),
    mode = "0644",
)

...which gives

ERROR: /some/path/BUILD.bazel:10:12: name 'kind' is not defined
ERROR: /some/path/BUILD.bazel:10:30: name 'deps' is not defined

Solution

  • Build targets need to be statically referenced in BUILD files, so embedding queries as inputs to rule attributes does not work.

    However, there are a couple of ways to dynamically generate targets to be used statically in the BUILD files:

    1) Run a tool that generates a BUILD file before running Bazel. rules_go's Gazelle is a good example.

    2) Write a repository rule that invokes non-hermetic tools to dynamically generate targets that your BUILD files can depend on.

    Note that you may come across the genquery rule, which does let you perform a query on targets, but the rule outputs to a file during Bazel's execution phase, and not a Starlark list that can ingested into other rules' attributes during the analysis phase, which happens before the execution phase.