crosvm/protos/build.rs
David Tolnay 65928af6c9 protos: Merge plugin_proto crate under protos::plugin
This de-duplicates the two separate build.rs files dealing with proto
compilation. The trunks interface.proto will be exposed under
protos::trunks and the plugin proto will be exposed under protos::plugin.

BUG=none
TEST=cargo check
TEST=cargo check --features tpm
TEST=cargo check --features plugin
TEST=cargo check --features tpm,plugin
TEST=FEATURES=test emerge-nami crosvm
TEST=FEATURES=test USE=crosvm-tpm emerge-nami crosvm
TEST=FEATURES=test USE=crosvm-plugin emerge-nami crosvm
TEST=FEATURES=test USE='crosvm-tpm crosvm-plugin' emerge-nami crosvm
TEST=local kokoro
CQ-DEPEND=CL:1553971

Change-Id: I203b654a38e9d671a508156ae06dfb6f70047c4f
Reviewed-on: https://chromium-review.googlesource.com/1556417
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: David Tolnay <dtolnay@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2019-04-12 14:49:57 -07:00

106 lines
3.5 KiB
Rust

// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::env;
use std::error::Error;
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};
type Result<T> = std::result::Result<T, Box<dyn Error>>;
struct ExternalProto {
// Where to find protos during builds within cros_sdk. Relative to
// $SYSROOT environment variable set by emerge builds.
dir_relative_to_sysroot: &'static str,
// Where to find protos during "cargo build" in a local developer
// environment. Relative to the platform/crosvm/protos directory.
dir_relative_to_us: &'static str,
// *.proto file expected to exist in both of the above directories.
proto_file_name: &'static str,
// Code generated by proto compiler will be placed under
// protos::generated::$module_name.
module: &'static str,
}
// Rustfmt bug: https://github.com/rust-lang/rustfmt/issues/3498
#[rustfmt::skip]
static EXTERNAL_PROTOS: &[ExternalProto] = &[
#[cfg(feature = "trunks")]
ExternalProto {
dir_relative_to_sysroot: "usr/include/chromeos/dbus/trunks",
dir_relative_to_us: "../../../platform2/trunks",
proto_file_name: "interface.proto",
module: "trunks",
},
];
struct LocalProto {
// Corresponding to the input file src/$module.proto.
module: &'static str,
}
#[rustfmt::skip]
static LOCAL_PROTOS: &[LocalProto] = &[
#[cfg(feature = "plugin")]
LocalProto { module: "plugin" },
];
fn main() -> Result<()> {
let out_dir = env::var("OUT_DIR")?;
let sysroot = env::var_os("SYSROOT");
// Write out a Rust module that imports the modules generated by protoc.
let generated = PathBuf::from(&out_dir).join("generated.rs");
let out = File::create(generated)?;
// Compile external protos.
for proto in EXTERNAL_PROTOS {
let dir = match &sysroot {
Some(dir) => PathBuf::from(dir).join(proto.dir_relative_to_sysroot),
None => PathBuf::from(proto.dir_relative_to_us),
};
let input_path = dir.join(proto.proto_file_name);
protoc(proto.module, input_path, &out)?;
}
// Compile protos from the local src directory.
for proto in LOCAL_PROTOS {
let input_path = format!("src/{}.proto", proto.module);
protoc(proto.module, input_path, &out)?;
}
Ok(())
}
// Compile a single proto file located at $input_path, placing the generated
// code at $OUT_DIR/$module and emitting the right `pub mod $module` into the
// output file.
fn protoc<P: AsRef<Path>>(module: &str, input_path: P, mut out: &File) -> Result<()> {
let input_path = input_path.as_ref();
let input_dir = input_path.parent().unwrap();
// Place output in a subdirectory so that different protos with the same
// common filename (like interface.proto) do not conflict.
let out_dir = format!("{}/{}", env::var("OUT_DIR")?, module);
fs::create_dir_all(&out_dir)?;
// Invoke protobuf compiler.
protoc_rust::run(protoc_rust::Args {
out_dir: &out_dir,
includes: &[input_dir.as_os_str().to_str().unwrap()],
input: &[input_path.as_os_str().to_str().unwrap()],
..Default::default()
})?;
// Write out a `mod` that refers to the generated module.
let file_stem = input_path.file_stem().unwrap().to_str().unwrap();
writeln!(out, "#[path = \"{}/{}.rs\"]", out_dir, file_stem)?;
writeln!(out, "pub mod {};", module)?;
Ok(())
}