1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use std::fs::File;
16 use std::io::Write;
17 use std::path::PathBuf;
18
19 /// Generate the protobuf bindings inside the uwb_core library.
20 ///
21 /// The protobuf are mainly used to represent the elements of uwb_uci_packets. If we use
22 /// Android's rust_protobuf build target to split the protobuf bindings to a dedicated crate, then
23 /// we cannot implement the conversion trait (i.e. std::convert::From) between the protobuf
24 /// bindings and the uwb_uci_packets's elements due to Rust's orphan rule.
generate_proto_bindings()25 fn generate_proto_bindings() {
26 let out_dir = std::env::var_os("OUT_DIR").unwrap();
27
28 // Generate the protobuf bindings to "${OUT_DIR}/uwb_service.rs".
29 protoc_rust::Codegen::new()
30 .out_dir(&out_dir)
31 .input("./protos/uwb_service.proto")
32 .run()
33 .expect("Running protoc failed.");
34
35 // Including the protobuf bindings directly hits the issue:
36 // "error: an inner attribute is not permitted in this context".
37 //
38 // To workaround this, first we create the file "${OUT_DIR}/proto_bindings.rs" that contains
39 // ```
40 // #[path = "${OUT_DIR}/uwb_service.rs"]
41 // pub mod bindings;
42 // ```
43 //
44 // Then include the generated file at proto.rs by:
45 // ```
46 // include!(concat!(env!("OUT_DIR"), "/proto_bindings.rs"));
47 // ```
48 let file_path = PathBuf::from(&out_dir).join("proto_bindings.rs");
49 let file = File::create(file_path).expect("Failed to create the generated file");
50 writeln!(&file, "#[path = \"{}/uwb_service.rs\"]", out_dir.to_str().unwrap())
51 .expect("Failed to write to the generated file");
52 writeln!(&file, "pub mod bindings;").expect("Failed to write to the generated file");
53 }
54
main()55 fn main() {
56 if std::env::var("CARGO_FEATURE_PROTO") == Ok("1".to_string()) {
57 generate_proto_bindings();
58 }
59 }
60