如何在Rust中使用Prost生成代码?

11

我不知道如何使用 prost_build 生成代码。

我已经阅读了文档,但它们没有详细说明如何生成代码。cargo build 命令也无法生成代码。

这是我的 build.rs 文件。

extern crate prost_build;
fn main() {
    prost_build::compile_protos(&["src/items.proto"],
                                &["src/"]).unwrap();
}

我的 Cargo.toml

[package]
name = "snazzy"
version = "0.1.0"
authors = ["xxx <xxx@xxx.com>"]
edition = "2018"
build = "build.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bytes = "0.4"
prost = "0.5"

[build-dependencies]
prost-build = { version = "0.4"  }

我的 items.proto

syntax = "proto3";

package snazzy.items;

message Shirt {
    enum Size {
        SMALL = 0;
        MEDIUM = 1;
        LARGE = 2;
    }
    string color = 1;
    Size size = 2;
}

我的文件树:

.
├── build.rs
├── Cargo.lock
├── Cargo.toml
└── src
    ├── items.proto
    └── main.rs

没有构建错误,但我看不到生成的代码在哪里。任何帮助都将不胜感激!
1个回答

11

你说得对,在文档中这个并没有被很好地解释清楚,这是因为构建脚本的工作方式,嗯,部分原因是这样。

你的protobuf实现位于target/{yourArch}/build/{yourCrateName}-{hash}/out

如果没有环境变量的话,要访问它将会非常困难。文档中重要的部分是以下代码片段,用以突出包含的内容:

pub mod items {
    include!(concat!(env!("OUT_DIR"), "/snazzy.items.rs"));
}

这包括在OUT_DIR中可用的文件(在编译过程中自动填充的目录)和protobuf实现的名称(protobuf文件中的包名),并使其所有内容结构体在crate::items下都可以使用。

让这些文件位于构建目录中是有意义的,因为它们是构建过程中生成的产物。在您的crate的src文件夹中进行代码生成会导致混乱,无论是版本控制还是项目完整性方面都会出现问题(会存在信息重复,并且提供的protobuf实现并不是非常重要,但功能蓝图却很重要)。


我忽略了文档的最后一段代码。感谢您详细的解释! - jl0x61
2
你还需要将 build.rs 和 lib.rs 放在项目的根目录下,而不是 src。我猜这份文档认为你已经知道了,但我是新手。 - sudo
我在src文件夹中同时拥有build.rclib.rc,这样程序可以完美运行。如果无法正常运行,我们可以开始另一个问题并一起找出错误。 - taras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接