Files
netdesk/native/viewer/build.rs
T

75 lines
3.1 KiB
Rust

//! Build script for the NetDesk native viewer.
//!
//! Embeds the NetDesk application icon (`assets/icon.ico`, multi-size) into the
//! Windows executable so Explorer, the taskbar and Alt-Tab all show the branded
//! green NetDesk mark. On the `x86_64-pc-windows-gnu` toolchain used for the
//! portable build, the resource is compiled with `windres` (shipped in the
//! MinGW bin dir that is on `PATH` during the workflow build) into a COFF object
//! which is then forced onto the final binary link line. No extra crates are
//! required — this keeps the build hermetic and offline-safe.
//!
//! If `windres` is unavailable the build still succeeds (a warning is emitted);
//! the runtime `ViewportBuilder::with_icon` call in `main.rs` still gives the
//! window + taskbar the icon, only the on-disk `.exe` file icon is skipped.
use std::path::PathBuf;
use std::process::Command;
fn main() {
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
// The .ico resource only applies to Windows PE binaries.
if target_os != "windows" {
return;
}
let manifest = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let ico = manifest.join("..").join("assets").join("icon.ico");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed={}", ico.display());
if !ico.exists() {
println!(
"cargo:warning=NetDesk icon not found at {} — exe icon not embedded",
ico.display()
);
return;
}
let out = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let rc_path = out.join("netdesk.rc");
let obj_path = out.join("netdesk_icon.o");
// windres wants forward slashes inside the quoted path (backslashes are
// treated as escapes in the .rc grammar). Resource id 1 => the app's
// default icon group, which is what Explorer/Shell pick up.
let ico_fwd = ico.display().to_string().replace('\\', "/");
if std::fs::write(&rc_path, format!("1 ICON \"{ico_fwd}\"\n")).is_err() {
println!("cargo:warning=could not write {} — exe icon not embedded", rc_path.display());
return;
}
match Command::new("windres")
.arg(&rc_path)
.args(["-O", "coff", "-o"])
.arg(&obj_path)
.status()
{
Ok(status) if status.success() => {
// -bins: attach the resource object only to binary targets, and force
// it onto the link line (resources have no referenced symbols, so a
// plain static lib could be dropped — a direct link-arg cannot).
println!("cargo:rustc-link-arg-bins={}", obj_path.display());
}
Ok(status) => {
println!(
"cargo:warning=windres exited with {status} — exe icon not embedded (window icon still set at runtime)"
);
}
Err(e) => {
println!(
"cargo:warning=windres not found ({e}) — exe icon not embedded (window icon still set at runtime)"
);
}
}
}