extern crate bzip2;
extern crate pkg_config;
extern crate tar;
use bzip2::read::{BzDecoder};
use std::env;
use std::fs::{OpenOptions};
use std::io::{ErrorKind};
use std::path::{Path};
use std::process::{Command};
use tar::{Archive};
const BUNDLED_PCRE_VERSION: &'static str = "8.39";
fn main() {
if pkg_config::Config::new().atleast_version("8.20").find("libpcre").is_ok() {
return;
}
let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let out_dir = env::var("OUT_DIR").unwrap();
let ext_pathbuf = Path::new(&cargo_manifest_dir).join("ext");
let pcre_tbz2_pathbuf = ext_pathbuf.join(format!("pcre-{}.tar.bz2", BUNDLED_PCRE_VERSION));
let pcre_tbz2_f = OpenOptions::new().read(true).open(pcre_tbz2_pathbuf).unwrap();
let decompressor = BzDecoder::new(pcre_tbz2_f);
let mut archive = Archive::new(decompressor);
if !archive.unpack(&out_dir).is_ok() {
panic!("failed to extract the tarball");
}
let pcre_pathbuf = Path::new(&out_dir).join(format!("pcre-{}", BUNDLED_PCRE_VERSION));
if cfg!(unix) {
let mut cmd = Command::new("autoreconf");
cmd.current_dir(&pcre_pathbuf);
let status = match cmd.status() {
Err(ref e) if e.kind() == ErrorKind::NotFound => {
panic!("failed to execute `autoreconf`: {}. Are the Autotools installed?", e);
},
Err(e) => {
panic!("failed to execute `autoreconf`: {}", e);
},
Ok(status) => status
};
if !status.success() {
panic!("`autoreconf` did not run successfully.");
}
let mut cmd = Command::new("./configure");
cmd.arg("--with-pic");
cmd.arg("--disable-shared");
cmd.arg("--disable-cpp");
cmd.arg("--enable-jit");
cmd.arg("--enable-utf");
cmd.arg("--enable-unicode-properties");
cmd.arg(format!("--prefix={}", Path::new(&out_dir).display()));
cmd.current_dir(&pcre_pathbuf);
let status = match cmd.status() {
Err(e) => {
panic!("failed to execute `./configure`: {}", e);
},
Ok(status) => status
};
if !status.success() {
panic!("`./configure --with-pic ...` did not run successfully.");
}
let mut cmd = Command::new("make");
cmd.arg("install");
cmd.current_dir(&pcre_pathbuf);
let status = match cmd.status() {
Err(ref e) if e.kind() == ErrorKind::NotFound => {
panic!("failed to execute `make`: {}. Is GNU Make installed?", e);
},
Err(e) => {
panic!("failed to execute `make`: {}", e);
},
Ok(status) => status
};
if !status.success() {
panic!("`make install` did not run successfully.");
}
println!("cargo:rustc-link-search=native={}", Path::new(&out_dir).join("lib").as_path().display());
} else {
let mut cmd = Command::new("cmake");
cmd.arg(".");
cmd.arg("-DBUILD_SHARED_LIBS=OFF");
cmd.arg("-DPCRE_BUILD_PCRECPP=OFF");
cmd.arg("-DPCRE_BUILD_PCREGREP=OFF");
cmd.arg("-DPCRE_BUILD_TESTS=OFF");
cmd.arg("-DPCRE_BUILD_PCRE8=ON");
cmd.arg("-DPCRE_SUPPORT_JIT=ON");
cmd.arg("-DPCRE_SUPPORT_UTF=ON");
cmd.arg("-DPCRE_SUPPORT_UNICODE_PROPERTIES=ON");
cmd.current_dir(&pcre_pathbuf);
let status = match cmd.status() {
Err(ref e) if e.kind() == ErrorKind::NotFound => {
panic!("failed to execute `cmake`: {}. Is CMake installed?", e);
},
Err(e) => {
panic!("failed to execute `cmake`: {}", e);
},
Ok(status) => status
};
if !status.success() {
panic!("`cmake . -DBUILD_SHARED_LIBS=OFF ...` did not run successfully.");
}
let mut cmd = Command::new("cmake");
cmd.arg("--build").arg(".").current_dir(&pcre_pathbuf);
let status = match cmd.status() {
Err(ref e) if e.kind() == ErrorKind::NotFound => {
panic!("failed to execute `cmake`: {}. Is CMake installed?", e);
},
Err(e) => {
panic!("failed to execute `cmake`: {}", e);
},
Ok(status) => status
};
if !status.success() {
panic!("`cmake --build .` did not run successfully.");
}
println!("cargo:rustc-link-search=native={}", pcre_pathbuf.as_path().display());
}
println!("cargo:rustc-link-lib=static=pcre");
}