xref: /libCEED/rust/libceed-sys/build.rs (revision 9df49d7ef0a77c7a3baec2427d8a7274681409b6)
1*9df49d7eSJed Brown extern crate bindgen;
2*9df49d7eSJed Brown extern crate pkg_config;
3*9df49d7eSJed Brown 
4*9df49d7eSJed Brown use std::path::PathBuf;
5*9df49d7eSJed Brown use std::process::Command;
6*9df49d7eSJed Brown 
7*9df49d7eSJed Brown fn main() {
8*9df49d7eSJed Brown     let out_dir = PathBuf::from(env("OUT_DIR").unwrap());
9*9df49d7eSJed Brown     let statik = env("CARGO_FEATURE_STATIC").is_some();
10*9df49d7eSJed Brown     let system = env("CARGO_FEATURE_SYSTEM").is_some();
11*9df49d7eSJed Brown 
12*9df49d7eSJed Brown     let ceed_pc = if system {
13*9df49d7eSJed Brown         "ceed".to_string()
14*9df49d7eSJed Brown     } else {
15*9df49d7eSJed Brown         // Install libceed.a or libceed.so to $OUT_DIR/lib
16*9df49d7eSJed Brown         let makeflags = env("CARGO_MAKEFLAGS").unwrap();
17*9df49d7eSJed Brown         let mut make = Command::new("make");
18*9df49d7eSJed Brown         make.arg("install")
19*9df49d7eSJed Brown             .arg(format!("prefix={}", out_dir.to_string_lossy()))
20*9df49d7eSJed Brown             .env("MAKEFLAGS", makeflags)
21*9df49d7eSJed Brown             .current_dir("c-src");
22*9df49d7eSJed Brown         if statik {
23*9df49d7eSJed Brown             make.arg("STATIC=1");
24*9df49d7eSJed Brown         }
25*9df49d7eSJed Brown         run(&mut make);
26*9df49d7eSJed Brown         out_dir
27*9df49d7eSJed Brown             .join("lib")
28*9df49d7eSJed Brown             .join("pkgconfig")
29*9df49d7eSJed Brown             .join("ceed.pc")
30*9df49d7eSJed Brown             .to_string_lossy()
31*9df49d7eSJed Brown             .into_owned()
32*9df49d7eSJed Brown     };
33*9df49d7eSJed Brown     pkg_config::Config::new()
34*9df49d7eSJed Brown         .statik(statik)
35*9df49d7eSJed Brown         .atleast_version("0.8")
36*9df49d7eSJed Brown         .probe(&ceed_pc)
37*9df49d7eSJed Brown         .unwrap();
38*9df49d7eSJed Brown 
39*9df49d7eSJed Brown     // Tell cargo to invalidate the built crate whenever the wrapper changes
40*9df49d7eSJed Brown     println!("cargo:rerun-if-changed=c-src/include/ceed/ceed.h");
41*9df49d7eSJed Brown     println!("cargo:rerun-if-changed=c-src/Makefile");
42*9df49d7eSJed Brown     println!("cargo:rerun-if-changed=c-src/config.mk");
43*9df49d7eSJed Brown 
44*9df49d7eSJed Brown     // The bindgen::Builder is the main entry point
45*9df49d7eSJed Brown     // to bindgen, and lets you build up options for
46*9df49d7eSJed Brown     // the resulting bindings.
47*9df49d7eSJed Brown     let bindings = bindgen::Builder::default()
48*9df49d7eSJed Brown         // The input header we would like to generate
49*9df49d7eSJed Brown         // bindings for.
50*9df49d7eSJed Brown         .header("c-src/include/ceed/ceed.h")
51*9df49d7eSJed Brown         .allowlist_function("Ceed.*")
52*9df49d7eSJed Brown         .allowlist_type("Ceed.*")
53*9df49d7eSJed Brown         .allowlist_var("Ceed.*")
54*9df49d7eSJed Brown         .allowlist_var("CEED_.*")
55*9df49d7eSJed Brown         // Don't chase recursive definitions of these system types
56*9df49d7eSJed Brown         .opaque_type("FILE")
57*9df49d7eSJed Brown         .opaque_type("va_list")
58*9df49d7eSJed Brown         // Accessing directly here, but perhaps should use libc crate
59*9df49d7eSJed Brown         .allowlist_function("fclose")
60*9df49d7eSJed Brown         .allowlist_function("open_memstream")
61*9df49d7eSJed Brown         // Tell cargo to not mangle the function names
62*9df49d7eSJed Brown         .trust_clang_mangling(false)
63*9df49d7eSJed Brown         // Tell cargo to invalidate the built crate whenever any of the
64*9df49d7eSJed Brown         // included header files changed.
65*9df49d7eSJed Brown         .parse_callbacks(Box::new(bindgen::CargoCallbacks))
66*9df49d7eSJed Brown         // Finish the builder and generate the bindings.
67*9df49d7eSJed Brown         .generate()
68*9df49d7eSJed Brown         // Unwrap the Result and panic on failure.
69*9df49d7eSJed Brown         .expect("Unable to generate bindings");
70*9df49d7eSJed Brown 
71*9df49d7eSJed Brown     // Write the bindings to the $OUT_DIR/bindings.rs file.
72*9df49d7eSJed Brown     bindings
73*9df49d7eSJed Brown         .write_to_file(out_dir.join("bindings.rs"))
74*9df49d7eSJed Brown         .expect("Couldn't write bindings!");
75*9df49d7eSJed Brown }
76*9df49d7eSJed Brown 
77*9df49d7eSJed Brown fn env(k: &str) -> Option<String> {
78*9df49d7eSJed Brown     std::env::var(k).ok()
79*9df49d7eSJed Brown }
80*9df49d7eSJed Brown 
81*9df49d7eSJed Brown fn run(command: &mut Command) {
82*9df49d7eSJed Brown     println!("Running: `{:?}`", command);
83*9df49d7eSJed Brown     assert!(command.status().unwrap().success());
84*9df49d7eSJed Brown }
85