extern crate cc;
extern crate fs_extra;
extern crate metadeps;
use std::env;
#[cfg(not(feature = "build-cmake"))]
use std::ffi::OsString;
use std::fs;
use std::path::PathBuf;
#[cfg(not(feature = "build-cmake"))]
use std::process::Command;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=c-ares");
if metadeps::probe().is_ok() {
return;
}
let outdir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let build = outdir.join("build");
let _ = fs::remove_dir_all(&build);
fs::create_dir(&build).unwrap();
let c_ares_dir = outdir.join("c-ares");
let _ = fs::remove_dir_all(&c_ares_dir);
let copy_options = fs_extra::dir::CopyOptions::new();
let src = env::current_dir().unwrap().join("c-ares");
fs_extra::dir::copy(&src, &outdir, ©_options).unwrap();
compile();
}
#[cfg(feature = "build-cmake")]
fn compile() {
let outdir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let c_ares_dir = outdir.join("c-ares");
let dst = cmake::Config::new(c_ares_dir)
.define("CARES_STATIC", "ON")
.define("CARES_SHARED", "OFF")
.define("CARES_BUILD_TOOLS", "OFF")
.define("CMAKE_INSTALL_LIBDIR", "lib")
.build();
println!("cargo:rustc-link-search={}/lib", dst.display());
println!("cargo:rustc-link-lib=static=cares");
}
#[cfg(not(feature = "build-cmake"))]
fn run(cmd: &mut Command) {
println!("running: {:?}", cmd);
match cmd.status() {
Ok(t) => assert!(t.success()),
Err(e) => panic!("{} return the error {}", stringify!($e), e),
}
}
#[cfg(not(feature = "build-cmake"))]
fn make() -> &'static str {
if cfg!(target_os = "freebsd") {
"gmake"
} else {
"make"
}
}
#[cfg(not(feature = "build-cmake"))]
fn nmake(target: &str) -> Command {
let mut cmd = cc::windows_registry::find(target, "nmake.exe").unwrap();
cmd.env_remove("MAKEFLAGS").env_remove("MFLAGS");
cmd
}
#[cfg(not(feature = "build-cmake"))]
fn compile() {
let target = env::var("TARGET").unwrap();
if target.contains("msvc") {
build_msvc(&target);
return;
}
let outdir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let c_ares_dir = outdir.join("c-ares");
let build = outdir.join("build");
run(Command::new("sh").current_dir(&c_ares_dir).arg("buildconf"));
let cfg = cc::Build::new();
let compiler = cfg.get_compiler();
let mut cflags = OsString::new();
for arg in compiler.args() {
cflags.push(arg);
cflags.push(" ");
}
let mut cmd = Command::new("sh");
cmd.env("CFLAGS", &cflags)
.env("CC", compiler.path())
.current_dir(&build)
.arg(format!("{}", c_ares_dir.join("configure").display()))
.arg("--enable-static")
.arg("--disable-shared")
.arg("--enable-optimize")
.arg("--disable-debug")
.arg("--disable-tests")
.arg(format!("--prefix={}", outdir.display()));
let host = env::var("HOST").unwrap();
if target != host && (!target.contains("windows") || !host.contains("windows")) {
if target.contains("windows") {
cmd.arg(format!("--host={}", host));
cmd.arg(format!("--target={}", target));
} else {
cmd.arg(format!("--build={}", host));
cmd.arg(format!("--host={}", target));
}
}
run(&mut cmd);
run(Command::new(make())
.arg(format!("-j{}", env::var("NUM_JOBS").unwrap()))
.current_dir(&build));
println!("cargo:rustc-link-search={}/src/lib/.libs", build.display());
println!("cargo:rustc-link-lib=static=cares");
}
#[cfg(not(feature = "build-cmake"))]
fn build_msvc(target: &str) {
let outdir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let c_ares_dir = outdir.join("c-ares");
run(Command::new("cmd")
.current_dir(&c_ares_dir)
.arg("/c")
.arg("buildconf.bat"));
let mut cmd = nmake(target);
cmd.current_dir(&c_ares_dir);
cmd.args(&["/f", "Makefile.msvc", "CFG=lib-release", "c-ares"]);
run(&mut cmd);
let build = outdir.join("build");
let mut cmd = nmake(target);
cmd.current_dir(&c_ares_dir);
cmd.args(&["/f", "Makefile.msvc", "/a", "CFG=lib-release", "install"]);
cmd.env("INSTALL_DIR", format!("{}", build.display()));
run(&mut cmd);
println!("cargo:rustc-link-search={}/lib", build.display());
println!("cargo:rustc-link-lib=iphlpapi");
println!("cargo:rustc-link-lib=static=libcares");
}