libyal_rs_common_build/
lib.rs

1#[cfg(not(target_os = "windows"))]
2mod posix;
3
4#[cfg(not(target_os = "windows"))]
5pub use crate::posix::{build_lib, sync_libs};
6
7#[cfg(target_os = "windows")]
8mod windows;
9
10#[cfg(target_os = "windows")]
11pub use crate::windows::{build_lib, sync_libs};
12
13use fs_extra::dir::{copy, CopyOptions};
14use rand::distributions::Alphanumeric;
15use rand::{thread_rng, Rng};
16use std::env;
17use std::fs::{create_dir, create_dir_all};
18use std::path::PathBuf;
19
20/// Sync dependencies and build the lib.
21/// See `build_lib` for more.
22pub fn sync_and_build_lib(lib_path: PathBuf, shared: bool) -> PathBuf {
23    sync_libs(&lib_path);
24
25    build_lib(lib_path, shared)
26}
27
28/// Find the library (based on env var or using the local submodule),
29/// copy it to the output folder and return the copied folder's path.
30pub fn get_lib_and_copy_to_out_dir(lib_name: &str) -> PathBuf {
31    let lib_path =
32        if let Ok(local_install) = env::var(format!("{}_LIBPATH", lib_name.to_uppercase())) {
33            PathBuf::from(local_install)
34        } else {
35            // For each `-sys` package, we expect the lib to be next to the Cargo.toml file.
36            PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join(lib_name)
37        };
38
39    let rand_folder_name: String = thread_rng().sample_iter(&Alphanumeric).take(6).collect();
40
41    let build_out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
42
43    // We have to use a random build dir because multiple builds of the same lib might happen at the same time.
44    let random_build_dir = build_out_dir.join(rand_folder_name);
45
46    create_dir_all(&random_build_dir).unwrap();
47
48    let copied_lib_path = random_build_dir.join(lib_name);
49    let _ = std::fs::remove_dir_all(&copied_lib_path);
50
51    copy(&lib_path, &random_build_dir, &CopyOptions::new()).expect(&format!(
52        "Error while copying sources from {:?} to `OUT_DIR` {:?}",
53        &lib_path, &random_build_dir
54    ));
55
56    copied_lib_path
57}
58
59pub fn generate_bindings(include_folder_path: &PathBuf, header_file_name: &str) {
60    // The bindgen::Builder is the main entry point
61    // to bindgen, and lets you build up options for
62    // the resulting bindings.
63    let bindings = bindgen::Builder::default()
64        // The input header we would like to generate
65        // bindings for.
66        .clang_args(&[format!("-I{}", include_folder_path.to_string_lossy())])
67        .header(header_file_name)
68        // Finish the builder and generate the bindings.
69        .generate()
70        // Unwrap the Result and panic on failure.
71        .expect("Unable to generate bindings");
72
73    // Write the bindings to the $OUT_DIR/bindings.rs file.
74    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
75
76    bindings
77        .write_to_file(out_path.join("bindings.rs"))
78        .expect("Couldn't write bindings!");
79}