use std::env;
#[cfg(unix)]
use std::ffi::OsString;
use std::fs;
#[cfg(unix)]
use std::path::Path;
use std::path::PathBuf;
use duct::cmd;
struct Metadata {
host: String,
target: String,
build_dir: PathBuf,
install_dir: PathBuf,
}
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let metadata = Metadata {
host: env::var("HOST").unwrap(),
target: env::var("TARGET").unwrap(),
build_dir: out_dir.join("build"),
install_dir: out_dir.join("install"),
};
fs::create_dir_all(&metadata.build_dir).expect("failed to create build dir");
fs::create_dir_all(&metadata.install_dir).expect("failed to create install dir");
build(&metadata);
println!("cargo:root={}", metadata.install_dir.display());
}
#[cfg(unix)]
fn build(metadata: &Metadata) {
{
let mut cppflags = env::var("CPPFLAGS").ok().unwrap_or_else(String::new);
let mut cflags = env::var("CFLAGS").ok().unwrap_or_else(String::new);
cflags += " -fPIC";
if let Ok(openssl_root) = env::var("DEP_OPENSSL_ROOT") {
cppflags += &format!(" -I{}", Path::new(&openssl_root).join("include").display());
}
let mut configure_args = vec![
format!("--prefix={}", metadata.install_dir.display()),
"--enable-static".into(),
"--disable-shared".into(),
#[cfg(feature = "nls")]
"--enable-nls".into(),
#[cfg(not(feature = "nls"))]
"--disable-nls".into(),
format!("CPPFLAGS={}", cppflags),
format!("CFLAGS={}", cflags),
];
if metadata.host != metadata.target {
configure_args.push(format!("--host={}", metadata.target));
}
let configure_path = Path::new("krb5").join("src").join("configure");
cmd(configure_path, &configure_args)
.dir(&metadata.build_dir)
.env_remove("CONFIG_SITE")
.run()
.expect("configure failed");
}
{
let mut make_flags = OsString::new();
let mut make_args = vec![];
if let Ok(s) = env::var("NUM_JOBS") {
match env::var_os("CARGO_MAKEFLAGS") {
Some(ref s)
if !(cfg!(windows)
|| cfg!(target_os = "openbsd")
|| cfg!(target_os = "netbsd")
|| cfg!(target_os = "freebsd")
|| cfg!(target_os = "bitrig")
|| cfg!(target_os = "dragonflybsd")) =>
{
make_flags = s.clone()
}
_ => make_args.push(format!("-j{}", s)),
}
}
cmd!("make", "install-mkdirs")
.dir(&metadata.build_dir)
.run()
.expect("install-mkdirs failed");
for dir in &[
"util/support",
"util/et",
"util/profile",
"util/verto",
"include",
"lib",
#[cfg(feature = "binaries")]
"plugins/kdb/db2",
#[cfg(feature = "binaries")]
"clients",
] {
for target in &["all", "install"] {
cmd!("make", target)
.dir(&metadata.build_dir.join(dir))
.env("MAKEFLAGS", &make_flags)
.run()
.unwrap_or_else(|_| panic!("make failed in {}", dir));
}
}
}
}
#[cfg(windows)]
fn build(metadata: &Metadata) {
if metadata.host != metadata.target {
panic!("cross-compilation on a Windows host is not supported");
}
let output = cmd!("robocopy", "krb5\\src", &metadata.build_dir, "/s", "/e")
.unchecked()
.run()
.unwrap_or_else(|e| panic!("copying source tree failed: {}", e));
if !matches!(output.status.code(), Some(0..=7)) {
panic!("copying source tree failed: {:?}", output);
}
let nmake = |args: &[&str]| {
cmd("nmake", args)
.dir(&metadata.build_dir)
.env("KRB_INSTALL_DIR", &metadata.install_dir)
};
nmake(&["-f", "Makefile.in", "prep-windows"])
.run()
.unwrap_or_else(|e| panic!("nmake prep failed: {}", e));
nmake(&[])
.run()
.unwrap_or_else(|e| panic!("nmake build failed: {}", e));
nmake(&["install"])
.run()
.unwrap_or_else(|e| panic!("nmake install failed: {}", e));
}