xref: /libCEED/rust/libceed-sys/build.rs (revision 60ef3feef7f5137af55ea7336903743d94ee71a8)
19df49d7eSJed Brown extern crate bindgen;
29df49d7eSJed Brown extern crate pkg_config;
39df49d7eSJed Brown 
4e7f21013SJed Brown use std::path::{Path, PathBuf};
59df49d7eSJed Brown use std::process::Command;
69df49d7eSJed Brown 
main()79df49d7eSJed Brown fn main() {
89df49d7eSJed Brown     let out_dir = PathBuf::from(env("OUT_DIR").unwrap());
99df49d7eSJed Brown     let statik = env("CARGO_FEATURE_STATIC").is_some();
109df49d7eSJed Brown     let system = env("CARGO_FEATURE_SYSTEM").is_some();
119df49d7eSJed Brown 
129df49d7eSJed Brown     let ceed_pc = if system {
139df49d7eSJed Brown         "ceed".to_string()
149df49d7eSJed Brown     } else {
159df49d7eSJed Brown         // Install libceed.a or libceed.so to $OUT_DIR/lib
169df49d7eSJed Brown         let makeflags = env("CARGO_MAKEFLAGS").unwrap();
179df49d7eSJed Brown         let mut make = Command::new("make");
189df49d7eSJed Brown         make.arg("install")
199df49d7eSJed Brown             .arg(format!("prefix={}", out_dir.to_string_lossy()))
20dfd5c3f2SJed Brown             .arg(format!(
21dfd5c3f2SJed Brown                 "OBJDIR={}",
22dfd5c3f2SJed Brown                 out_dir.join("build").to_string_lossy()
23dfd5c3f2SJed Brown             ))
24dfd5c3f2SJed Brown             .arg(format!(
25dfd5c3f2SJed Brown                 "LIBDIR={}",
26dfd5c3f2SJed Brown                 out_dir.join("build").join("lib").to_string_lossy()
27dfd5c3f2SJed Brown             ))
2880a9ef05SNatalie Beams             .arg("FC=") // Don't try to find Fortran (unused library build/install)
299df49d7eSJed Brown             .env("MAKEFLAGS", makeflags)
309df49d7eSJed Brown             .current_dir("c-src");
319df49d7eSJed Brown         if statik {
329df49d7eSJed Brown             make.arg("STATIC=1");
339df49d7eSJed Brown         }
349df49d7eSJed Brown         run(&mut make);
359df49d7eSJed Brown         out_dir
369df49d7eSJed Brown             .join("lib")
379df49d7eSJed Brown             .join("pkgconfig")
389df49d7eSJed Brown             .join("ceed.pc")
399df49d7eSJed Brown             .to_string_lossy()
409df49d7eSJed Brown             .into_owned()
419df49d7eSJed Brown     };
429df49d7eSJed Brown     pkg_config::Config::new()
439df49d7eSJed Brown         .statik(statik)
44*4018a20aSJeremy L Thompson         .atleast_version("0.12.0")
459df49d7eSJed Brown         .probe(&ceed_pc)
469df49d7eSJed Brown         .unwrap();
479df49d7eSJed Brown 
489df49d7eSJed Brown     // Tell cargo to invalidate the built crate whenever the wrapper changes
4949aac155SJeremy L Thompson     println!("cargo:rerun-if-changed=c-src/include/ceed.h");
50c9c2c079SJeremy L Thompson     println!("cargo:rerun-if-changed=c-src/include/ceed/types.h");
519df49d7eSJed Brown     println!("cargo:rerun-if-changed=c-src/Makefile");
52e7f21013SJed Brown     if Path::new("c-src/config.mk").is_file() {
539df49d7eSJed Brown         println!("cargo:rerun-if-changed=c-src/config.mk");
54e7f21013SJed Brown     }
559df49d7eSJed Brown 
569df49d7eSJed Brown     // The bindgen::Builder is the main entry point
579df49d7eSJed Brown     // to bindgen, and lets you build up options for
589df49d7eSJed Brown     // the resulting bindings.
599df49d7eSJed Brown     let bindings = bindgen::Builder::default()
609df49d7eSJed Brown         // The input header we would like to generate
619df49d7eSJed Brown         // bindings for.
6249aac155SJeremy L Thompson         .header("c-src/include/ceed.h")
639df49d7eSJed Brown         .allowlist_function("Ceed.*")
649df49d7eSJed Brown         .allowlist_type("Ceed.*")
659df49d7eSJed Brown         .allowlist_var("Ceed.*")
669df49d7eSJed Brown         .allowlist_var("CEED_.*")
679df49d7eSJed Brown         // Don't chase recursive definitions of these system types
689df49d7eSJed Brown         .opaque_type("FILE")
699df49d7eSJed Brown         .opaque_type("va_list")
709df49d7eSJed Brown         // Accessing directly here, but perhaps should use libc crate
719df49d7eSJed Brown         .allowlist_function("fclose")
729df49d7eSJed Brown         .allowlist_function("open_memstream")
739df49d7eSJed Brown         // Tell cargo to not mangle the function names
749df49d7eSJed Brown         .trust_clang_mangling(false)
759df49d7eSJed Brown         // Tell cargo to invalidate the built crate whenever any of the
769df49d7eSJed Brown         // included header files changed.
779df49d7eSJed Brown         .parse_callbacks(Box::new(bindgen::CargoCallbacks))
789df49d7eSJed Brown         // Finish the builder and generate the bindings.
799df49d7eSJed Brown         .generate()
809df49d7eSJed Brown         // Unwrap the Result and panic on failure.
819df49d7eSJed Brown         .expect("Unable to generate bindings");
829df49d7eSJed Brown 
839df49d7eSJed Brown     // Write the bindings to the $OUT_DIR/bindings.rs file.
849df49d7eSJed Brown     bindings
859df49d7eSJed Brown         .write_to_file(out_dir.join("bindings.rs"))
869df49d7eSJed Brown         .expect("Couldn't write bindings!");
879df49d7eSJed Brown }
889df49d7eSJed Brown 
env(k: &str) -> Option<String>899df49d7eSJed Brown fn env(k: &str) -> Option<String> {
909df49d7eSJed Brown     std::env::var(k).ok()
919df49d7eSJed Brown }
929df49d7eSJed Brown 
run(command: &mut Command)939df49d7eSJed Brown fn run(command: &mut Command) {
949df49d7eSJed Brown     println!("Running: `{:?}`", command);
959df49d7eSJed Brown     assert!(command.status().unwrap().success());
969df49d7eSJed Brown }
97