为什么一个公开可见的巴泽尔protobuf的目标“未声明”(Why is a publicly vi

2019-09-30 17:45发布

我试图用巴泽尔的协议缓冲规则编译(生成)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工作空间规则用于自protobuf的GitHub库包含巴泽勒WORKSPACEBUILD文件。

该new_http_archive必须用于六个库,因为它不是一个巴泽尔工作区。 另外值得一提的是巴泽尔传递依赖必须在我提供WORKSPACE文件(从巴泽尔文档):

巴泽尔只读取工作区中的文件中列出的依赖关系。 如果你的项目(A)依赖于另一个项目(B),这在其工作区文件列出在第三个项目(C)的依赖,你就必须两个B和C添加到您的项目的工作区文件。

six.BUILD直接从回购取出并保存在本地:

  • https://github.com/google/protobuf/blob/master/six.BUILD

我的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目标是明确和公开:

  • https://github.com/google/protobuf/blob/77f64bb7779ec2195f9bc4dc82497d12c18fc6b7/BUILD#L756

Answer 1:

问题是,你的目标(原//:PY)取决于//:protobuf_python,不@com_gooogle_protobuf //:protobuf_python。 你可以用巴泽勒查询证实了这一点。

$ 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同一个版本库使用宏的作品。

所以,你可以通过设置解决这个问题default_runtime = "@com_google_protobuf//:protobuf_python"你py_proto_librarys属性。



文章来源: Why is a publicly visible Bazel ProtoBuf target 'not declared'