use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
fn main() {
let manifest_dir: PathBuf = PathBuf::from(env_var("CARGO_MANIFEST_DIR"));
let workspace_root: PathBuf = manifest_dir
.parent()
.and_then(|p: &Path| p.parent())
.map(Path::to_path_buf)
.unwrap_or(manifest_dir.clone());
let bridge_dir: PathBuf = workspace_root
.join("sdks")
.join("csharp")
.join("loaders")
.join("DotnetByteBridge");
let bridge_dll: PathBuf = bridge_dir
.join("bin")
.join("Release")
.join("net10.0")
.join("Polyplug.Loaders.DotnetByteBridge.dll");
println!(
"cargo:rerun-if-changed={}",
bridge_dir.join("ByteBridge.cs").to_string_lossy()
);
println!(
"cargo:rerun-if-changed={}",
bridge_dir
.join("Polyplug.Loaders.DotnetByteBridge.csproj")
.to_string_lossy()
);
let out_dir: PathBuf = PathBuf::from(env_var("OUT_DIR"));
let embed_path: PathBuf = out_dir.join("byte_bridge.dll");
let built: bool = build_bridge(&bridge_dir);
let bridge_available: bool = if built && bridge_dll.exists() {
match std::fs::copy(&bridge_dll, &embed_path) {
Ok(_) => true,
Err(e) => {
println!(
"cargo:warning=polyplug_dotnet: failed to stage byte-load bridge dll: {e}"
);
let _: Result<(), std::io::Error> = std::fs::write(&embed_path, []);
false
}
}
} else {
println!(
"cargo:warning=polyplug_dotnet: byte-load bridge unavailable (dotnet SDK missing or build failed); BundleSource::Bytes will be unsupported at runtime"
);
let _: Result<(), std::io::Error> = std::fs::write(&embed_path, []);
false
};
println!(
"cargo:rustc-env=POLYPLUG_DOTNET_BYTE_BRIDGE_DLL={}",
embed_path.to_string_lossy()
);
println!(
"cargo:rustc-env=POLYPLUG_DOTNET_BYTE_BRIDGE_AVAILABLE={}",
if bridge_available { "1" } else { "0" }
);
}
fn build_bridge(bridge_dir: &Path) -> bool {
let status: Result<std::process::ExitStatus, std::io::Error> = Command::new("dotnet")
.arg("build")
.arg("-c")
.arg("Release")
.arg("--nologo")
.arg(bridge_dir)
.status();
matches!(status, Ok(s) if s.success())
}
fn env_var(key: &str) -> String {
std::env::var(key).unwrap_or_default()
}