fn main() {
println!("cargo:rerun-if-changed=build.rs");
#[cfg(feature = "ssimulacra2")]
ssimulacra2::build();
}
#[cfg(feature = "ssimulacra2")]
mod ssimulacra2 {
use std::path::{Path, PathBuf};
use std::{env, fs};
const JXL_EXPORT_H: &str = "\
#ifndef JXL_EXPORT_H
#define JXL_EXPORT_H
#define JXL_EXPORT
#define JXL_NO_EXPORT
#define JXL_DEPRECATED
#define JXL_DEPRECATED_EXPORT
#define JXL_DEPRECATED_NO_EXPORT
#define JXL_EXPORT_DEPRECATED
#endif
";
const HIGHWAY_SOURCES: &[&str] = &[
"aligned_allocator.cc",
"nanobenchmark.cc",
"per_target.cc",
"print.cc",
"targets.cc",
"timer.cc",
];
pub fn build() {
let manifest = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
let third_party = manifest.join("third_party");
let s2_src = third_party.join("ssimulacra2/src");
let s2_lib = s2_src.join("lib");
let highway = third_party.join("highway");
let shim = third_party.join("shim");
assert_submodule(&s2_src.join("ssimulacra2.cc"), "ssimulacra2");
assert_submodule(&highway.join("hwy/highway.h"), "highway");
for path in [&third_party, &shim] {
println!("cargo:rerun-if-changed={}", path.display());
}
let export_dir = out.join("jxl");
fs::create_dir_all(&export_dir).expect("create OUT_DIR/jxl");
fs::write(export_dir.join("jxl_export.h"), JXL_EXPORT_H).expect("write jxl_export.h");
let mut jxl = base_build();
jxl.include(&s2_src) .include(s2_lib.join("include")) .include(&highway)
.include(&out) .include(&shim)
.define("JPEGXL_MAJOR_VERSION", "0")
.define("JPEGXL_MINOR_VERSION", "8")
.define("JPEGXL_PATCH_VERSION", "0")
.define("JXL_INTERNAL_LIBRARY_BUILD", None);
let lcms2 = pkg_config::Config::new()
.cargo_metadata(false)
.probe("lcms2")
.expect("lcms2 not found — install liblcms2-dev (Debian) / lcms2 (Homebrew)");
for dir in &lcms2.include_paths {
jxl.include(dir);
}
for src in jxl_cmake_sources(&s2_lib.join("jxl.cmake")) {
jxl.file(s2_lib.join(src));
}
jxl.file(s2_src.join("ssimulacra2.cc"));
jxl.file(shim.join("ssimulacra2_shim.cc"));
jxl.compile("ssimulacra2_shim");
let mut hwy = base_build();
hwy.include(&highway);
for src in HIGHWAY_SOURCES {
hwy.file(highway.join("hwy").join(src));
}
hwy.compile("hwy");
pkg_config::Config::new()
.probe("lcms2")
.expect("lcms2 not found — install liblcms2-dev (Debian) / lcms2 (Homebrew)");
}
fn base_build() -> cc::Build {
let mut build = cc::Build::new();
build
.cpp(true)
.std("c++11")
.flag_if_supported("-fno-rtti")
.warnings(false);
build
}
fn jxl_cmake_sources(cmake: &Path) -> Vec<String> {
let text =
fs::read_to_string(cmake).unwrap_or_else(|e| panic!("read {}: {e}", cmake.display()));
text.lines()
.map(str::trim)
.filter(|line| !line.starts_with('#'))
.filter(|line| line.ends_with(".cc"))
.map(str::to_owned)
.collect()
}
fn assert_submodule(probe: &Path, name: &str) {
assert!(
probe.exists(),
"third_party/{name} is not checked out (missing {}).\n\
Run: git submodule update --init --recursive",
probe.display(),
);
}
}