extern crate cc;
use std::env;
use std::fs::File;
use std::path::PathBuf;
fn main() {
let target = env::var("TARGET").unwrap();
if !cfg!(feature = "backtrace-sys") || target.contains("msvc") || target.contains("emscripten") || target.contains("cloudabi") ||
target.contains("hermit") ||
target.contains("wasm32") ||
target.contains("fuchsia") ||
target.contains("uclibc")
{
println!("cargo:rustc-cfg=empty");
return;
}
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut build = cc::Build::new();
build
.include("src/libbacktrace")
.include(&out_dir)
.warnings(false)
.file("src/libbacktrace/alloc.c")
.file("src/libbacktrace/dwarf.c")
.file("src/libbacktrace/fileline.c")
.file("src/libbacktrace/posix.c")
.file("src/libbacktrace/sort.c")
.file("src/libbacktrace/state.c");
if target.contains("windows") || target.contains("darwin") {
build.file("src/libbacktrace/read.c");
} else {
build.file("src/libbacktrace/mmapio.c");
}
build.flag("-fvisibility=hidden");
if target.contains("darwin") {
build.file("src/libbacktrace/macho.c");
build.define("HAVE_MACH_O_DYLD_H", "1");
} else if target.contains("windows") {
build.file("src/libbacktrace/pecoff.c");
} else {
build.file("src/libbacktrace/elf.c");
let pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
if pointer_width == "64" {
build.define("BACKTRACE_ELF_SIZE", "64");
} else {
build.define("BACKTRACE_ELF_SIZE", "32");
}
}
File::create(out_dir.join("backtrace-supported.h")).unwrap();
build.define("BACKTRACE_SUPPORTED", "1");
build.define("BACKTRACE_USES_MALLOC", "1");
build.define("BACKTRACE_SUPPORTS_THREADS", "0");
build.define("BACKTRACE_SUPPORTS_DATA", "0");
File::create(out_dir.join("config.h")).unwrap();
if target.contains("android") {
maybe_enable_dl_iterate_phdr_android(&mut build);
} else if target.contains("dragonfly") || target.contains("freebsd") {
build.define("HAVE_DL_ITERATE_PHDR", "1");
build.define("HAVE_KERN_PROC", "1");
} else if target.contains("netbsd") {
build.define("HAVE_DL_ITERATE_PHDR", "1");
build.define("HAVE_KERN_PROC_ARGS", "1");
} else if !target.contains("apple-ios")
&& !target.contains("solaris")
&& !target.contains("redox")
&& !target.contains("haiku")
&& !target.contains("vxworks")
{
build.define("HAVE_DL_ITERATE_PHDR", "1");
}
build.define("_GNU_SOURCE", "1");
build.define("_LARGE_FILES", "1");
let syms = [
"backtrace_full",
"backtrace_dwarf_add",
"backtrace_initialize",
"backtrace_pcinfo",
"backtrace_syminfo",
"backtrace_get_view",
"backtrace_release_view",
"backtrace_alloc",
"backtrace_free",
"backtrace_vector_finish",
"backtrace_vector_grow",
"backtrace_vector_release",
"backtrace_close",
"backtrace_open",
"backtrace_print",
"backtrace_simple",
"backtrace_qsort",
"backtrace_create_state",
"backtrace_uncompress_zdebug",
"macho_get_view",
"macho_symbol_type_relevant",
"macho_get_commands",
"macho_try_dsym",
"macho_try_dwarf",
"macho_get_addr_range",
"macho_get_uuid",
"macho_add",
"macho_add_symtab",
"macho_file_to_host_u64",
"macho_file_to_host_u32",
"macho_file_to_host_u16",
];
let prefix = if cfg!(feature = "rustc-dep-of-std") {
println!("cargo:rustc-cfg=rdos");
"__rdos_"
} else {
println!("cargo:rustc-cfg=rbt");
"__rbt_"
};
for sym in syms.iter() {
build.define(sym, &format!("{}{}", prefix, sym)[..]);
}
build.compile("backtrace");
}
fn maybe_enable_dl_iterate_phdr_android(build: &mut cc::Build) {
let expansion = cc::Build::new().file("src/android-api.c").expand();
let expansion = match std::str::from_utf8(&expansion) {
Ok(s) => s,
Err(_) => return,
};
println!("expanded android version detection:\n{}", expansion);
let marker = "APIVERSION";
let i = match expansion.find(marker) {
Some(i) => i,
None => return,
};
let version = match expansion[i + marker.len() + 1..].split_whitespace().next() {
Some(s) => s,
None => return,
};
let version = match version.parse::<u32>() {
Ok(n) => n,
Err(_) => return,
};
if version >= 21 {
build.define("HAVE_DL_ITERATE_PHDR", "1");
}
}