xref: /aosp_15_r20/external/uwb/src/rust/uwb_core/build.rs (revision e0df40009cb5d71e642272d38ba1bb7ffccfce41)
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