1 //
2 // Copyright 2021 Google, Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at:
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 extern crate protobuf_codegen;
17 extern crate protoc_grpcio;
18 extern crate protoc_rust;
19
20 use std::env;
21 use std::fs;
22 use std::io::Write;
23 use std::path::{Path, PathBuf};
24
paths_to_strs<P: AsRef<Path>>(paths: &[P]) -> Vec<&str>25 fn paths_to_strs<P: AsRef<Path>>(paths: &[P]) -> Vec<&str> {
26 paths.iter().map(|p| p.as_ref().as_os_str().to_str().unwrap()).collect()
27 }
28
29 // Generate mod.rs files for given input files.
gen_mod_rs<P: AsRef<Path>>(out_dir: PathBuf, inputs: &[P], grpc: bool)30 fn gen_mod_rs<P: AsRef<Path>>(out_dir: PathBuf, inputs: &[P], grpc: bool) {
31 // Will panic if file doesn't exist or it can't create it
32 let mut f = fs::File::create(out_dir.join("mod.rs")).unwrap();
33
34 f.write_all(b"// Generated by build.rs\n\n").unwrap();
35
36 for i in 0..inputs.len() {
37 let stem = inputs[i].as_ref().file_stem().unwrap();
38 f.write_all(format!("pub mod {}; \n", stem.to_str().unwrap()).as_bytes()).unwrap();
39 if grpc {
40 f.write_all(format!("pub mod {}_grpc;\n", stem.to_str().unwrap()).as_bytes()).unwrap();
41 }
42 }
43 }
44
main()45 fn main() {
46 let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
47 let proto_out_dir = out_dir.join("proto_out");
48 let grpc_out_dir = out_dir.join("grpc_out");
49
50 // Make sure to create the output directories before using it
51 match fs::create_dir(proto_out_dir.as_os_str().to_str().unwrap()) {
52 Err(e) => println!("Proto dir failed to be created: {}", e),
53 _ => (),
54 };
55
56 match fs::create_dir(grpc_out_dir.as_os_str().to_str().unwrap()) {
57 Err(e) => println!("Grpc dir failed to be created: {}", e),
58 _ => (),
59 }
60
61 // Proto root is //platform2/bt/gd
62 let proto_root = match env::var("PLATFORM_SUBDIR") {
63 Ok(dir) => PathBuf::from(dir).join("bt/gd"),
64 // Currently at //platform2/gd/rust/facade_proto
65 Err(_) => PathBuf::from(env::current_dir().unwrap()).join("../..").canonicalize().unwrap(),
66 };
67
68 //
69 // Generate protobuf output
70 //
71 let facade_dir = proto_root.join("facade");
72 let proto_input_files = [facade_dir.join("common.proto")];
73 let proto_include_dirs = [facade_dir];
74
75 protoc_rust::Codegen::new()
76 .out_dir(proto_out_dir.as_os_str().to_str().unwrap())
77 .inputs(&paths_to_strs(&proto_input_files))
78 .includes(&paths_to_strs(&proto_include_dirs))
79 .customize(Default::default())
80 .run()
81 .expect("protoc");
82
83 //
84 // Generate grpc output
85 //
86 let grpc_proto_input_files = [
87 proto_root.join("hci/facade/hci_facade.proto"),
88 proto_root.join("hci/facade/controller_facade.proto"),
89 proto_root.join("hal/hal_facade.proto"),
90 proto_root.join("facade/rootservice.proto"),
91 ];
92 let grpc_proto_include_dirs = [
93 proto_root.join("hci/facade"),
94 proto_root.join("hal"),
95 proto_root.join("facade"),
96 proto_root,
97 ];
98
99 protoc_grpcio::compile_grpc_protos(
100 &grpc_proto_input_files,
101 &grpc_proto_include_dirs,
102 &grpc_out_dir,
103 None,
104 )
105 .expect("Failed to compile gRPC definitions");
106
107 gen_mod_rs(proto_out_dir, &proto_input_files, false);
108 gen_mod_rs(grpc_out_dir, &grpc_proto_input_files, true);
109 }
110