Search code examples
c++grpcbazel

How to track source of rules (functions) in bazel? Is there any order of initialisation or query to discover it?


How to find places where the rule is defined and which definition bazel uses in this specific package?

Say, I have gRPC installed and looking at grpc/examples/cpp/helloword/BUILD file. I can see a common rule for cpp builds: cc_binary. But this rule is not in grpc WORKSPACE file. Nor it in BUILD file. I do grep -rnw -e '"cc_binary"' and can't find it anywhere but /grpc/third_party/.. subdirectories. And this wouldn't make any sense for bazel to initiate this rule there.

I do finding the dependencies of a rule bazel query "deps(//examples/cpp/helloworld:cc_binary)" and strangely, it doesn't want to query the rules - only targets. I get:

ERROR: no such target '//examples/cpp/helloworld:cc_binary': target 'cc_binary' not declared in package 'examples/cpp/helloworld'

When I do bazel query 'kind(cc_binary, deps(//examples/cpp/helloworld:greeter_client))' I think I'm getting closer with this list:

//examples/cpp/helloworld:greeter_client
@upb//upbc:protoc-gen-upbdefs
@upb//upbc:protoc-gen-upb
@com_google_protobuf//:protoc
//src/compiler:grpc_cpp_plugin
@bazel_tools//third_party/def_parser:def_parser

But how can it help me? Is there a way to do it?


Solution

  • In general, query --output=build will emit a comment indicating where a target's rule class is defined:

    $ bazel query --output build //src/proto/grpc/core:stats_py_pb2
    py_proto_library(
      name = "stats_py_pb2",
      deps = ["//src/proto/grpc/core:stats_descriptor"],
    )
    # Rule stats_py_pb2 instantiated at (most recent call last):
    #   grpc/src/proto/grpc/core/BUILD:35:17 in <toplevel>
    # Rule py_proto_library defined at (most recent call last):
    #   grpc/bazel/python_rules.bzl:154:24 in <toplevel>
    

    cc_binary is a builtin rule, implemented in Java within Bazel. Therefore, Bazel cannot provide a Starlark source for its definition:

    $ bazel query --output build //examples/cpp/helloworld:greeter_client
    cc_binary(
      name = "greeter_client",
      deps = ["//:grpc++", "//examples/protos:helloworld_cc_grpc"],
      defines = ["BAZEL_BUILD"],
      srcs = ["//examples/cpp/helloworld:greeter_client.cc"],
    )
    # Rule greeter_client instantiated at (most recent call last):
    #   grpc/examples/cpp/helloworld/BUILD:17:10 in <toplevel>