fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=scripts/pre-commit");
println!("cargo:rerun-if-changed=scripts/pre-push");
install_git_hooks();
if std::env::var("CARGO_FEATURE_ORACLE").is_ok() {
build_zopfli_oracle();
}
}
fn build_zopfli_oracle() {
let dir = "vendor/zopfli/src/zopfli";
if !std::path::Path::new(&format!("{}/zopfli.h", dir)).exists() {
panic!(
"[oracle] vendor/zopfli is not initialized — run `git submodule \
update --init vendor/zopfli` before `cargo test --features oracle`"
);
}
println!("cargo:rerun-if-changed={}", dir);
let mut build = cc::Build::new();
if cfg!(target_os = "macos") && std::path::Path::new("/usr/bin/ar").exists() {
build.archiver("/usr/bin/ar");
}
build
.include(dir)
.file(format!("{}/blocksplitter.c", dir))
.file(format!("{}/cache.c", dir))
.file(format!("{}/deflate.c", dir))
.file(format!("{}/gzip_container.c", dir))
.file(format!("{}/hash.c", dir))
.file(format!("{}/katajainen.c", dir))
.file(format!("{}/lz77.c", dir))
.file(format!("{}/squeeze.c", dir))
.file(format!("{}/tree.c", dir))
.file(format!("{}/util.c", dir))
.file(format!("{}/zlib_container.c", dir))
.file(format!("{}/zopfli_lib.c", dir))
.opt_level(2)
.warnings(false)
.compile("zopfli_oracle");
}
fn install_git_hooks() {
let git = std::path::Path::new(".git");
if !git.is_dir() {
return; }
install_hook("scripts/pre-commit", ".git/hooks/pre-commit");
install_hook("scripts/pre-push", ".git/hooks/pre-push");
}
fn install_hook(src: &str, dst: &str) {
let src = std::path::Path::new(src);
let dst = std::path::Path::new(dst);
if !src.exists() {
return;
}
let needs_update = !dst.exists() || {
let src_mtime = src.metadata().and_then(|m| m.modified()).ok();
let dst_mtime = dst.metadata().and_then(|m| m.modified()).ok();
src_mtime > dst_mtime
};
if needs_update {
let content = std::fs::read(src).unwrap_or_else(|_| panic!("read {}", src.display()));
std::fs::write(dst, &content).unwrap_or_else(|_| panic!("write {}", dst.display()));
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(dst, std::fs::Permissions::from_mode(0o755))
.unwrap_or_else(|_| panic!("chmod +x {}", dst.display()));
}
}
}