1 // Copyright 2024, Linaro Limited 2 // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> 3 // SPDX-License-Identifier: GPL-2.0-or-later 4 5 #[cfg(unix)] 6 use std::os::unix::fs::symlink as symlink_file; 7 #[cfg(windows)] 8 use std::os::windows::fs::symlink_file; 9 use std::{env, fs::remove_file, io::Result, path::Path}; 10 11 fn main() -> Result<()> { 12 let manifest_dir = env!("CARGO_MANIFEST_DIR"); 13 let file = if let Ok(root) = env::var("MESON_BUILD_ROOT") { 14 let sub = get_rust_subdir(manifest_dir).unwrap(); 15 format!("{root}/{sub}/bindings.inc.rs") 16 } else { 17 // Placing bindings.inc.rs in the source directory is supported 18 // but not documented or encouraged. 19 format!("{manifest_dir}/src/bindings.inc.rs") 20 }; 21 22 let file = Path::new(&file); 23 if !Path::new(&file).exists() { 24 panic!(concat!( 25 "\n", 26 " No generated C bindings found! Maybe you wanted one of\n", 27 " `make clippy`, `make rustfmt`, `make rustdoc`?\n", 28 "\n", 29 " For other uses of `cargo`, start a subshell with\n", 30 " `pyvenv/bin/meson devenv`, or point MESON_BUILD_ROOT to\n", 31 " the top of the build tree." 32 )); 33 } 34 35 let out_dir = env::var("OUT_DIR").unwrap(); 36 let dest_path = format!("{out_dir}/bindings.inc.rs"); 37 let dest_path = Path::new(&dest_path); 38 if dest_path.symlink_metadata().is_ok() { 39 remove_file(dest_path)?; 40 } 41 symlink_file(file, dest_path)?; 42 43 println!("cargo:rerun-if-changed=build.rs"); 44 Ok(()) 45 } 46 47 fn get_rust_subdir(path: &str) -> Option<&str> { 48 path.find("/rust").map(|index| &path[index + 1..]) 49 } 50