From 3f3f6680a52a75eca00c7c9f294b245c93828856 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Mon, 12 Oct 2026 08:14:02 +0200 Subject: [PATCH] feat(dist): website data, library installs, XCFramework, dist tarball Closes the remaining artifact rows of the final audit (docs/rewrite/notes/final-Z4.md): - webgen: config.mdx, actions.mdx, commands.mdx (byte-identical to Zig's webgen output once its missing stdout flush is added) - `just install-lib`: libghostty (+ ghostty.h, modulemap) and libghostty-vt with versioned symlinks, headers and libghostty-vt.pc - scripts/xcframework.sh: per-arch builds, lipo and xcodebuild -create-xcframework for GhosttyKit (dry-run verified only) - `just install` builds --profile production so the installed app id is com.mitchellh.ghostty; other profiles install the -debug id/name - `just update-translations`: xgettext/msgmerge pipeline; extracted msgids equal upstream's .pot (found and fixed an untranslated string in the child-exited banner) - `just dist` / `distcheck`: versioned source tarball with VERSION and a prebuilt GTK resource bundle - Windows: icon, version resource and DPI/common-controls manifest embedded via embed-resource, GUI subsystem Test Plan: - just install-lib /tmp/p release all && pkg-config --cflags \ --libs /tmp/p/share/pkgconfig/libghostty-vt.pc - just distcheck --- build.rs | 48 ++++-- crates/ghostty-build-data/src/lib.rs | 38 ++++ crates/ghostty-build-data/src/webdata.rs | 210 +++++++++++++++++++++++ dist/windows/ghostty.ico | Bin 0 -> 86258 bytes dist/windows/ghostty.manifest | 14 ++ dist/windows/ghostty.rc | 36 ++++ docs/rewrite/notes/final-Z4.md | 27 +++ justfile | 101 +++++++++-- scripts/dist.sh | 95 ++++++++++ scripts/install-lib.sh | 92 ++++++++++ scripts/update-translations.sh | 74 ++++++++ scripts/xcframework.sh | 83 +++++++++ 12 files changed, 795 insertions(+), 23 deletions(-) create mode 100644 crates/ghostty-build-data/src/webdata.rs create mode 100644 dist/windows/ghostty.ico create mode 100644 dist/windows/ghostty.manifest create mode 100644 dist/windows/ghostty.rc create mode 100644 docs/rewrite/notes/final-Z4.md create mode 100755 scripts/dist.sh create mode 100755 scripts/install-lib.sh create mode 100755 scripts/update-translations.sh create mode 100755 scripts/xcframework.sh diff --git a/build.rs b/build.rs index 4ce698d..3f87cff 100644 --- a/build.rs +++ b/build.rs @@ -1,16 +1,44 @@ -//! Link the final binary with lazy symbol binding. +//! Root build script. //! -//! Rust links executables with `-z now` (eager binding) by default. The GTK -//! apprt compiles in code for newer GTK/libadwaita API (e.g. the GTK 4.16 CSS -//! diagnostics) that is only ever called after a runtime `at_least` check, -//! exactly like the Zig build, which links GTK dynamically with lazy binding. -//! With eager binding the dynamic loader would refuse to start the program on -//! an older library that merely lacks such a symbol; with lazy binding the -//! symbol is only resolved if the guarded code actually runs. +//! * Linux: link the final binary with lazy symbol binding. Rust links +//! executables with `-z now` (eager binding) by default. The GTK apprt +//! compiles in code for newer GTK/libadwaita API (e.g. the GTK 4.16 CSS +//! diagnostics) that is only ever called after a runtime `at_least` check, +//! exactly like the Zig build, which links GTK dynamically with lazy +//! binding. With eager binding the dynamic loader would refuse to start the +//! program on an older library that merely lacks such a symbol; with lazy +//! binding the symbol is only resolved if the guarded code actually runs. +//! * Windows (Zig: `GhosttyExe.zig`): use the GUI subsystem and embed +//! `dist/windows/ghostty.rc` (icon, version resource and the manifest that +//! declares per-monitor DPI awareness and the common-controls v6 activation +//! context). fn main() { println!("cargo:rerun-if-changed=build.rs"); - if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") { - println!("cargo:rustc-link-arg-bins=-Wl,-z,lazy"); + match std::env::var("CARGO_CFG_TARGET_OS").as_deref() { + Ok("linux") => println!("cargo:rustc-link-arg-bins=-Wl,-z,lazy"), + Ok("windows") => windows(), + _ => {} } } + +fn windows() { + println!("cargo:rerun-if-changed=dist/windows/ghostty.rc"); + println!("cargo:rerun-if-changed=dist/windows/ghostty.ico"); + println!("cargo:rerun-if-changed=dist/windows/ghostty.manifest"); + + // `exe.subsystem = .Windows`. + if std::env::var("CARGO_CFG_TARGET_ENV").as_deref() == Ok("msvc") { + println!("cargo:rustc-link-arg-bins=/SUBSYSTEM:WINDOWS"); + println!("cargo:rustc-link-arg-bins=/ENTRY:mainCRTStartup"); + } else { + println!("cargo:rustc-link-arg-bins=-Wl,--subsystem,windows"); + } + + // `exe.addWin32ResourceFile(.{ .file = "dist/windows/ghostty.rc" })`. + // The resource is only linked into the binary targets, not the + // (nonexistent) library target of this package. + embed_resource::compile_for("dist/windows/ghostty.rc", ["ghostty"], embed_resource::NONE) + .manifest_required() + .expect("failed to embed the Windows resource file"); +} diff --git a/crates/ghostty-build-data/src/lib.rs b/crates/ghostty-build-data/src/lib.rs index e3fa2e6..ee5e2f3 100644 --- a/crates/ghostty-build-data/src/lib.rs +++ b/crates/ghostty-build-data/src/lib.rs @@ -15,6 +15,7 @@ pub mod fish; pub mod mdgen; pub mod sublime; pub mod vim; +pub mod webdata; pub mod zsh; #[allow(clippy::needless_raw_string_hashes)] @@ -43,6 +44,14 @@ pub enum Mode { Man1, /// `ghostty(5)` man page markdown (Zig: `mdgen_ghostty_5`). Man5, + /// Website `config.mdx` (Zig: `webgen_config`). + WebdataConfig, + /// Website `actions.mdx` (keybind actions; Zig: `webgen_actions`). + WebdataActions, + /// Website `commands.mdx` (CLI actions; Zig: `webgen_commands`). + WebdataCommands, + /// The Ghostty version string (embedded into source tarballs as `VERSION`). + Version, } impl Mode { @@ -58,6 +67,10 @@ impl Mode { ("terminfo", Mode::Terminfo), ("mdgen-ghostty-1", Mode::Man1), ("mdgen-ghostty-5", Mode::Man5), + ("webgen-config", Mode::WebdataConfig), + ("webgen-actions", Mode::WebdataActions), + ("webgen-commands", Mode::WebdataCommands), + ("version", Mode::Version), ]; /// Parse `+name` (Zig action syntax) or a bare `name`. @@ -82,6 +95,10 @@ impl Mode { Mode::Terminfo => ghostty_termio::terminfo::ghostty.encode_to_string(), Mode::Man1 => mdgen::ghostty_1(), Mode::Man5 => mdgen::ghostty_5(), + Mode::WebdataConfig => webdata::config_mdx(), + Mode::WebdataActions => webdata::actions_mdx(), + Mode::WebdataCommands => webdata::commands_mdx(), + Mode::Version => ghostty_cli::build_info::get().version_string.clone(), } } } @@ -174,6 +191,27 @@ mod tests { assert!(five.contains("**`new_split`**")); } + #[test] + fn webdata_has_frontmatter_and_sections() { + let config = webdata::config_mdx(); + assert!(config.starts_with( + "---\ntitle: Reference\ndescription: Reference of all Ghostty configuration options.\n" + )); + assert!(config.contains("organize these options.\n\n## `language`\n\n")); + assert!(config.contains("## `font-family`\n")); + assert!(!config.contains("## `_")); + // Callouts and indented code blocks are rewritten for the website. + assert!(config.contains("\n") || config.contains("\n")); + assert!(config.contains("```\n")); + let actions = webdata::actions_mdx(); + assert!(actions.starts_with("---\ntitle: Keybinding Action Reference\n")); + assert!(actions.contains("\n## `ignore`\nIgnore this key combination.\n")); + let commands = webdata::commands_mdx(); + assert!(commands.contains("## version\n")); + assert!(commands.contains("\n```\nghostty --version\n```\n\n")); + assert!(commands.contains("\n```\nghostty +list-fonts\n```\n\n")); + } + /// Every supported locale has a `.po` catalog and vice versa /// (Zig: `GhosttyI18n.zig` iterates `os/i18n_locales.zig`). #[test] diff --git a/crates/ghostty-build-data/src/webdata.rs b/crates/ghostty-build-data/src/webdata.rs new file mode 100644 index 0000000..31f97f7 --- /dev/null +++ b/crates/ghostty-build-data/src/webdata.rs @@ -0,0 +1,210 @@ +//! Website data generators (port of `build/GhosttyWebdata.zig` and +//! `build/webgen/main_{config,actions,commands}.zig`). They produce the +//! `config.mdx`, `actions.mdx` (keybind actions) and `commands.mdx` (CLI +//! actions) files installed to `share/ghostty/webdata/`. + +use ghostty_input::binding::ActionKey; + +use crate::config_fields; + +/// `webgen/main_config.zig`: the configuration reference. +#[must_use] +pub fn config_mdx() -> String { + #[derive(Clone, Copy, PartialEq, Eq)] + enum Block { + Text, + Code, + CalloutNote, + CalloutWarning, + } + + fn end_block(w: &mut String, block: Option) { + match block { + Some(Block::Code) => w.push_str("```\n"), + Some(Block::CalloutNote) => w.push_str("\n"), + Some(Block::CalloutWarning) => w.push_str("\n"), + Some(Block::Text) | None => {} + } + } + + fn starts_with_ignore_case(s: &str, prefix: &str) -> bool { + s.len() >= prefix.len() + && s.as_bytes()[..prefix.len()].eq_ignore_ascii_case(prefix.as_bytes()) + } + + let mut w = String::from( + "---\n\ +title: Reference\n\ +description: Reference of all Ghostty configuration options.\n\ +editOnGithubLink: https://github.com/ghostty-org/ghostty/edit/main/src/config/Config.zig\n\ +---\n\ +\n\ +This is a reference of all Ghostty configuration options. These\n\ +options are ordered roughly by how common they are to be used\n\ +and grouped with related options. I recommend utilizing your\n\ +browser's search functionality to find the option you're looking\n\ +for.\n\ +\n\ +In the future, we'll have a more user-friendly way to view and\n\ +organize these options.\n\ +\n", + ); + + let fields = config_fields(); + for (i, field) in fields.iter().enumerate() { + if field.help.is_empty() { + continue; + } + w.push_str("## `"); + w.push_str(field.name); + w.push_str("`\n"); + + // For all subsequent fields with no docs, they are grouped with the + // previous field. (Zig breaks at `_` fields; those are already + // filtered out of `config_fields`, which would otherwise leave a + // gap, so the group may only extend to the next raw field.) + for next in &fields[i + 1..] { + if !next.help.is_empty() { + break; + } + w.push_str("## `"); + w.push_str(next.name); + w.push_str("`\n"); + } + + w.push('\n'); + + let mut block: Option = None; + for s in field.help.split('\n') { + // Empty line resets our block. + if s.is_empty() { + end_block(&mut w, block); + block = None; + w.push('\n'); + continue; + } + + let first = block.is_none(); + if block.is_none() { + if s.starts_with(" ") { + block = Some(Block::Code); + w.push_str("```\n"); + } else if starts_with_ignore_case(s, "note:") { + block = Some(Block::CalloutNote); + w.push_str("\n"); + } else if starts_with_ignore_case(s, "warning:") { + block = Some(Block::CalloutWarning); + w.push_str("\n"); + } else { + block = Some(Block::Text); + } + } + + w.push_str(match block { + Some(Block::CalloutNote) if first => &s["note:".len()..], + Some(Block::CalloutWarning) if first => &s["warning:".len()..], + Some(Block::Code) => s.strip_prefix(" ").unwrap_or(s), + _ => s, + }); + w.push('\n'); + } + end_block(&mut w, block); + w.push('\n'); + } + w +} + +/// `webgen/main_actions.zig` (`input/helpgen_actions.zig`, markdown with +/// docs): the keybind action reference. +#[must_use] +pub fn actions_mdx() -> String { + let mut w = String::from( + "---\n\ +title: Keybinding Action Reference\n\ +description: Reference of all Ghostty keybinding actions.\n\ +editOnGithubLink: https://github.com/ghostty-org/ghostty/edit/main/src/input/Binding.zig\n\ +---\n\ +\n\ +This is a reference of all Ghostty keybinding actions.\n\ +\n", + ); + + // Doc comments are written below all related (consecutive undocumented) + // actions, so they are buffered until the next documented action. + let mut stream = String::new(); + for &key in ActionKey::ALL { + let name = key.name(); + if name.starts_with('_') { + continue; + } + let docs = key.help_string(); + let has_docs = !key.docs().is_empty(); + + if has_docs { + w.push_str(&stream); + w.push('\n'); + stream.clear(); + } + + w.push_str("## `"); + w.push_str(name); + w.push_str("`\n"); + + if has_docs { + let mut iter = docs.split('\n').peekable(); + while let Some(s) = iter.next() { + // If it is the last line and empty, then skip it. + if iter.peek().is_none() && s.is_empty() { + continue; + } + stream.push_str(s); + stream.push('\n'); + } + } + } + if !stream.is_empty() { + w.push_str(&stream); + } + w +} + +/// `webgen/main_commands.zig`: the CLI action reference. +#[must_use] +pub fn commands_mdx() -> String { + let mut w = String::from( + "---\n\ +title: Reference\n\ +description: Reference of all Ghostty action subcommands.\n\ +editOnGithubLink: https://github.com/ghostty-org/ghostty/tree/main/src/cli\n\ +---\n\ +Ghostty includes a number of utility actions that can be accessed as subcommands.\n\ +Actions provide utilities to work with config, list keybinds, list fonts, demo themes,\n\ +and debug.\n", + ); + + for &action in ghostty_cli::Action::ALL { + let name = action.name(); + w.push_str("## "); + w.push_str(name); + w.push('\n'); + + let help = action.help_text(); + if help.is_empty() { + continue; + } + for s in help.split('\n') { + w.push_str(s); + w.push('\n'); + } + w.push_str("\n```\n"); + match action { + ghostty_cli::Action::Help | ghostty_cli::Action::Version => { + w.push_str("ghostty --"); + } + _ => w.push_str("ghostty +"), + } + w.push_str(name); + w.push_str("\n```\n\n"); + } + w +} diff --git a/dist/windows/ghostty.ico b/dist/windows/ghostty.ico new file mode 100644 index 0000000000000000000000000000000000000000..1c5afc258c58e54477b3122ebce8837caf9030b2 GIT binary patch literal 86258 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 literal 0 HcmV?d00001 diff --git a/dist/windows/ghostty.manifest b/dist/windows/ghostty.manifest new file mode 100644 index 0000000..9a07906 --- /dev/null +++ b/dist/windows/ghostty.manifest @@ -0,0 +1,14 @@ + + + + + true/pm + PerMonitorV2 + + + + + + + + diff --git a/dist/windows/ghostty.rc b/dist/windows/ghostty.rc new file mode 100644 index 0000000..0f3d12f --- /dev/null +++ b/dist/windows/ghostty.rc @@ -0,0 +1,36 @@ +// LANG_NEUTRAL(0), SUBLANG_NEUTRAL(0) +LANGUAGE 0, 0 + +#define RT_MANIFEST 1 +RT_MANIFEST 24 "ghostty.manifest" + +#define ID_ICON_GHOSTTY 1 +ID_ICON_GHOSTTY ICON "ghostty.ico" + +VS_VERSION_INFO VERSIONINFO +//FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_COMMIT_HEIGHT +//PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_COMMIT_HEIGHT +//FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +//FILEFLAGS VER_DBG +//FILEOS VOS_NT +//FILETYPE VFT_APP +//FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + //VALUE "CompanyName", "???" + //VALUE "FileDescription", "???" + //VALUE "FileVersion", VERSION + //VALUE "LegalCopyright", "(C) 2024 ???" + VALUE "OriginalFilename", "ghostty.exe" + VALUE "ProductName", "Ghostty" + //VALUE "ProductVersion", VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409,1200 + END +END diff --git a/docs/rewrite/notes/final-Z4.md b/docs/rewrite/notes/final-Z4.md new file mode 100644 index 0000000..caf89dd --- /dev/null +++ b/docs/rewrite/notes/final-Z4.md @@ -0,0 +1,27 @@ +# Z4: artifact and distribution gaps + +- Webdata (`GhosttyWebdata.zig`): `ghostty-build-data +webgen-{config,actions,commands}` (`src/webdata.rs`); + `just webdata`, `just install-webdata PREFIX`. Byte-identical to Zig 0.15.2 output of a copy whose webgen mains + gained `stdout.flush()`. Upstream's mains never flush the 2048-byte buffer, so the real Zig files are truncated. + Rust emits the complete files. Also `+version` mode (build-info version string). +- libghostty / vt install: `scripts/install-lib.sh`, `just install-lib PREFIX PROFILE WHAT`; `just install` installs vt + (as Zig's default install does). Layout, headers and `libghostty-vt.pc` match the Zig output (soname `.so.0` set via + patchelf, symlinks `.so`, `.so.0`, `.so.0.1.0`). libghostty adds `ghostty.h` + `module.modulemap`. +- XCFramework: `scripts/xcframework.sh` / `just xcframework` (cargo staticlib per target, `lipo -create`, + `xcodebuild -create-xcframework -headers crates/ghostty-lib/include`, iOS + simulator slices). Verified only with + `DRY_RUN=1`: no macOS tools or SDK here; the darwin cross build was not attempted. +- App id: `just install` defaults to `--profile production` (ReleaseFast); other profiles get `-debug` id/name, like + Zig Debug/ReleaseSafe. Desktop, D-Bus, systemd and metainfo files use it. DESTDIR install checked for production + (`com.mitchellh.ghostty`, build mode .ReleaseFast) and release (`-debug`). +- i18n: `scripts/update-translations.sh` / `just update-translations` (xgettext with the same flags + `--keyword=tr` + over blueprints and apprt-gtk Rust sources, py.pot, merge, msgmerge). msgids identical to upstream's .pot. + Found and fixed: `surface_child_exited.rs` didn't translate "Command succeeded/failed" (now `tr`). Script accepts + an OUT_DIR; po/ was not rewritten in place (location comments would churn). +- Dist: `scripts/dist.sh`, `just dist` / `just distcheck`: `ghostty-.tar.gz` with `VERSION` and the prebuilt + `crates/ghostty-apprt-gtk/dist/ghostty.gresource` (used by apprt-gtk/build.rs outside a git checkout, like Zig's + `ghostty_resources.c/h`). Framedata is already committed. As in Zig, VERSION is for packagers (`GHOSTTY_VERSION_STRING`). + Uses `git ls-files` (includes uncommitted files), not `git archive HEAD`. distcheck passes. +- Windows: `dist/windows/{ghostty.rc,ico,manifest}` copied; root `build.rs` uses `embed-resource` plus the GUI subsystem. + The root binary can't cargo-check for Windows (GTK/wayland deps), so verified with a scratch crate using the same + build.rs for x86_64-pc-windows-gnu: PE subsystem 2, manifest (PerMonitorV2, Common-Controls 6) present. +- Touched outside lane: apprt-gtk `build.rs` (prebuilt gresource) and `surface_child_exited.rs` (tr). diff --git a/justfile b/justfile index b024e4b..e9132a8 100644 --- a/justfile +++ b/justfile @@ -89,22 +89,43 @@ locales OUT="target/locale": # Install bin + share/ghostty (shell-integration, themes, docs) + # share/terminfo (compiled db, ghostty.terminfo, ghostty.termcap) + shell # completions, vim/neovim/bat syntax, man pages, translations, desktop file, -# D-Bus/systemd/metainfo and icons, mirroring Ghostty's GhosttyResources.zig, -# GhosttyDocs.zig and GhosttyI18n.zig. +# D-Bus/systemd/metainfo and icons, plus libghostty-vt (lib, headers, +# libghostty-vt.pc), mirroring Ghostty's GhosttyResources.zig, +# GhosttyDocs.zig, GhosttyI18n.zig and GhosttyLibVt.zig. # -# Usage: `just install [PREFIX] [FLATPAK] [SYSTEM_PACKAGE]`; honours DESTDIR. +# Usage: `just install [PREFIX] [FLATPAK] [SYSTEM_PACKAGE] [PROFILE]`; +# honours DESTDIR. # PREFIX install prefix (default /usr/local) # FLATPAK "true": use the Flatpak D-Bus template, no systemd unit # and no 1024x1024 icon (Zig: -Dflatpak) # SYSTEM_PACKAGE "true": install the systemd user unit to lib/systemd/user # instead of share/systemd/user (Zig: --system / system -# package mode) -install PREFIX="/usr/local" FLATPAK="false" SYSTEM_PACKAGE="false": build-release build-data docs locales +# package mode) +# PROFILE cargo profile to build and install (default "production": +# no debug assertions, the Zig ReleaseFast equivalent). +# Like Zig's Debug/ReleaseSafe modes, any other profile +# (dev, release) installs the "-debug" application id +# (com.mitchellh.ghostty-debug, "Ghostty (Debug)"), which is +# the id the binary uses at runtime when built with debug +# assertions. +install PREFIX="/usr/local" FLATPAK="false" SYSTEM_PACKAGE="false" PROFILE="production": build-data docs locales #!/usr/bin/env bash set -euo pipefail + cargo build --profile {{ PROFILE }} + just install-lib '{{ PREFIX }}' '{{ PROFILE }}' vt P="${DESTDIR:-}{{ PREFIX }}" BD=target/release/ghostty-build-data - install -Dm755 target/release/ghostty "$P/bin/ghostty" + dir={{ PROFILE }} + if [ "$dir" = dev ]; then dir=debug; fi + # GhosttyResources.zig: Debug/ReleaseSafe get the "-debug" id and name. + if [ "{{ PROFILE }}" = production ]; then + APPID=com.mitchellh.ghostty + NAME=Ghostty + else + APPID=com.mitchellh.ghostty-debug + NAME="Ghostty (Debug)" + fi + install -Dm755 "target/$dir/ghostty" "$P/bin/ghostty" mkdir -p "$P/share/ghostty" "$P/share/terminfo" cp -R resources/shell-integration resources/themes "$P/share/ghostty/" find "$P/share/ghostty/shell-integration" -name '*.md' -delete @@ -150,20 +171,20 @@ install PREFIX="/usr/local" FLATPAK="false" SYSTEM_PACKAGE="false": build-releas gen() { # template out mkdir -p "$(dirname "$2")" - sed -e 's|@NAME@|Ghostty|g' -e 's|@APPID@|com.mitchellh.ghostty|g' \ + sed -e "s|@NAME@|$NAME|g" -e "s|@APPID@|$APPID|g" \ -e "s|@GHOSTTY@|{{ PREFIX }}/bin/ghostty|g" "$1" > "$2" } - gen dist/linux/app.desktop.in "$P/share/applications/com.mitchellh.ghostty.desktop" + gen dist/linux/app.desktop.in "$P/share/applications/$APPID.desktop" if [ "{{ FLATPAK }}" = "true" ]; then - gen dist/linux/dbus.service.flatpak.in "$P/share/dbus-1/services/com.mitchellh.ghostty.service" + gen dist/linux/dbus.service.flatpak.in "$P/share/dbus-1/services/$APPID.service" else - gen dist/linux/dbus.service.in "$P/share/dbus-1/services/com.mitchellh.ghostty.service" + gen dist/linux/dbus.service.in "$P/share/dbus-1/services/$APPID.service" # systemd looks in lib/ for system packages and share/ otherwise. sysd=share if [ "{{ SYSTEM_PACKAGE }}" = "true" ]; then sysd=lib; fi - gen dist/linux/systemd.service.in "$P/$sysd/systemd/user/app-com.mitchellh.ghostty.service" + gen dist/linux/systemd.service.in "$P/$sysd/systemd/user/app-$APPID.service" fi - gen dist/linux/com.mitchellh.ghostty.metainfo.xml.in "$P/share/metainfo/com.mitchellh.ghostty.metainfo.xml" + gen dist/linux/com.mitchellh.ghostty.metainfo.xml.in "$P/share/metainfo/$APPID.metainfo.xml" install -Dm644 dist/linux/ghostty_dolphin.desktop "$P/share/kio/servicemenus/com.mitchellh.ghostty.desktop" install -Dm755 dist/linux/ghostty_nautilus.py "$P/share/nautilus-python/extensions/ghostty.py" ic="$P/share/icons/hicolor" @@ -173,8 +194,62 @@ install PREFIX="/usr/local" FLATPAK="false" SYSTEM_PACKAGE="false": build-releas if [ "{{ FLATPAK }}" = "true" ] && [ "${pair%%:*}" = "1024" ]; then continue; fi install -Dm644 "dist/icons/${pair%%:*}.png" "$ic/${pair##*:}/apps/com.mitchellh.ghostty.png" done - echo "installed to $P" + echo "installed to $P (application id $APPID)" # Regenerate resources/terminfo from the terminfo source in ghostty-termio. terminfo: scripts/gen-terminfo.sh + +# Install libghostty and libghostty-vt below PREFIX (honours DESTDIR): +# lib/libghostty.{so,a}, include/ghostty.h, include/module.modulemap +# (GhosttyLib.zig) and lib/libghostty-vt.so{,.0,.0.1.0}, +# include/ghostty/vt*.h, share/pkgconfig/libghostty-vt.pc (GhosttyLibVt.zig). +# WHAT is one of: all, vt, ghostty. +install-lib PREFIX="/usr/local" PROFILE="production" WHAT="all": + scripts/install-lib.sh '{{ PREFIX }}' '{{ PROFILE }}' '{{ WHAT }}' + +# Build libghostty (the embedded C API) as static and shared libraries. +lib PROFILE="production": + cargo build -p ghostty-lib --profile {{ PROFILE }} + +# Build GhosttyKit.xcframework with lipo + xcodebuild (macOS only; Zig: +# GhosttyXCFramework.zig). TARGET is "universal" (macOS arm64+x86_64, iOS, +# iOS simulator) or "native". Set DRY_RUN=1 to only print the commands. +xcframework TARGET="universal" PROFILE="production" OUT="macos/GhosttyKit.xcframework": + scripts/xcframework.sh '{{ TARGET }}' '{{ PROFILE }}' '{{ OUT }}' + +# Generate the website reference data (Zig: GhosttyWebdata.zig): config.mdx, +# actions.mdx (keybind actions) and commands.mdx (CLI actions) in OUT. +webdata OUT="target/webdata": build-data + #!/usr/bin/env bash + set -euo pipefail + mkdir -p "{{ OUT }}" + for m in config actions commands; do + target/release/ghostty-build-data "+webgen-$m" > "{{ OUT }}/$m.mdx" + done + +# Install the website data to PREFIX/share/ghostty/webdata (Zig: +# `-Demit-webdata`); honours DESTDIR. +install-webdata PREFIX="/usr/local": webdata + #!/usr/bin/env bash + set -euo pipefail + for m in config actions commands; do + install -Dm644 "target/webdata/$m.mdx" "${DESTDIR:-}{{ PREFIX }}/share/ghostty/webdata/$m.mdx" + done + +# Regenerate po/com.mitchellh.ghostty.pot (xgettext over the GTK blueprints, +# the GTK apprt Rust sources and the Nautilus extension) and msgmerge every +# po/*.po against it (Zig: `zig build update-translations`). +update-translations: + scripts/update-translations.sh + +# Create the versioned source tarball target/dist/ghostty-.tar.gz with +# the embedded VERSION file and the prebuilt dist resources (Zig: `zig build +# dist`). +dist: + scripts/dist.sh target/dist + +# Extract the dist tarball and check that it builds and tests (Zig: +# `zig build distcheck`). +distcheck: dist + scripts/dist.sh --check diff --git a/scripts/dist.sh b/scripts/dist.sh new file mode 100755 index 0000000..e817698 --- /dev/null +++ b/scripts/dist.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# Create the versioned source tarball (Zig: `zig build dist`, +# build/GhosttyDist.zig) or check one (`zig build distcheck`). +# +# scripts/dist.sh [OUT_DIR] create OUT_DIR/ghostty-.tar.gz +# scripts/dist.sh --check [TARBALL] extract it and verify it +# +# The tarball extracts into `ghostty-/` (expected by debhelper, +# rpmbuild, ...) and contains, in addition to the checked-in sources: +# * `VERSION`: the embedded Ghostty version (Zig: the `VERSION` file), +# * the prebuilt dist resources that are not committed but built here to cut +# the build-time dependencies of downstream packagers: the compiled GTK +# GResource bundle `crates/ghostty-apprt-gtk/dist/ghostty.gresource` +# (Zig: `src/apprt/gtk/ghostty_resources.{c,h}`; picked up by +# ghostty-apprt-gtk/build.rs outside of a git checkout, replacing +# blueprint-compiler + glib-compile-resources). The boo frame data +# (Zig: `framedata.compressed`) is already committed +# (`crates/ghostty-cli/src/boo_frames.deflate`). +# +# In a git checkout the file set is `git ls-files` (tracked files, plus +# untracked files that are not ignored), otherwise all files except build +# output. Files marked `export-ignore` in .gitattributes are dropped. +set -euo pipefail + +cd "$(dirname "$0")/.." +root=$PWD + +# Resources that are generated into the tarball (dist path relative to root). +dist_resources=(crates/ghostty-apprt-gtk/dist/ghostty.gresource) + +version() { + cargo build -q --release -p ghostty-build-data >&2 + "${CARGO_TARGET_DIR:-target}/release/ghostty-build-data" +version +} + +if [ "${1:-}" = --check ]; then + version=$(version) + tarball=${2:-target/dist/ghostty-$version.tar.gz} + work=$(mktemp -d) + trap 'rm -rf "$work"' EXIT + tar -xzf "$tarball" -C "$work" + src="$work/ghostty-$version" + [ -f "$src/VERSION" ] || { echo "missing VERSION" >&2; exit 1; } + [ "$(cat "$src/VERSION")" = "$version" ] || { echo "VERSION mismatch" >&2; exit 1; } + for r in "${dist_resources[@]}"; do + [ -f "$src/$r" ] || { echo "missing dist resource $r" >&2; exit 1; } + done + # Check that the extracted tree builds and passes its tests. + (cd "$src" && cargo test --offline -q -p ghostty-build-data) + echo "distcheck ok: $tarball" + exit 0 +fi + +out=${1:-target/dist} +version=$(version) +name=ghostty-$version +mkdir -p "$out" +work=$(mktemp -d) +trap 'rm -rf "$work"' EXIT + +# Generate the dist resources. +cargo build -q -p ghostty-apprt-gtk +gres=$(find "${CARGO_TARGET_DIR:-target}/debug/build" -path '*ghostty-apprt-gtk-*/out/ghostty.gresource' -printf '%T@ %p\n' | + sort -rn | head -1 | cut -d' ' -f2-) +[ -n "$gres" ] || { echo "ghostty.gresource was not built" >&2; exit 1; } +mkdir -p "$work/stage/crates/ghostty-apprt-gtk/dist" +cp "$gres" "$work/stage/crates/ghostty-apprt-gtk/dist/ghostty.gresource" +printf '%s' "$version" >"$work/stage/VERSION" + +# The file list. +if [ -e .git ] && command -v git >/dev/null 2>&1; then + git ls-files -z --cached --others --exclude-standard +else + find . -path ./target -prune -o -path ./.git -prune -o -path ./.zig-cache -prune \ + -o -name '*.orig' -prune -o -type f -print0 | sed -z 's|^\./||' +fi >"$work/files0" +# export-ignore (git attribute). +if [ -e .git ] && command -v git >/dev/null 2>&1; then + git check-attr -z export-ignore --stdin -z <"$work/files0" | + tr '\0' '\n' | awk 'NR%3==1{f=$0} NR%3==0 && $0=="set"{print f}' >"$work/ignored" || true + if [ -s "$work/ignored" ]; then + tr '\0' '\n' <"$work/files0" | grep -vxFf "$work/ignored" | tr '\n' '\0' >"$work/files0.new" + mv "$work/files0.new" "$work/files0" + fi +fi +# Drop files that no longer exist (deleted but still tracked). +tr '\0' '\n' <"$work/files0" | while IFS= read -r f; do [ -e "$f" ] && printf '%s\0' "$f"; done >"$work/files" + +tar --create --null --files-from "$work/files" \ + --transform "s,^,$name/," --sort=name --owner=0 --group=0 --numeric-owner \ + -f "$work/src.tar" +(cd "$work/stage" && tar --append -f "$work/src.tar" --transform "s,^,$name/," \ + --owner=0 --group=0 --numeric-owner VERSION crates) +gzip -n -c "$work/src.tar" >"$out/$name.tar.gz" +echo "$out/$name.tar.gz" diff --git a/scripts/install-lib.sh b/scripts/install-lib.sh new file mode 100755 index 0000000..22aba13 --- /dev/null +++ b/scripts/install-lib.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# Install libghostty and/or libghostty-vt below a prefix, mirroring +# build/GhosttyLib.zig (`install`, `installHeader`) and build/GhosttyLibVt.zig. +# +# Usage: scripts/install-lib.sh PREFIX PROFILE [all|vt|ghostty] +# PREFIX install prefix; DESTDIR (env) is prepended for the file copies but +# not for the paths recorded in the pkg-config file. +# PROFILE cargo profile whose artifacts are installed (dev -> target/debug). +# WHAT `vt`: libghostty-vt only (what `zig build` always installs); +# `ghostty`: libghostty only (Zig: `-Dapp-runtime=none`, non-Darwin); +# `all` (default): both. +# +# libghostty-vt (version 0.1.0): +# lib/libghostty-vt.so.0.1.0 (+ libghostty-vt.so.0, libghostty-vt.so symlinks; +# macOS: libghostty-vt.0.1.0.dylib, libghostty-vt.0.dylib, libghostty-vt.dylib) +# include/ghostty/vt.h and include/ghostty/vt/**.h +# share/pkgconfig/libghostty-vt.pc +# libghostty: +# lib/libghostty.so, lib/libghostty.a (macOS: .dylib), include/ghostty.h, +# include/module.modulemap +set -euo pipefail + +cd "$(dirname "$0")/.." +prefix=${1:?usage: install-lib.sh PREFIX PROFILE [all|vt|ghostty]} +profile=${2:-production} +what=${3:-all} +dest="${DESTDIR:-}$prefix" +dir=$profile +[ "$profile" = dev ] && dir=debug +tdir=${CARGO_TARGET_DIR:-target}/$dir +cargo_args=(--profile "$profile") +vt_version=0.1.0 +vt_major=${vt_version%%.*} + +case $(uname -s) in +Darwin) dylib=dylib ;; +*) dylib=so ;; +esac + +install_vt() { + cargo build "${cargo_args[@]}" -p ghostty-vt-capi + local src="$tdir/libghostty_vt_capi.$dylib" + install -d "$dest/lib" "$dest/share/pkgconfig" + if [ "$dylib" = so ]; then + local real="libghostty-vt.so.$vt_version" + install -m755 "$src" "$dest/lib/$real" + # The cargo-built soname is the unversioned name; Zig's is `.so.0`. + if command -v patchelf >/dev/null 2>&1; then + patchelf --set-soname "libghostty-vt.so.$vt_major" "$dest/lib/$real" + else + echo "patchelf not found: soname stays libghostty-vt.so" >&2 + fi + ln -sf "$real" "$dest/lib/libghostty-vt.so.$vt_major" + ln -sf "libghostty-vt.so.$vt_major" "$dest/lib/libghostty-vt.so" + else + local real="libghostty-vt.$vt_version.dylib" + install -m755 "$src" "$dest/lib/$real" + if command -v install_name_tool >/dev/null 2>&1; then + install_name_tool -id "@rpath/libghostty-vt.$vt_major.dylib" "$dest/lib/$real" + fi + ln -sf "$real" "$dest/lib/libghostty-vt.$vt_major.dylib" + ln -sf "libghostty-vt.$vt_major.dylib" "$dest/lib/libghostty-vt.dylib" + fi + + # Headers: include/ghostty/**.h (lib.installHeadersDirectory, .h only). + local inc=crates/ghostty-vt-capi/include/ghostty + while IFS= read -r h; do + install -Dm644 "$inc/$h" "$dest/include/ghostty/$h" + done < <(cd "$inc" && find . -type f -name '*.h' | sed 's|^\./||' | LC_ALL=C sort) + + # pkg-config file (no trailing newline, like the Zig `b.fmt` literal). + printf 'prefix=%s\nincludedir=${prefix}/include\nlibdir=${prefix}/lib\n\nName: libghostty-vt\nURL: https://github.com/ghostty-org/ghostty\nDescription: Ghostty VT library\nVersion: %s\nCflags: -I${includedir}\nLibs: -L${libdir} -lghostty-vt' \ + "$prefix" "$vt_version" >"$dest/share/pkgconfig/libghostty-vt.pc" + chmod 644 "$dest/share/pkgconfig/libghostty-vt.pc" +} + +install_ghostty() { + cargo build "${cargo_args[@]}" -p ghostty-lib + install -d "$dest/lib" "$dest/include" + install -m755 "$tdir/libghostty.$dylib" "$dest/lib/libghostty.$dylib" + install -m644 "$tdir/libghostty.a" "$dest/lib/libghostty.a" + install -m644 crates/ghostty-lib/include/ghostty.h "$dest/include/ghostty.h" + install -m644 crates/ghostty-lib/include/module.modulemap "$dest/include/module.modulemap" +} + +case $what in +all) install_vt; install_ghostty ;; +vt) install_vt ;; +ghostty) install_ghostty ;; +*) echo "unknown component: $what" >&2; exit 2 ;; +esac +echo "installed libraries to $dest" diff --git a/scripts/update-translations.sh b/scripts/update-translations.sh new file mode 100755 index 0000000..ab6d583 --- /dev/null +++ b/scripts/update-translations.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Update the translation catalogs in po/ (Zig: `zig build update-translations`, +# build/GhosttyI18n.zig `createUpdateStep`). +# +# 1. xgettext over the GTK blueprint files and the Rust sources of the GTK +# apprt (Zig: src/apprt/gtk/**/*.zig) -> gtk.pot. The `tr(...)` function +# of `ghostty_os::i18n` is the Rust counterpart of Zig's `_(...)`. +# 2. xgettext over the Nautilus extension -> py.pot. +# 3. xgettext merge (py.pot first, because of xgettext's charset behaviour +# when merging) -> po/com.mitchellh.ghostty.pot. +# 4. msgmerge every po/.po against the new template. +# +# Usage: scripts/update-translations.sh [OUT_DIR] +# OUT_DIR where to write the .pot/.po files (default: po/, i.e. in place). +# The existing catalogs are always read from po/. +set -euo pipefail + +cd "$(dirname "$0")/.." +domain=com.mitchellh.ghostty +out=${1:-po} +mkdir -p "$out" +tmp=$(mktemp -d) +trap 'rm -rf "$tmp"' EXIT + +gtk=crates/ghostty-apprt-gtk + +# Blueprint files in the order of the GResource list (build.rs BLUEPRINTS, +# Zig: gresource.blueprints). The arguments to xgettext must be relative +# paths in the repo root so the location comments don't depend on where the +# checkout lives. +mapfile -t blueprints < <( + sed -n 's/^[[:space:]]*(\([0-9]*\), \([0-9]*\), "\([^"]*\)"),.*/\1 \2 \3/p' "$gtk/build.rs" | + while read -r major minor name; do + echo "$gtk/resources/ui/$major.$minor/$name.blp" + done +) +# Rust sources of the GTK apprt, sorted for a deterministic order. +mapfile -t sources < <(cd . && find "$gtk/src" -type f -name '*.rs' | LC_ALL=C sort) + +xgettext \ + --language=C \ + --from-code=UTF-8 \ + --keyword=tr \ + --keyword=_ \ + --keyword=C_:1c,2 \ + -o "$tmp/gtk.pot" \ + "${blueprints[@]}" "${sources[@]}" + +xgettext \ + --language=Python \ + --from-code=UTF-8 \ + -o "$tmp/py.pot" \ + dist/linux/ghostty_nautilus.py + +xgettext \ + --add-comments=Translators \ + --package-name="$domain" \ + --msgid-bugs-address=m@mitchellh.com \ + '--copyright-holder="Mitchell Hashimoto, Ghostty contributors"' \ + -o - \ + "$tmp/py.pot" "$tmp/gtk.pot" >"$tmp/$domain.pot" + +for po in po/*.po; do + lang=$(basename "$po" .po) + msgmerge --quiet --no-fuzzy-matching "$po" "$tmp/$domain.pot" >"$tmp/$lang.po" +done + +# Only write once everything succeeded (Zig: UpdateSourceFiles). +cp "$tmp/$domain.pot" "$out/$domain.pot" +for po in po/*.po; do + lang=$(basename "$po" .po) + cp "$tmp/$lang.po" "$out/$lang.po" +done +echo "updated $out/$domain.pot and $(ls po/*.po | wc -l) catalogs" diff --git a/scripts/xcframework.sh b/scripts/xcframework.sh new file mode 100755 index 0000000..04db917 --- /dev/null +++ b/scripts/xcframework.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# Build GhosttyKit.xcframework (macOS only; mirrors build/GhosttyLib.zig +# `initMacOSUniversal`/`initStatic`, build/GhosttyXCFramework.zig, +# build/LipoStep.zig and build/XCFrameworkStep.zig). +# +# Usage: scripts/xcframework.sh [universal|native] [PROFILE] [OUT] +# universal (default) a universal (arm64 + x86_64, via lipo) macOS static +# library, an iOS device library and an iOS simulator library. +# native only the static library for the host macOS architecture. +# PROFILE cargo profile (default production) +# OUT output path (default macos/GhosttyKit.xcframework, like Zig) +# +# Each slice is `libghostty.a` (the Rust staticlib already bundles every +# dependency, so there is no libtool step) plus the `include/` directory with +# ghostty.h and module.modulemap. Static libraries have no dSYM. +# +# DRY_RUN=1 prints the commands instead of running them (usable on any host). +set -euo pipefail + +cd "$(dirname "$0")/.." +target=${1:-universal} +profile=${2:-production} +out=${3:-macos/GhosttyKit.xcframework} +dir=$profile +[ "$profile" = dev ] && dir=debug +tdir=${CARGO_TARGET_DIR:-target} + +# Config.zig osVersionMin: macOS 13, iOS 17. +export MACOSX_DEPLOYMENT_TARGET=13.0 +export IPHONEOS_DEPLOYMENT_TARGET=17.0 + +run() { + if [ "${DRY_RUN:-}" = 1 ]; then + printf '+' + printf ' %q' "$@" + printf '\n' + else + "$@" + fi +} + +# Build only the static library for a Rust target triple (the crate also +# declares a cdylib, which needs no linking for the xcframework). +build() { + run cargo rustc --profile "$profile" -p ghostty-lib --lib --crate-type staticlib --target "$1" +} +lib() { echo "$tdir/$1/$dir/libghostty.a"; } + +host_arch=$(uname -m) +case $host_arch in +arm64 | aarch64) native=aarch64-apple-darwin ;; +*) native=x86_64-apple-darwin ;; +esac + +args=() +case $target in +universal) + build aarch64-apple-darwin + build x86_64-apple-darwin + build aarch64-apple-ios + build aarch64-apple-ios-sim + + universal_dir="$tdir/universal-apple-darwin/$dir" + run mkdir -p "$universal_dir" + run lipo -create -output "$universal_dir/libghostty.a" \ + "$(lib aarch64-apple-darwin)" "$(lib x86_64-apple-darwin)" + args+=(-library "$universal_dir/libghostty.a" -headers crates/ghostty-lib/include) + args+=(-library "$(lib aarch64-apple-ios)" -headers crates/ghostty-lib/include) + args+=(-library "$(lib aarch64-apple-ios-sim)" -headers crates/ghostty-lib/include) + ;; +native) + build "$native" + args+=(-library "$(lib "$native")" -headers crates/ghostty-lib/include) + ;; +*) + echo "usage: $0 [universal|native] [PROFILE] [OUT]" >&2 + exit 2 + ;; +esac + +# The output path is static, so delete the old framework first. +run rm -rf "$out" +run xcodebuild -create-xcframework "${args[@]}" -output "$out"