extern crate autotools;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
pub struct Artifacts {
include_dir: PathBuf,
lib_dir: PathBuf,
}
impl Artifacts {
pub fn print_cargo_metadata(&self) {
println!("cargo:include={}", self.include_dir.display());
println!("cargo:rustc-link-search=native={}", self.lib_dir.display());
for lib in &["onig", "jq"] {
println!("cargo:rustc-link-lib=static={}", lib);
}
}
pub fn include_dir(&self) -> &Path {
&self.include_dir
}
pub fn lib_dir(&self) -> &Path {
&self.lib_dir
}
}
pub fn build() -> Result<Artifacts, ()> {
let out_dir = env::var_os("OUT_DIR")
.map(PathBuf::from)
.expect("OUT_DIR not set");
for i in 1..=3 {
match run_autotools(&out_dir) {
Err(_) if i < 3 => {
eprintln!("Build experienced some sort of failure. Retrying ({}).", i)
}
Ok(artifacts) => return Ok(artifacts),
_ => (),
}
}
Err(())
}
fn run_autotools(out_dir: &Path) -> Result<Artifacts, ()> {
let sources_dir = out_dir.join("sources");
let modules_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("modules");
prepare_sources(&modules_dir, &sources_dir);
let worker = {
let out = out_dir.to_path_buf();
let root = sources_dir.join("jq");
std::thread::spawn(move || {
autotools::Config::new(&root)
.reconf("-fi")
.out_dir(&out)
.disable("maintainer-mode", None)
.with("oniguruma", Some("builtin"))
.make_args(vec!["LDFLAGS=-all-static".into(), "CFLAGS=-fPIC".into()])
.build();
})
};
match worker.join() {
Ok(_) => Ok(Artifacts {
lib_dir: out_dir.join("lib"),
include_dir: out_dir.join("include"),
}),
_ => Err(()),
}
}
fn cp_r(src: &Path, dst: &Path) {
for f in fs::read_dir(src).unwrap() {
let f = f.unwrap();
let path = f.path();
let name = path.file_name().unwrap();
let dst = dst.join(name);
if f.file_type().unwrap().is_dir() {
fs::create_dir_all(&dst).unwrap();
cp_r(&path, &dst);
} else {
let _ = fs::remove_file(&dst);
fs::copy(&path, &dst).unwrap();
}
}
}
fn prepare_sources(src: &Path, dst: &Path) {
if dst.exists() {
fs::remove_dir_all(dst).unwrap();
}
fs::create_dir_all(dst).unwrap();
cp_r(src, dst);
}