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 Brownfn 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 Brownfn env(k: &str) -> Option<String> { 909df49d7eSJed Brown std::env::var(k).ok() 919df49d7eSJed Brown } 929df49d7eSJed Brown run(command: &mut Command)939df49d7eSJed Brownfn run(command: &mut Command) { 949df49d7eSJed Brown println!("Running: `{:?}`", command); 959df49d7eSJed Brown assert!(command.status().unwrap().success()); 969df49d7eSJed Brown } 97