【问题标题】:Why is a publicly visible Bazel ProtoBuf target 'not declared'为什么“未声明”公开可见的 Bazel ProtoBuf 目标
【发布时间】:2018-03-19 01:25:41
【问题描述】:

我正在尝试使用Bazel's Protocol Buffer Rules 来编译(生成)Python 语言绑定和任何依赖项。我的项目布局很简单,只有一个目录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 仅读取 WORKSPACE 文件中列出的依赖项。如果你的 项目(A)依赖于另一个项目(B),其中列出了依赖项 第三个项目 (C) 在其 WORKSPACE 文件中,您必须同时添加 B 和 C 到您项目的 WORKSPACE 文件中。

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 目标已明确定义并公开:

【问题讨论】:

    标签: git protocol-buffers bazel


    【解决方案1】:

    问题是你的目标(//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" 来解决此问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多