extern crate bindgen;
extern crate fs_extra;
extern crate autotools;
use autotools::Config;
use std::env;
use std::path::PathBuf;
use std::process::Command;
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let mut libunwind_path = PathBuf::from(env::var("OUT_DIR").unwrap());
libunwind_path.push("libunwind");
let project_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let _e = fs_extra::dir::create(libunwind_path.clone(),true);
let options = fs_extra::dir::CopyOptions::new();
fs_extra::dir::copy(project_dir.join("libunwind"), out_dir.clone(), &options).unwrap();
let target = env::var("TARGET").unwrap();
let host = env::var("HOST").unwrap();
let link_lib_arch = match target.as_str() {
"x86_64-unknown-linux-gnu"| "x86_64-unknown-linux-musl" => "x86_64",
"i686-unknown-linux-gnu"|"i586-unknown-linux-gnu" => "x86",
"arm-unknown-linux-gnueabihf" => "arm",
_ => ""
};
if link_lib_arch.is_empty() {
println!("cargo:warning=target {} is unsupported",target);
return;
}
if link_lib_arch == "x86" || link_lib_arch == "arm " {
let _autogen = Command::new("sh").current_dir(&libunwind_path)
.arg("-c")
.arg(format!("autoreconf --force --install --verbose {}",&libunwind_path.to_str().unwrap()))
.output()
.expect("failed to run autoreconf, do you have the autotools installed?");
let mut dst = Config::new(&libunwind_path);
if !env::var_os("CARGO_FEATURE_PTRACE").is_some() {
dst.disable("ptrace", None);
} else {
println!("cargo:warning=ptrace-on");
dst.enable("ptrace", None);
}
if link_lib_arch == "x86" && host.contains("x86_64") {
dst.cflag("-m32")
.target(&target)
.host(&target)
.disable("documentation", None)
.disable("tests", None)
.enable_shared();
} else if link_lib_arch == "arm" && host.contains("x86_64") {
dst.env("CC","arm-linux-gnueabihf-gcc")
.target(&target)
.host(&target)
.disable("documentation", None)
.disable("tests", None)
.enable_shared();
}
else {
dst.disable("documentation", None).disable("tests", None).enable_shared().enable_static();
}
let dst = dst.build();
println!("cargo:rustc-link-search={}/lib", dst.display());
}
if target.contains("musl") {
println!("cargo:rustc-link-search=/usr/lib/x86_64-linux-gnu");
println!("cargo:rustc-link-lib=static=lzma");
println!("cargo:rustc-link-lib=static=unwind-{}",link_lib_arch);
println!("cargo:rustc-link-lib=static=unwind");
println!("cargo:rustc-link-lib=static=unwind-coredump");
if env::var_os("CARGO_FEATURE_PTRACE").is_some() {
println!("cargo:rustc-link-lib=static=unwind-ptrace");
}
} else {
println!("cargo:rustc-link-lib=unwind-{}",link_lib_arch);
println!("cargo:rustc-link-lib=unwind");
println!("cargo:rustc-link-lib=unwind-coredump");
if env::var_os("CARGO_FEATURE_PTRACE").is_some() {
println!("cargo:rustc-link-lib=unwind-ptrace");
}
}
let wrapper = if link_lib_arch == "arm" && host.contains("x86_64") {
"wrapper-arm.h"
} else {
"wrapper.h"
};
let bindings = match link_lib_arch {
"x86" => {
bindgen::Builder::default()
.header(project_dir.join(wrapper).to_str().unwrap())
.clang_arg("-Ilibunwind/include")
.blacklist_function("_Ux86_.*")
},
"arm" => {
bindgen::Builder::default()
.header(project_dir.join(wrapper).to_str().unwrap())
.clang_arg("-Ilibunwind/include")
.blacklist_function("_Uarm_.*")
},
_=> {
bindgen::Builder::default()
.header(project_dir.join(wrapper).to_str().unwrap())
.clang_arg("-Ilibunwind/include")
.blacklist_function("_Ux86_64_.*")
}
};
let bindings = if !env::var_os("CARGO_FEATURE_PTRACE").is_some() {
bindings.blacklist_function("_UPT_.*").blacklist_item("_UPT_.*")
} else {
bindings
};
let bindings = bindings.generate().expect("Unable to generate bindings");
bindings
.write_to_file(out_dir.join("bindings.rs"))
.expect("Couldn't write bindings!");
}