use std::env;
use std::fs;
use std::path::{Path, PathBuf};
const STATIC_LIB_NAME: &str = "sdc";
fn main() {
println!("cargo:rerun-if-env-changed=LIBSDC_PATH");
if env::var_os("CARGO_FEATURE_FFI_STC").is_none() {
return;
}
compile_libsdc();
}
fn compile_libsdc() {
let Some(root) = env::var_os("LIBSDC_PATH").map(PathBuf::from) else {
panic!(
"the \"ffi-stc\" feature is enabled but LIBSDC_PATH is not set.\n\
Point it at the directory holding the libsdc++ (DDE Lab Syndrome-Trellis Codes) \
sources, for example:\n \
PowerShell: $env:LIBSDC_PATH = \"C:\\\\src\\\\libsdc\"\n \
sh: export LIBSDC_PATH=/usr/local/src/libsdc\n\
Build without the feature to skip this step entirely."
);
};
if !root.is_dir() {
panic!(
"LIBSDC_PATH points at {}, which is not a directory.\n\
It must name the directory holding the libsdc++ sources.",
root.display()
);
}
let mut sources = Vec::new();
collect_cpp_sources(&root, &mut sources);
if sources.is_empty() {
panic!(
"no .cpp file was found under {}.\n\
LIBSDC_PATH must point at the libsdc++ sources themselves, not at an install prefix \
or an archive.",
root.display()
);
}
for source in &sources {
println!("cargo:rerun-if-changed={}", source.display());
}
cc::Build::new()
.cpp(true)
.include(&root)
.files(&sources)
.compile(STATIC_LIB_NAME);
}
fn collect_cpp_sources(directory: &Path, sources: &mut Vec<PathBuf>) {
let Ok(entries) = fs::read_dir(directory) else {
return;
};
let mut paths: Vec<PathBuf> = entries.flatten().map(|entry| entry.path()).collect();
paths.sort();
for path in paths {
if path.is_dir() {
collect_cpp_sources(&path, sources);
} else if path.extension().is_some_and(|ext| ext == "cpp") {
sources.push(path);
}
}
}