diff --git a/Cargo.lock b/Cargo.lock index cd755e8..8296b07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1379,7 +1379,6 @@ dependencies = [ "ghostty-inspector", "ghostty-os", "ghostty-vt", - "glib-build-tools", "glow", "gtk4", "gtk4-layer-shell", @@ -1856,12 +1855,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "glib-build-tools" -version = "0.22.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9871f38b67853c358b8190f77b9f878eb27d933a950f1045b244c4559a9f5f0" - [[package]] name = "glib-macros" version = "0.22.9" diff --git a/crates/ghostty-apprt-gtk/Cargo.toml b/crates/ghostty-apprt-gtk/Cargo.toml index 288fbd7..21e7c2a 100644 --- a/crates/ghostty-apprt-gtk/Cargo.toml +++ b/crates/ghostty-apprt-gtk/Cargo.toml @@ -46,9 +46,6 @@ dear-imgui-glow = "0.19" glow = "0.18" wayland-sys = { version = "0.31.11", features = ["client", "dlopen"] } -[build-dependencies] -glib-build-tools = "0.22" - [dev-dependencies] env_logger = "0.11" diff --git a/crates/ghostty-apprt-gtk/build.rs b/crates/ghostty-apprt-gtk/build.rs index d8a41fe..13c310e 100644 --- a/crates/ghostty-apprt-gtk/build.rs +++ b/crates/ghostty-apprt-gtk/build.rs @@ -73,9 +73,12 @@ fn main() { // neither blueprint-compiler nor glib-compile-resources (Zig: // `GhosttyDist.Resource` for `ghostty_resources.{c,h}`). As in Zig, it is // never used in a git checkout. - println!("cargo:rerun-if-changed=dist/ghostty.gresource"); let prebuilt = manifest.join("dist/ghostty.gresource"); if prebuilt.is_file() && !manifest.join("../../.git").exists() { + // Watch the bundle only when it is an input. In a checkout it is + // normally absent, and watching a missing file forces every build + // to recompile the resources and all dependent crates. + println!("cargo:rerun-if-changed=dist/ghostty.gresource"); std::fs::copy(&prebuilt, out.join("ghostty.gresource")).unwrap(); return; } @@ -119,10 +122,24 @@ fn main() { let xml_path = out.join("ghostty.gresource.xml"); std::fs::write(&xml_path, xml).unwrap(); - glib_build_tools::compile_resources( - &[out.as_path(), res.as_path()], - xml_path.to_str().unwrap(), - "ghostty.gresource", + // glib-build-tools also watches the generated XML and UI files. Their + // timestamps change during this script, invalidating the next build. + // All actual inputs are already covered by the `resources` watch above. + let compiled = Command::new("glib-compile-resources") + .arg("--sourcedir") + .arg(&out) + .arg("--sourcedir") + .arg(&res) + .arg("--target") + .arg(out.join("ghostty.gresource")) + .arg(&xml_path) + .output() + .expect("`glib-compile-resources` is required to build ghostty-apprt-gtk"); + assert!( + compiled.status.success(), + "glib-compile-resources failed with {}:\n{}", + compiled.status, + String::from_utf8_lossy(&compiled.stderr) ); } diff --git a/crates/ghostty-build-info/build.rs b/crates/ghostty-build-info/build.rs index 93a89c0..d13471f 100644 --- a/crates/ghostty-build-info/build.rs +++ b/crates/ghostty-build-info/build.rs @@ -61,10 +61,13 @@ fn detect_version(manifest_dir: &Path) -> (String, Option) { let git_dir = PathBuf::from(git_dir); println!("cargo:rerun-if-changed={}", git_dir.join("HEAD").display()); println!("cargo:rerun-if-changed={}", git_dir.join("refs").display()); - println!( - "cargo:rerun-if-changed={}", - git_dir.join("packed-refs").display() - ); + // Missing watched paths make Cargo rerun this script on every build. + // Packing loose refs also changes `refs`, so it will register this + // optional file once Git creates it. + let packed_refs = git_dir.join("packed-refs"); + if packed_refs.is_file() { + println!("cargo:rerun-if-changed={}", packed_refs.display()); + } } let hash = run( "git", diff --git a/docs/rewrite/ARCHITECTURE.md b/docs/rewrite/ARCHITECTURE.md index 72faeea..5862419 100644 --- a/docs/rewrite/ARCHITECTURE.md +++ b/docs/rewrite/ARCHITECTURE.md @@ -70,6 +70,16 @@ ghostty-bench (benchmarks), ghostty-build-data (completions, man pages, syntax). Non-code: `resources/` (shell-integration, themes, terminfo), `dist/` (desktop integration), `po/` (translations), crate-local `res/`/`shaders/`/`resources/`. +Build inputs: `ghostty-build-info/build.rs` derives version metadata from the +workspace manifest and Git HEAD/refs, watching `packed-refs` only when it exists +(packing loose refs also changes the watched `refs` directory). The GTK build +script compiles `resources/` in checkouts and watches the optional +`dist/ghostty.gresource` bundle only when consuming it from a source tarball. +Missing optional files must not be emitted as Cargo `rerun-if-changed` inputs: +they invalidate every subsequent build and rebuild downstream crates. +GTK invokes `glib-compile-resources` directly so generated XML/UI files in +`OUT_DIR` are not watched as inputs; the `resources/` watch covers their sources. + ## Key design decisions 1. **Safe Rust by default.** Workspace lint `unsafe_code = "forbid"`. Crates