use std::{env, process};
use std::path::PathBuf;
macro_rules! cmd(
($name:expr) => (process::Command::new($name));
);
macro_rules! get(
($name:expr) => (env::var($name).unwrap());
);
macro_rules! run(
($command:expr) => (
assert!($command.stdout(process::Stdio::inherit())
.stderr(process::Stdio::inherit())
.status().unwrap().success());
);
);
macro_rules! link(
($kind:expr, $name:expr) => (
println!("cargo:rustc-link-lib={}={}", $kind, $name)
);
);
macro_rules! look(
($path:expr) => (
println!("cargo:rustc-link-search={}", $path)
);
);
fn main() {
let ssh = require("libssh2", None);
require("openssl", Some("-lssl -lcrypto"));
require("zlib", Some("-lz"));
if get!("TARGET").contains("apple") {
link!("dylib", "iconv");
}
let from = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join("build").join("libgit2");
let cmake = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join("build").join("cmake");
let into = PathBuf::from(&get!("OUT_DIR"));
run!(cmd!("cmake").current_dir(&into)
.arg(&from)
.arg("-DBUILD_CLAR=OFF")
.arg("-DBUILD_EXAMPLES=OFF")
.arg("-DBUILD_SHARED_LIBS=OFF")
.arg("-DCMAKE_C_FLAGS=-fPIC")
.arg("-DTHREADSAFE=ON")
.arg(&format!("-DCMAKE_MODULE_PATH={}", cmake.display()))
.arg(&format!("-DUSE_SSH={}", if ssh { "ON" } else { "OFF" })));
run!(cmd!("make").current_dir(&into).arg(&format!("-j{}", get!("NUM_JOBS"))));
look!(into.display());
link!("static", "git2");
}
fn require(name: &str, fallback: Option<&str>) -> bool {
macro_rules! rescue(
($fallback:expr) => ({
match $fallback {
Some(output) => instruct(output),
None => {},
}
return false;
});
);
let result = match cmd!("pkg-config").arg("--libs").arg(name).output() {
Ok(result) => result,
Err(_) => rescue!(fallback),
};
if !result.status.success() {
rescue!(fallback);
}
instruct(std::str::from_utf8(&result.stdout).unwrap());
true
}
fn instruct(output: &str) {
for chunk in output.split(' ') {
if chunk.starts_with("-l") {
link!("dylib", &chunk[2..]);
} else if chunk.starts_with("-L") {
look!(&chunk[2..]);
}
}
}