#!/usr/bin/env bash # Builds VibEdit for Windows and/or Linux from any OS (pure Go, no C toolchain # needed). # # ./build.sh -> dist/vibedit.exe (Windows x64) # ./build.sh linux -> dist/vibedit (Linux x64) # ./build.sh all -> both # ./build.sh [target] --package -> also downloads ffmpeg for that OS and creates # dist/VibEdit-windows-x64.zip and/or # dist/VibEdit-linux-x64.tar.xz (ready to run) set -euo pipefail cd "$(dirname "$0")" VERSION=1.0.0 FFMPEG_URL=https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip # Static release build (needs glibc 2.28+) with the same GPU encoders as the # Windows one. BtbN keeps only the newest release branches, so bump the # version here when this URL stops working. FFMPEG_LINUX_URL=https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n9.0-latest-linux64-gpl-9.0.tar.xz TARGET=windows PACKAGE=0 for arg in "$@"; do case "$arg" in windows|linux|all) TARGET=$arg ;; --package) PACKAGE=1 ;; *) echo "usage: $0 [windows|linux|all] [--package]" >&2; exit 2 ;; esac done GO=${GO:-go} if ! command -v "$GO" >/dev/null 2>&1 && [ -x "$HOME/.local/go/bin/go" ]; then GO="$HOME/.local/go/bin/go" fi mkdir -p dist # download URL NAME: fetches URL to dist/cache/NAME unless it is already there. download() { mkdir -p dist/cache if [ ! -f "dist/cache/$2" ]; then echo "Downloading $1 ..." wget -q --show-progress -O "dist/cache/$2.tmp" "$1" mv "dist/cache/$2.tmp" "dist/cache/$2" fi } build_windows() { GOOS=windows GOARCH=amd64 CGO_ENABLED=0 "$GO" build -trimpath \ -ldflags "-s -w -X main.version=$VERSION" -o dist/vibedit.exe . echo "Built dist/vibedit.exe" [ "$PACKAGE" = 1 ] || return 0 download "$FFMPEG_URL" ffmpeg-essentials.zip rm -rf dist/VibEdit dist/VibEdit-windows-x64.zip mkdir -p dist/VibEdit cp dist/vibedit.exe dist/VibEdit/ cp package-readme.txt dist/VibEdit/README.txt python3 - <<'EOF' import os, zipfile src = zipfile.ZipFile("dist/cache/ffmpeg-essentials.zip") wanted = {"ffmpeg.exe": "ffmpeg.exe", "ffprobe.exe": "ffprobe.exe", "LICENSE": "ffmpeg-LICENSE.txt"} found = set() for info in src.infolist(): base = os.path.basename(info.filename) if base in wanted and base not in found: with open(os.path.join("dist/VibEdit", wanted[base]), "wb") as f: f.write(src.read(info)) found.add(base) missing = set(wanted) - found if missing: raise SystemExit("ffmpeg zip is missing: " + ", ".join(sorted(missing))) with zipfile.ZipFile("dist/VibEdit-windows-x64.zip", "w", zipfile.ZIP_DEFLATED) as out: for name in sorted(os.listdir("dist/VibEdit")): out.write(os.path.join("dist/VibEdit", name), "VibEdit/" + name) EOF echo "Packaged dist/VibEdit-windows-x64.zip" } build_linux() { GOOS=linux GOARCH=amd64 CGO_ENABLED=0 "$GO" build -trimpath \ -ldflags "-s -w -X main.version=$VERSION" -o dist/vibedit . echo "Built dist/vibedit" [ "$PACKAGE" = 1 ] || return 0 local cache cache=$(basename "$FFMPEG_LINUX_URL") download "$FFMPEG_LINUX_URL" "$cache" rm -rf dist/linux-x64 dist/VibEdit-linux-x64.tar.xz mkdir -p dist/linux-x64/VibEdit cp dist/vibedit linux/install.sh dist/linux-x64/VibEdit/ cp linux/README.txt dist/linux-x64/VibEdit/README.txt cp winres/icon.png dist/linux-x64/VibEdit/vibedit.png echo "Compressing (takes a minute or two) ..." python3 - "dist/cache/$cache" <<'EOF' import os, sys, tarfile dst = "dist/linux-x64/VibEdit" wanted = {"ffmpeg": "ffmpeg", "ffprobe": "ffprobe", "LICENSE.txt": "ffmpeg-LICENSE.txt"} executables = {"vibedit", "ffmpeg", "ffprobe", "install.sh"} found = set() with tarfile.open(sys.argv[1]) as src: for m in src.getmembers(): base = os.path.basename(m.name) if m.isfile() and base in wanted and base not in found: path = os.path.join(dst, wanted[base]) with open(path, "wb") as f: f.write(src.extractfile(m).read()) os.chmod(path, 0o755 if wanted[base] in executables else 0o644) found.add(base) missing = set(wanted) - found if missing: raise SystemExit("ffmpeg archive is missing: " + ", ".join(sorted(missing))) def normalize(ti): ti.uid = ti.gid = 0 ti.uname = ti.gname = "" if ti.isdir() or os.path.basename(ti.name) in executables: ti.mode = 0o755 else: ti.mode = 0o644 return ti with tarfile.open("dist/VibEdit-linux-x64.tar.xz", "w:xz") as out: out.add(dst, "VibEdit", recursive=False, filter=normalize) for name in sorted(os.listdir(dst)): out.add(os.path.join(dst, name), "VibEdit/" + name, filter=normalize) EOF echo "Packaged dist/VibEdit-linux-x64.tar.xz" } case "$TARGET" in windows) build_windows ;; linux) build_linux ;; all) build_windows; build_linux ;; esac