dinghy_build/
bindgen_macros.rs1#[macro_export]
5macro_rules! dinghy_bindgen {
6 () => {{
7 let bindgen = $crate::dinghy_bindgen_pre_0_49!();
8
9 if $crate::build::is_cross_compiling().expect("Couldn't determine if it is cross-compiling")
10 {
11 bindgen.detect_include_paths(false)
12 } else {
13 bindgen
14 }
15 }};
16}
17
18#[macro_export]
20macro_rules! dinghy_bindgen_pre_0_49 {
21 () => {{
22 use $crate::build::is_cross_compiling;
23 use $crate::build_env::sysroot_path;
24 use $crate::utils::path_to_str;
25 use $crate::{Result, Context};
26
27 fn apple_patch(builder: bindgen::Builder) -> Result<bindgen::Builder> {
28 if is_cross_compiling()? {
29 let target = env::var("TARGET")?;
30 if target.contains("apple") && target.contains("aarch64") {
31 return Ok(builder
37 .clang_arg(format!("-arch"))
38 .clang_arg(format!("arm64")));
39 }
40 }
41 Ok(builder)
42 }
43
44 fn libclang_path_patch(builder: bindgen::Builder) -> Result<bindgen::Builder> {
45 if is_cross_compiling()? {
46 if let Ok(libclang_path) = env::var("DINGHY_BUILD_LIBCLANG_PATH") {
47 env::set_var("LIBCLANG_PATH", libclang_path)
48 }
49 }
50 Ok(builder)
51 }
52
53 fn detect_toolchain(builder: bindgen::Builder) -> Result<bindgen::Builder> {
54 if is_cross_compiling()? {
55 let target = env::var("TARGET")?;
56 let builder = if let Ok(_) = env::var("TARGET_SYSROOT") {
57 builder.clang_arg(format!("--sysroot={}", path_to_str(&sysroot_path()?)?))
58 } else {
59 println!("cargo:warning=No Sysroot detected, assuming the target is baremetal. If you have a sysroot, you must either define a TARGET_SYSROOT or use Dinghy to build your project.");
60 builder
61 };
62 Ok(builder.clang_arg(format!("--target={}", target)))
63 } else {
64 Ok(builder)
65 }
66 }
67
68 fn include_gcc_system_headers(builder: bindgen::Builder) -> Result<bindgen::Builder> {
69 if is_cross_compiling()? {
70 let path = cc::Build::new()
73 .get_compiler()
74 .to_command()
75 .arg("--print-file-name=include")
76 .output()
77 .with_context(|| "Couldn't find target GCC executable.")
78 .and_then(|output| {
79 if output.status.success() {
80 Ok(String::from_utf8(output.stdout)?)
81 } else {
82 panic!("Couldn't determine target GCC include dir.")
83 }
84 })?;
85
86 Ok(builder.clang_arg("-isystem").clang_arg(path.trim()))
87 } else {
88 Ok(builder)
89 }
90 }
91
92 libclang_path_patch(
93 apple_patch(
94 include_gcc_system_headers(
95 detect_toolchain(bindgen::Builder::default().clang_arg("--verbose")).unwrap(),
96 )
97 .unwrap(),
98 )
99 .unwrap()
100 )
101 .unwrap()
102 }};
103}
104
105#[macro_export]
112macro_rules! generate_bindgen_bindings {
113 ($builder:expr) => {{
114 let out_path = env::var("OUT_DIR")
115 .map(PathBuf::from)
116 .expect("Couldn't convert OUT_DIR var into a path")
117 .join("bindings.rs");
118 $builder
119 .generate()
120 .expect("Unable to generate bindings")
121 .write_to_file(out_path)
122 .expect("Unable to write the bindings in the file")
123 }};
124}