use std::env;
use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
use proxima_build::Timer;
use proxima_build::sizing::SizingSource;
#[allow(clippy::expect_used)]
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR set by cargo"));
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR set by cargo");
emit_batch_sizing(&out_dir, &manifest_dir);
emit_time_driver_binding(&out_dir);
}
#[allow(clippy::expect_used)]
fn emit_batch_sizing(out_dir: &Path, manifest_dir: &str) {
let source = SizingSource::load(manifest_dir, "proxima-core.toml", "PROXIMA_CORE")
.unwrap_or_else(|err| panic!("{err}"));
let resolve = |section: &str, key: &str| {
source
.resolve_int(section, key)
.unwrap_or_else(|err| panic!("{err}"))
};
let recv_slot_bytes = resolve("batch", "recv_slot_bytes");
let recv_initial_cap = resolve("batch", "recv_initial_cap");
let send_arena_initial_bytes = resolve("batch", "send_arena_initial_bytes");
let send_span_cap = resolve("batch", "send_span_cap");
let signal_waiters_inline_cap = resolve("signal", "waiters_inline_cap");
let generated = format!(
"// auto-generated by build.rs from proxima-core.toml — do not edit\n\
pub const BATCH_RECV_SLOT_BYTES: usize = {recv_slot_bytes};\n\
pub const BATCH_RECV_INITIAL_CAP: usize = {recv_initial_cap};\n\
pub const BATCH_SEND_ARENA_INITIAL_BYTES: usize = {send_arena_initial_bytes};\n\
pub const BATCH_SEND_SPAN_CAP: usize = {send_span_cap};\n\
pub const SIGNAL_WAITERS_INLINE_CAP: usize = {signal_waiters_inline_cap};\n"
);
let out_path = out_dir.join("proxima_core_sized.rs");
fs::write(&out_path, generated)
.unwrap_or_else(|err| panic!("write {}: {err}", out_path.display()));
}
#[allow(clippy::expect_used)]
fn emit_time_driver_binding(out_dir: &Path) {
println!("cargo:rustc-check-cfg=cfg(proxima_external_driver)");
let driver_path = if env::var("PROXIMA_PROFILE").is_ok() {
let resolved = proxima_build::resolve_profile().expect("resolve proxima profile");
let timer = resolved.profile.timer_kind().expect("resolve timer axis");
proxima_build::emit_timer_binding(&resolved).expect("emit proxima_time_bound_driver.rs");
proxima_build::emit_rerun_directives(&resolved);
timer.driver_path().to_string()
} else {
let driver = default_driver_path();
let path = out_dir.join("proxima_time_bound_driver.rs");
let mut file = fs::File::create(&path).expect("create proxima_time_bound_driver.rs");
write!(
file,
"// auto-generated default binding (PROXIMA_PROFILE unset)\n\
pub static BOUND_DRIVER: &dyn crate::time::Driver = &{driver};\n"
)
.expect("write default binding");
driver.to_string()
};
if driver_path == Timer::PrimeWheel.driver_path() {
println!("cargo:rustc-cfg=proxima_external_driver");
}
println!("cargo:rerun-if-env-changed=PROXIMA_PROFILE");
println!("cargo:rerun-if-env-changed=PROXIMA_TIMER");
}
fn default_driver_path() -> &'static str {
if env::var("CARGO_FEATURE_TIME_DRIVER_PRIME_WHEEL").is_ok() {
Timer::PrimeWheel.driver_path()
} else if env::var("CARGO_FEATURE_TIME_DRIVER_STD_THREAD").is_ok() {
Timer::StdThread.driver_path()
} else if env::var("CARGO_FEATURE_TIME_DRIVER_MOCK").is_ok() {
Timer::Mock.driver_path()
} else if env::var("CARGO_FEATURE_TIME_DRIVER_WASM").is_ok()
&& env::var("CARGO_CFG_TARGET_ARCH").as_deref() == Ok("wasm32")
{
"crate::time::drivers::wasm::DRIVER"
} else {
"crate::time::drivers::unbound::DRIVER"
}
}