244 lines
6.0 KiB
Bash
244 lines
6.0 KiB
Bash
#!/bin/bash
|
|
#Script to build ghostty from source. It automatically grabs required zig version binary.
|
|
#v1.0.4
|
|
|
|
set -euo pipefail
|
|
|
|
# === Config ===
|
|
PREFIX="${HOME}/.local"
|
|
OPTIMIZATION="ReleaseFast"
|
|
GHOSTTY_REPO="https://github.com/ghostty-org/ghostty.git"
|
|
GHOSTTY_PUBKEY="RWQlAjJC23149WL2sEpT/l0QKy7hMIFhYdQOFy0Z7z7PbneUgvlsnYcV"
|
|
BUILD_DIR="/tmp/ghostty_build"
|
|
CLEAN_BUILD=false
|
|
|
|
# === Parse arguments ===
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
--clean)
|
|
CLEAN_BUILD=true
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# === Helpers ===
|
|
command_exists() { command -v "$1" >/dev/null 2>&1; }
|
|
info() { echo "==> $*"; }
|
|
error() { echo "ERROR: $*" >&2; exit 1; }
|
|
|
|
# === Create build directory ===
|
|
mkdir -p "$BUILD_DIR"
|
|
cd "$BUILD_DIR"
|
|
|
|
# === Version selection ===
|
|
choose_version() {
|
|
info "Fetching available Ghostty versions from GitHub..."
|
|
local tags
|
|
tags=$(curl -s https://api.github.com/repos/ghostty-org/ghostty/tags \
|
|
| grep '"name":' \
|
|
| cut -d'"' -f4)
|
|
|
|
if [ -z "$tags" ]; then
|
|
error "Could not fetch tags from GitHub."
|
|
fi
|
|
|
|
local latest
|
|
latest=$(echo "$tags" | head -n1)
|
|
|
|
echo
|
|
echo "Available Ghostty versions:"
|
|
echo " 0) $latest (latest release)"
|
|
echo " 1) tip (development)"
|
|
local i=2
|
|
local arr=()
|
|
while read -r tag; do
|
|
if [ "$tag" != "$latest" ] && [ "$tag" != "tip" ]; then
|
|
echo " $i) $tag"
|
|
arr+=("$tag")
|
|
i=$((i+1))
|
|
fi
|
|
done <<< "$tags"
|
|
|
|
echo
|
|
read -rp "Select a version [0-$((i-1))]: " choice
|
|
|
|
case "$choice" in
|
|
0) GHOSTTY_VERSION="$latest" ;;
|
|
1) GHOSTTY_VERSION="tip" ;;
|
|
*) local idx=$((choice-2)); GHOSTTY_VERSION="${arr[$idx]}" ;;
|
|
esac
|
|
|
|
info "Selected Ghostty version: $GHOSTTY_VERSION"
|
|
}
|
|
|
|
# === Zig version mapping ===
|
|
resolve_zig_version() {
|
|
case "$GHOSTTY_VERSION" in
|
|
1.0.*|1.1.*) echo "0.13.0" ;;
|
|
1.2.*) echo "0.14.1" ;;
|
|
tip) echo "0.14.1" ;;
|
|
v*)
|
|
local ver="${GHOSTTY_VERSION#v}"
|
|
case "$ver" in
|
|
1.0.*|1.1.*) echo "0.13.0" ;;
|
|
1.2.*) echo "0.14.1" ;;
|
|
*) error "Unknown mapping for Ghostty version $ver";;
|
|
esac
|
|
;;
|
|
*) error "Unknown Ghostty version format: $GHOSTTY_VERSION";;
|
|
esac
|
|
}
|
|
|
|
# === Download Zig standalone binary ===
|
|
setup_zig() {
|
|
local zig_version="$1"
|
|
local os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
local arch=$(uname -m)
|
|
|
|
case "$os" in
|
|
linux) os="linux" ;;
|
|
darwin) os="macos" ;;
|
|
*) error "Unsupported OS: $os";;
|
|
esac
|
|
|
|
case "$arch" in
|
|
x86_64) arch="x86_64" ;;
|
|
aarch64|arm64) arch="aarch64" ;;
|
|
*) error "Unsupported arch: $arch";;
|
|
esac
|
|
|
|
local tarball
|
|
local dirname
|
|
|
|
if [[ "$zig_version" < "0.14.1" ]]; then
|
|
tarball="zig-${os}-${arch}-${zig_version}.tar.xz"
|
|
dirname="zig-${os}-${arch}-${zig_version}"
|
|
else
|
|
tarball="zig-${arch}-${os}-${zig_version}.tar.xz"
|
|
dirname="zig-${arch}-${os}-${zig_version}"
|
|
fi
|
|
|
|
if [ ! -d "$dirname" ]; then
|
|
info "Downloading Zig $zig_version from https://ziglang.org/download/$zig_version/$tarball"
|
|
curl -fLO "https://ziglang.org/download/$zig_version/$tarball"
|
|
tar -xf "$tarball"
|
|
fi
|
|
|
|
export PATH="$BUILD_DIR/$dirname:$PATH"
|
|
info "Using Zig at $(command -v zig) ($(zig version))"
|
|
}
|
|
|
|
# === Install build dependencies ===
|
|
install_deps_linux() {
|
|
if ! command_exists apt-get && ! command_exists pacman && ! command_exists dnf; then
|
|
error "No supported package manager found (apt, pacman, dnf). Install dependencies manually."
|
|
fi
|
|
|
|
local distro=""
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
distro="$ID"
|
|
fi
|
|
|
|
if command_exists apt-get; then
|
|
info "Installing dependencies via apt-get..."
|
|
sudo apt-get update
|
|
|
|
# Base packages
|
|
sudo apt-get install -y git libgtk-4-dev gettext libxml2-utils pkg-config curl tar xz-utils g++
|
|
|
|
# Harfbuzz development
|
|
sudo apt-get install -y libharfbuzz-dev libharfbuzz-gobject0
|
|
|
|
# GTK Blueprint compiler
|
|
sudo apt-get install -y blueprint-compiler
|
|
|
|
# libadwaita package
|
|
case "$distro" in
|
|
ubuntu|debian)
|
|
if ! sudo apt-get install -y libadwaita-1-dev; then
|
|
sudo apt-get install -y libadwaita-dev || true
|
|
fi
|
|
;;
|
|
*)
|
|
sudo apt-get install -y libadwaita-1-dev libadwaita-dev || true
|
|
;;
|
|
esac
|
|
|
|
# GTK layer-shell package
|
|
case "$distro" in
|
|
ubuntu)
|
|
sudo apt-get install -y libgtk-layer-shell-dev || true
|
|
;;
|
|
debian)
|
|
sudo apt-get install -y libgtk4-layer-shell-dev || true
|
|
;;
|
|
*)
|
|
sudo apt-get install -y libgtk4-layer-shell-dev libgtk-layer-shell-dev || true
|
|
;;
|
|
esac
|
|
|
|
# Verify critical pkg-config dependencies
|
|
for pkg in gtk4 libadwaita-1 gtk-layer-shell-1.0; do
|
|
if ! pkg-config --exists "$pkg"; then
|
|
error "Missing required development package: $pkg. Did apt-get install succeed?"
|
|
fi
|
|
done
|
|
|
|
elif command_exists pacman; then
|
|
sudo pacman -Sy --noconfirm \
|
|
git gtk4 gtk4-layer-shell libadwaita gettext pkgconf curl tar xz g++ blueprint-compiler harfbuzz
|
|
elif command_exists dnf; then
|
|
sudo dnf install -y \
|
|
git gtk4-devel gtk4-layer-shell-devel libadwaita-devel \
|
|
gettext pkgconf curl tar xz g++ blueprint-compiler harfbuzz-devel
|
|
fi
|
|
}
|
|
|
|
# === Clone Ghostty repo and checkout version ===
|
|
fetch_source_git() {
|
|
if [ ! -d "ghostty" ]; then
|
|
git clone "$GHOSTTY_REPO"
|
|
fi
|
|
cd ghostty
|
|
git fetch --tags --quiet
|
|
|
|
if [ "$GHOSTTY_VERSION" = "tip" ]; then
|
|
git checkout main
|
|
else
|
|
git checkout "$GHOSTTY_VERSION"
|
|
fi
|
|
}
|
|
|
|
# === Build and install Ghostty ===
|
|
build_install() {
|
|
zig build -Doptimize="$OPTIMIZATION"
|
|
zig build install -p "$PREFIX" -Doptimize="$OPTIMIZATION"
|
|
info "Ghostty installed to $PREFIX/bin/ghostty"
|
|
}
|
|
|
|
# === Clean build directory ===
|
|
cleanup_build() {
|
|
if $CLEAN_BUILD; then
|
|
info "Cleaning up build directory $BUILD_DIR"
|
|
cd ..
|
|
rm -rf "$BUILD_DIR"
|
|
fi
|
|
}
|
|
|
|
# === Main ===
|
|
main() {
|
|
choose_version
|
|
if [[ "$(uname -s)" == "Linux" ]]; then
|
|
install_deps_linux
|
|
fi
|
|
local zig_ver
|
|
zig_ver=$(resolve_zig_version)
|
|
setup_zig "$zig_ver"
|
|
fetch_source_git
|
|
build_install
|
|
cleanup_build
|
|
}
|
|
|
|
main "$@" |