为什么公开可见的Bazel ProtoBuf目标'未声明' [英] Why is a publicly visible Bazel ProtoBuf target 'not declared'

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

问题描述

我试图使用巴泽尔协议缓冲区规则编译(生成)Python语言绑定和任何依赖项。我的项目布局很简单,只有一个目录 proto ,其中包含 .proto 文件和 BUILD 文件。

 工作空间
BUILD.six
| - 原型
| | - example.proto
| | - BUILD

我的 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/ (
名称=six,
实际值=b / source / s / six / six-1.10.0.tar.gz,


绑定@six_archive //:six,

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



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


Bazel只读取您的WORKSPACE文件。如果您的
项目(A)依赖于另一个项目(B),该项目在其WORKSPACE文件中列出了对
a第三个项目(C)的依赖关系,则必须同时添加B
和C到您项目的WORKSPACE文件。



$ 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是一个宏,它可以做任何想要的事情。



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



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 //:您的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):

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 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#L320 https://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目标'未声明'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆