use std::env; use std::path::PathBuf; fn build_quickjs() { let libdir_path = PathBuf::from("quickjs") .canonicalize() .expect("cannot canonicalize path"); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let quickjs_path = out_path.join("quickjs"); for path in walkdir::WalkDir::new(&libdir_path).into_iter() { let path = path.expect("Error walking quickjs directory"); if path.file_type().is_dir() { continue; } let path = path.into_path(); if let Some(ext) = path.extension() { if ext == "c" || ext == "h" { println!("cargo:rerun-if-changed={}", path.display()); } } let relative_path = path.strip_prefix(&libdir_path).unwrap(); let output_file_path = quickjs_path.join(relative_path); if let Some(parent) = output_file_path.parent() { std::fs::create_dir_all(&parent).expect(&format!( "Unable to create output directory {}", parent.display() )); } std::fs::copy(&path, &output_file_path).expect(&format!( "Unable to copy from {} to {}", path.display(), output_file_path.display() )); } let output = std::process::Command::new("make") .arg("libquickjs.a") .current_dir(&quickjs_path) .output() .expect("could not spawn `make`"); if !output.status.success() { eprintln!("Failed to build quickjs: {}", output.status); if let Ok(out) = std::str::from_utf8(&output.stdout) { eprintln!("stdout from `make`:"); eprintln!("{}", out); } else { eprintln!("<>"); } if let Ok(out) = std::str::from_utf8(&output.stderr) { eprintln!("stderr from `make`:"); eprintln!("{}", out); } else { eprintln!("<>"); } panic!("could not build quickjs"); } println!("cargo:rustc-link-search={}", quickjs_path.to_str().unwrap()); println!("cargo:rustc-link-lib=static=quickjs"); } fn build_static_functions() { println!("cargo:rerun-if-changed=static-functions.c"); cc::Build::new() .files(&["static-functions.c"]) .flag_if_supported("-Wno-unused-parameter") .compile("static-functions"); println!("cargo:rustc-link-lib=static=static-functions"); } fn generate_bindings() { println!("cargo:rerun-if-changed=wrapper.h"); let bindings = bindgen::Builder::default() .header("wrapper.h") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() .expect("Unable to generate bindings"); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); } fn main() { build_quickjs(); build_static_functions(); generate_bindings(); }