git - 为什么公开可见的 Bazel ProtoBuf 目标是 'not declared'

标签 git protocol-buffers bazel

我正在尝试使用 Bazel's Protocol Buffer Rules编译(生成)Python 语言绑定(bind)和任何依赖项。我的项目布局很简单,只有一个目录 proto,其中包含 .proto 文件和 BUILD 文件。

WORKSPACE
BUILD.six
|-- proto
|    |-- example.proto 
|    |-- BUILD

我的 WORKSPACE 文件:

workspace(name = "com_example")

http_archive(
    name = "com_google_protobuf",
    strip_prefix = "protobuf-3.4.1",
    urls = ["https://github.com/google/protobuf/archive/v3.4.1.zip"],
)

new_http_archive(
    name = "six_archive",
    build_file = "six.BUILD",
    url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz",
)

bind(
    name = "six",
    actual = "@six_archive//:six",
)

在我的 WORKSPACE 文件中,为了便于阅读,已省略下载文件的预期 SHA-256 哈希值。 http_archive WORKSPACE 规则用于自 ProtoBuf GitHub repo包含 Bazel WORKSPACEBUILD 文件。

new_http_archive必须用于六个库,因为它不是 Bazel 工作区。同样值得注意的是 Bazel transitive dependencies必须在我的 WORKSPACE 文件中提供(来自 Bazel 文档):

Bazel only reads dependencies listed in your WORKSPACE file. If your project (A) depends on another project (B) which list a dependency on a third project (C) in its WORKSPACE file, you'll have to add both B and C to your project's WORKSPACE file.

six.BUILD 直接从 repo 中获取并保存在本地:

我的 BUILD 文件

load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")

py_proto_library(
    name = "py",
    use_grpc_plugin = True,
    deps = [
        "@com_google_protobuf//:protobuf_python",
        ":example_proto",
    ],
    visibility = ["//visibility:public"],
    # protoc = "@com_google_protobuf//:protoc",
)

proto_library(
    name = "example_proto",
    srcs = ["example.proto"],
)

构建时出现的问题:

bazel build //proto:py

输出(为了便于阅读而格式化):

proto/BUILD:3:1:
no such target '//:protobuf_python':
target 'protobuf_python' not declared in package '' defined by BUILD and referenced by '//proto:py'.
ERROR: Analysis of target '//proto:py' failed; build aborted.

但是,从我的命令行构建外部依赖项是可行的:

bazel build @com_google_protobuf//:protobuf_python

输出(为了便于阅读而截断):

INFO: Found 1 target...
...
INFO: Elapsed time: 51.577s, Critical Path: 8.63s

protobuf_python 目标明确定义并公开:

最佳答案

问题是您的目标 (//proto:py) 依赖于//:protobuf_python,而不是 @com_gooogle_protobuf//:protobuf_python。您可以使用 bazel 查询来确认这一点。

$ bazel query --output build //proto:py
# proto/BUILD:3:1
py_library(
  name = "py",
  visibility = ["//visibility:public"],
  generator_name = "py",
  generator_function = "py_proto_library",
  generator_location = "proto/BUILD:3",
  deps = ["//:protobuf_python", "@com_google_protobuf//:protobuf_python", "//proto:example_proto"],
  imports = [],
  srcs = [],
)

您可以在 deps 列表中看到它。那么现在的问题是,为什么它取决于那个?你当然没有在任何地方设置它。答案是,由于 py_proto_library 是一个宏,它可以为所欲为。

特别是,宏的这些行给您带来了麻烦:

https://github.com/google/protobuf/blob/6032746882ea48ff6d983df8cb77e2ebf399bf0c/protobuf.bzl#L320 https://github.com/google/protobuf/blob/6032746882ea48ff6d983df8cb77e2ebf399bf0c/protobuf.bzl#L373-L374

py_proto_library 有一个名为 default_runtime 的属性,它附加到 deps 列表。默认值为“:protobuf_python”。但这仅在您在声明 protobuf_python 的同一存储库中使用宏时才有效。

因此,您可以通过在 py_proto_librarys 属性中设置 default_runtime = "@com_google_protobuf//:protobuf_python" 来解决此问题。

关于git - 为什么公开可见的 Bazel ProtoBuf 目标是 'not declared',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46619281/

相关文章:

java - Jgit遍历特定分支的提交内容

go - 解码Protobuf文字

c - protobuf-c : How to pack nested messages

reverse-engineering - 在没有 .proto 文件的情况下解析 Protocol-Buffers

docker - 如何为安装了Bazel,Kubectl和Gcloud的Cloud Build创建Slim Docker镜像?

c++ - 如何在 Bazel 构建命令期间传递标志,例如 -DVERBOSE?

git - 将远程分支重置为之前的提交

git - 集中式 GIT 工作流/部署 - 发布分支

go - 对于 Gazelle,如何让它使用 WORKSPACE 中定义的 go_repository?

linux - Git 和硬链接(hard link)