当前位置: 首页 > 知识库问答 >
问题:

proto包和实际目录结构之间的关系是什么

彭宏阔
2023-03-14

我读过官方文件

为了澄清我的问题,假设这是我的项目结构:

root
├── project
│   └── protos
│       ├── common
│       │   └── common.proto
│       └── custom
│           ├── app.proto
│           └── util
│               └── util.proto           

常见的原型

syntax = "proto3";

// how should I decide the package for this file based on my project structure?
package project.protos.common;

message Common {
    // ...
}

app.proto,它引用common.proto(在另一个单独的目录中)和util.proto(在子目录中)

syntax = "proto3";

package project.protos.custom;

import "project/protos/common/common.proto";
import "project/protos/custom/util/util.proto";
import "google/protobuf/timestamp.proto";

message App {
    project.protos.common.Common common = 3;
    project.protos.custom.util.Util util = 4;
}

util。原型

syntax = "proto3";

package project.protos.custom.util;

option java_multiple_files = true;

message Util {
    // ...
}

在做了几次试验后,结果表明,如果我在根目录下运行protoc命令,使用以下命令:

protoc -I . --java_out=. project/protos/**/*.proto

然后导入正常工作,每个原始文件都被编译为没有错误。但是,假设我不是在根目录下运行协议,而是在子目录项目中使用类似的命令:

protoc -I . --java_out=. protos/**/*.proto

编译将失败,并出现以下错误:

project/protos/common/common.proto: File not found.
project/protos/custom/util/util.proto: File not found.
protos/custom/app.proto:6:1: Import "project/protos/common/common.proto" was not found or had errors.
protos/custom/app.proto:8:1: Import "project/protos/custom/util/util.proto" was not found or had errors.
protos/custom/app.proto:19:5: "project.protos.common.Common" seems to be defined in "protos/common/common.proto", which is not imported by "protos/custom/app.proto".  To use it here, please add the necessary import.
protos/custom/app.proto:20:5: "project.protos.custom.util.Util" is not defined.

由于我大部分时间都在使用Java,所以我目前正在考虑如何打包

也就是说,如果我想用指定为“project.protos.common”的包编译proto,那么我应该在project dir的父目录上运行protoc命令,其中project/protos/common是一个有效路径。

类似地,如果我在另一个proto文件中导入一个proto,导入路径设置为"project/原型/自定义/util/util.proto",那么我也应该确保在我运行proc命令时从目录中,路径project/pros/自定义/util/util.proto存在。

我目前猜测无论我们输入到-I选项中的路径是什么,Proc都会以与Java类路径或python搜索路径相同的方式处理它们。导入后,Proc将在每个指定的-I路径上查找导入的文件,遵循由import语句指示的相对路径。

但是在网上搜索类似的问题,看了一些文章之后,现在我有了这样的印象,在Probuf中打包和导入实际上比我想象的要灵活得多。这里我的理解错了吗?

共有1个答案

柯昱
2023-03-14

我将间接回答:

  1. 包名对应目录
  2. 一个包可能跨越单个目录中的多个文件
  3. (但是)即使在同一个包中,单个文件也必须导入Pros
  4. 通过一些org id命名空间|范围包是有用的(例如googlefor时间戳
  5. 相关Packages的层次结构(例如google.protobuf清单为google/probuf/...)与其文件系统位置无关。
  6. 尽管Package层次结构是固定的,但在生成特定于语言的绑定时,“放置”具有灵活性。

我将尝试提供每种方法的示例

protocinclude目录为例,包google。protobuf清楚地将其标识为谷歌发起的包,代表protobuf的“东西”。

Package必须在目录中表示为google/probuf,但它在系统中的位置是任意的,没有依赖关系(请参阅--proto_path)。

包中的文件,例如api。proto必须导入,例如类型。proto(使用完整的名称空间路径(即google/protobuf/type.proto),即使它们共享一个包。

foo.proto时,如果foo.proto导入google/Probug/api.protoProc需要一些查找Package的方法,因此需要Proc--proto_path=path/to/google(尽管如果Proc在路径中,则不需要在Linux上添加include目录)。所有导入必须类似--proto_path'd。

其中,proto输出文件,以及(更重要的是)用于生成输出的名称空间,由于proto文件中的选项[langauge]_package标志,具有一定的灵活性。

我不熟悉Java,但在Golang的情况下,我可以使用选项go_package来帮助我指定一个Golang模块名称(github.com/[org]/[repo]),以确保生成的文件放置在repo中,以便它们将被其他Golang模块正确导入。

 类似资料:
  • 现在其他包中的 HelloWorld.java 可以访问数据类型这个类。 如果我在其他包这个目录中创建一个新的目录,并且把 HelloWorld.java 移动到这个目录内。编辑器会提示需要声明这个包,假如这个新的目录的名称是 h,那么需要增加一条 package h;这个时候数据类型这个类就无法被访问了。 包和目录层级之间是有什么关系?

  • 问题内容: 为了比较不同供应商(Oracle,SQL Server,DB2,MySQL和PostgreSQL)的数据库,我如何唯一地标识任何对象,我是否需要目录?例如,在Java的DatabaseMetadata中,我至少应指定目录和模式fooPattern。 目录仅仅是数据存储的抽象吗? 问题答案: 在Oracle中: 服务器实例==数据库==目录==所有数据均由同一执行引擎管理 模式==数据库

  • 在OSGi bundles中,用一个版本号导出和导入包。包仍然定义了一个版本。这在我看来是多余的。

  • 我看到这里 老实说,我不理解这张纸条。它们是否意味着有可能用MonadPlus永远中断,例如IO Bool?比如说,IO False将破坏它。。。 当然,我可以破例或者永远实现自己的,但我的兴趣是关于这个奇怪的音符。

  • 问题内容: 我发现了一个示例,在该示例中,将按钮添加到面板(的实例),然后将面板添加到容器(的实例),然后根据构造将容器包括在(窗口)中。 我尝试了两件事: 我摆脱了容器。在更多详细信息中,我将按钮添加到面板(实例为),然后将面板添加至窗口(实例为)。工作正常。 我摆脱了面板。在更多详细信息中,我直接将按钮添加到了容器,然后将容器添加到了窗口(的实例)。 所以,我不明白两件事。 为什么我们有两种竞

  • 问题内容: 我最近学习了如何在工作流程中使用virtualenv和virtualenvwrapper,但是我在一些指南中看到了pyenv,但是我似乎无法理解pyenv是什么以及它与virtualenv有何不同/相似。pyenv是virtualenv的更好/更新的替代品还是免费的工具?如果后者有什么不同之处,以及两者(以及适用的virtualenvwrapper)如何一起工作? 问题答案: Pyen