• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use pkg_config::Config;
2 use std::env;
3 use std::path::PathBuf;
4 
main()5 fn main() {
6     // Re-run build if any of these change
7     println!("cargo:rerun-if-changed=bindings/wrapper.hpp");
8     println!("cargo:rerun-if-changed=build.rs");
9 
10     // We need to configure libchrome and libmodp_b64 settings as well
11     let libchrome = Config::new().probe("libchrome").unwrap();
12     let libchrome_paths = libchrome
13         .include_paths
14         .iter()
15         .map(|p| format!("-I{}", p.to_str().unwrap()))
16         .collect::<Vec<String>>();
17 
18     let search_root = env::var("CXX_ROOT_PATH").unwrap();
19     let paths = vec![
20         "/system/",
21         "/system/btcore",
22         "/system/include",
23         "/system/include/hardware",
24         "/system/types",
25     ];
26 
27     let bt_searches =
28         paths.iter().map(|tail| format!("-I{}{}", search_root, tail)).collect::<Vec<String>>();
29 
30     // Also re-run bindgen if anything in the C++ source changes. Unfortunately the Rust source
31     // files also reside in the same directory so any changes of Rust files (and other non-C files
32     // actually) will cause topshim to be rebuild. The TOPSHIM_SHOULD_REBUILD env variable is a
33     // development tool to speed up build that can be set to "no" if topshim is not expected to be
34     // change.
35     let topshim_should_rebuild = match env::var("TOPSHIM_SHOULD_REBUILD") {
36         Err(_) => true,
37         Ok(should_rebuild) => should_rebuild != "no",
38     };
39     if topshim_should_rebuild {
40         println!("cargo:rerun-if-changed={}{}", search_root, "/system/");
41     }
42 
43     // "-x" and "c++" must be separate due to a bug
44     let clang_args: Vec<&str> = vec!["-x", "c++", "-std=c++17"];
45 
46     // The bindgen::Builder is the main entry point
47     // to bindgen, and lets you build up options for
48     // the resulting bindings.
49     let bindings = bindgen::Builder::default()
50         .clang_args(bt_searches)
51         .clang_args(libchrome_paths)
52         .clang_args(clang_args)
53         .enable_cxx_namespaces()
54         .size_t_is_usize(true)
55         .blocklist_function("RawAddress_.*")
56         .blocklist_function(".*Uuid_.*")
57         .allowlist_type("(bt_|bthh_|btgatt_|btsdp|bluetooth_sdp|btsock_|bthf_|btrc_).*")
58         .allowlist_type("sock_connect_signal_t")
59         .allowlist_function("(bt_|bthh_|btgatt_|btsdp|osi_property_get).*")
60         .allowlist_function("hal_util_.*")
61         // We must opaque out std:: in order to prevent bindgen from choking
62         .opaque_type("std::.*")
63         // Whitelist std::string though because we use it a lot
64         .allowlist_type("std::string")
65         .rustfmt_bindings(true)
66         .derive_debug(true)
67         .derive_partialeq(true)
68         .derive_eq(true)
69         .derive_default(true)
70         .header("bindings/wrapper.hpp")
71         .generate()
72         .expect("Unable to generate bindings");
73 
74     // Write the bindings to the $OUT_DIR/bindings.rs file.
75     let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
76     bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings!");
77 }
78