我正在尝试使用 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 WORKSPACE
和 BUILD
文件。
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/