本文介绍了为什么公开可见的Bazel ProtoBuf目标'未声明'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 WORKSPACE规则用于自包含Bazel WORKSPACE BUILD 文件。



必须用于六个库,因为它不是Bazel工作区。另外值得注意的是,必须在我的系统中提供 WORKSPACE 文件(来自Bazel文档):b / b
$ b


$ b six.BUILD 直接取自回购和本地保存:







我的 BUILD 文件

 加载(@ 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(
nam e =example_proto,
srcs = [example.proto],

在构建时出现问题:

  bazel构建//原型:py 
$ b

 proto / BUILD:3:1:
没有这样的目标'//:protobuf_python':
目标'protobuf_python'未在BUILD定义的包中声明,并且由'// proto:py' 。
错误:分析目标'// proto:py'失败;建立中止。

但是,从我的命令行构建外部依赖项的工作原理:

  bazel build @com_google_protobuf //:protobuf_python 

输出(为可读性截断):

 信息:找到1个目标... 
...
INFO:经过时间:51.577s,关键路径: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 = [],

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



特别是,这些宏的这些行引起了你的麻烦:






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

所以,你可以通过设置 default_runtime =@ com_google_protobuf //:您的py_proto_librarys属性中的protobuf_python


I'm attempting to use Bazel's Protocol Buffer Rules to compile (generate) Python language bindings and any dependencies. The layout of my project is simple, with a single directory, proto, containing the .proto file and BUILD file.

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

My WORKSPACE file:

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",
)

In my WORKSPACE file, the expected SHA-256 hash of the file downloaded has been omitted for readability. The http_archive WORKSPACE rule is used to since the ProtoBuf GitHub repo contains Bazel WORKSPACE and BUILD files.

The new_http_archive must be used for the six library since it's not a Bazel workspace. Also worth noting that Bazel transitive dependencies must be provided in my WORKSPACE file (from Bazel documentation):

six.BUILD is taken directly from the repo and saved locally:

My BUILD file

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"],
)

The problem arrises when building:

bazel build //proto:py

Output (formatted for readability):

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.

However, building the external dependency from my command line works:

bazel build @com_google_protobuf//:protobuf_python

Output (truncated for readability):

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

The protobuf_python target is clearly defined and public:

解决方案

The problem is that your target (//proto:py) depends on //:protobuf_python, not @com_gooogle_protobuf//:protobuf_python. You can confirm this with bazel query.

$ 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 = [],
)

You can see it in the deps list. So now the question is, why does it depend on that? You certainly didn't set that anywhere. The answer is that, since py_proto_library is a macro, it can do whatever it wants.

In particular, these lines of the macro are causing you trouble:

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

py_proto_library has an attribute called default_runtime that it appends to the deps list. The default value is ":protobuf_python". But that only works if you use the macro in the same repository that declares protobuf_python.

So, you can fix this by setting default_runtime = "@com_google_protobuf//:protobuf_python" in your py_proto_librarys attributes.

这篇关于为什么公开可见的Bazel ProtoBuf目标'未声明'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 13:15