blob: d94680cbf87959915c8371a5d2fbd8b043af2661 [file] [log] [blame]
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/compiled_action.gni")
import("//build/rust/rustc_library.gni")
# Generate a rust library based on the provided protobufs.
#
# sources (required)
# The paths to the .proto sources
#
# packages (required)
# The protobuf packages represented by the specified sources and
# their dependencies
#
# include_dirs (optional, default = [])
# Directories in which to search for imported proto files.
#
# deps (optional, default = [])
# Additional rust crates for the generated library to depend on. It is not
# necessary to include the prost runtime, it is included implicitly.
#
# Ex:
# rust_proto_library("vm_guest_proto") {
# sources = [
# "vm_guest.proto",
# ]
# packages = [
# "vm_tools", "google.protobuf",
# ]
# include_dirs = [
# "//third_party/protobuf/src"
# ]
# }
#
# rustc_binary("bin") {
# edition = "2021"
# output_name = "example"
# deps = [
# ":vm_guest_proto",
# ]
# sources = [
# "src/main.rs",
# ]
# }
template("rust_proto_library") {
assert(defined(invoker.sources), "Need protobuf sources for $target_name")
proto_sources = rebase_path(invoker.sources, root_build_dir)
assert(defined(invoker.packages),
"The protobuf packages that are being generated should be specified.")
proto_packages = invoker.packages
if (!defined(invoker.include_dirs)) {
proto_include_dirs = []
} else {
proto_include_dirs = rebase_path(invoker.include_dirs, root_build_dir)
}
crate_deps = [ "//third_party/rust_crates:prost" ]
if (defined(invoker.deps)) {
crate_deps += invoker.deps
}
target_crate_root = "${target_gen_dir}/${target_name}"
# The rust code we expect to be generated by our compiled action
expected_outputs = []
foreach(package, proto_packages) {
expected_outputs += [ "${target_crate_root}/${package}.rs" ]
}
rebased_out_dir = rebase_path(target_crate_root, root_build_dir)
protoc_label = "//third_party/protobuf:protoc($host_toolchain)"
protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc"
prost_build_label =
"//tools/protobuf/rust_proto:prost_build_standalone($host_toolchain)"
prost_build_path = get_label_info(prost_build_label, "root_out_dir") +
"/prost_build_standalone"
include_args = []
foreach(dir, proto_include_dirs) {
include_args += [
"--include-dirs",
dir,
]
}
proto_args = []
foreach(proto, proto_sources) {
proto_args += [
"--protos",
proto,
]
}
_main_target_label = get_label_info(":$target_name", "label_with_toolchain")
action("gen_${target_name}") {
script = "//tools/protobuf/rust_proto/prost_build_wrapper.py"
inputs = [
prost_build_path,
protoc_path,
]
deps = [
prost_build_label,
protoc_label,
]
sources = invoker.sources
outputs = [ "${target_crate_root}/lib.rs" ] + expected_outputs
depfile = "$target_gen_dir/$target_name.d"
args =
[
"--protoc",
rebase_path(protoc_path, root_build_dir),
"--prost_build",
rebase_path(prost_build_path, root_build_dir),
"--out-dir",
rebased_out_dir,
"--gn-target",
_main_target_label,
"--depfile",
rebase_path(depfile, root_build_dir),
"--expected-outputs",
] + rebase_path(outputs, root_build_dir) + [ "--expected-packages" ] +
proto_packages + include_args + proto_args
}
rustc_library(target_name) {
edition = "2021"
deps = [ ":gen_${target_name}" ] + crate_deps
source_root = "${target_crate_root}/lib.rs"
sources = get_target_outputs(":gen_${target_name}")
}
}