Use Jerboa artifact toolchain
ober
bda3c1b1db49fbc85c7ea46301f64a4625372040
--- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ petite_boot.h scheme_boot.h program_boot.h vendor/ +/.jerboa/ signal_tui_shim.dylib signal_tui_shim.so signal_log_shim.dylib --- a/Makefile +++ b/Makefile @@ -1,14 +1,23 @@ # jerbuild bundles Chez Scheme + the jerboa stdlib under ~/.cache/jerbuild/, # so building jerboa-signal needs only `jerbuild` + a C compiler — no jerboa # source checkout and no separately-built Chez. -JERBUILD ?= jerbuild -JH := $(shell $(JERBUILD) --jerboa-home 2>/dev/null) -ifeq ($(JH),) -$(error jerbuild not found on PATH (or '$(JERBUILD) --jerboa-home' failed). Install jerbuild, or set JERBUILD=/path/to/jerbuild) -endif +JERBOA_VERSION ?= v0.2.0 +JERBOA_TOOL_DIR ?= $(CURDIR)/.jerboa/bin +JERBUILD ?= $(shell if [ -x ./jerbuild ] && [ -x ./jerboa ]; then \ + printf '%s\n' ./jerbuild; \ +elif [ -x "$(JERBOA_TOOL_DIR)/jerbuild" ] && [ -x "$(JERBOA_TOOL_DIR)/jerboa" ]; then \ + printf '%s\n' "$(JERBOA_TOOL_DIR)/jerbuild"; \ +elif [ -x ../jerboa/dist/jerbuild ] && [ -x ../jerboa/dist/jerboa ]; then \ + printf '%s\n' ../jerboa/dist/jerbuild; \ +elif command -v jerbuild >/dev/null 2>&1 && command -v jerboa >/dev/null 2>&1; then \ + command -v jerbuild; \ +else \ + printf '%s\n' "$(JERBOA_TOOL_DIR)/jerbuild"; \ +fi) +JH = $(shell "$(JERBUILD)" --jerboa-home 2>/dev/null) -LIBDIRS := --libdirs $(CURDIR):$(JH)/lib -JEXEC := $(JERBUILD) exec $(LIBDIRS) +LIBDIRS = --libdirs $(CURDIR):$(JH)/lib +JEXEC = $(JERBUILD) exec $(LIBDIRS) BIN := jerboa-signal BIN_DIR := $(HOME)/.local/bin TUI_SHIM_DIR := $(CURDIR)/vendor/termbox2 @@ -22,13 +31,13 @@ TUI_SHIM := $(TUI_SHIM_DIR)/signal_tui_shim.$(TUI_SHIM_EXT) LOG_SHIM := signal_log_shim.$(TUI_SHIM_EXT) SQLCIPHER_PREFIX := $(shell brew --prefix sqlcipher 2>/dev/null) -.PHONY: all build binary run run-tui test install clean help vendor-deps tui-shim log-shim +.PHONY: all build binary run run-tui test install clean help vendor-deps tui-shim log-shim ensure-jerboa-tools .DEFAULT_GOAL := help all: binary # Standalone native binary via .jerbuild (entry signal/main.ss -> jerboa-signal). -binary: +binary: ensure-jerboa-tools $(JERBUILD) build build: binary @@ -61,6 +70,24 @@ vendor/termbox2: mkdir -p vendor git clone --depth 1 https://github.com/termbox/termbox2.git vendor/termbox2 +ensure-jerboa-tools: + @if [ -x ./jerbuild ] && [ -x ./jerboa ]; then \ + echo "=== Using project-local ./jerbuild ==="; \ + elif [ -x "$(JERBOA_TOOL_DIR)/jerbuild" ] && [ -x "$(JERBOA_TOOL_DIR)/jerboa" ]; then \ + echo "=== Using downloaded Jerboa toolchain: $(JERBOA_TOOL_DIR) ==="; \ + elif [ -x ../jerboa/dist/jerbuild ] && [ -x ../jerboa/dist/jerboa ]; then \ + echo "=== Using sibling Jerboa build: ../jerboa/dist/jerbuild ==="; \ + elif command -v jerbuild >/dev/null 2>&1 && command -v jerboa >/dev/null 2>&1; then \ + echo "=== Using Jerboa toolchain from PATH: $$(command -v jerbuild) ==="; \ + else \ + echo "=== Fetching Jerboa $(JERBOA_VERSION) release tools into $(JERBOA_TOOL_DIR) ==="; \ + sh support/ensure-jerboa.sh "$(JERBOA_VERSION)" "$(JERBOA_TOOL_DIR)"; \ + fi + @"$(JERBUILD)" --jerboa-home >/dev/null || { \ + echo "ERROR: Jerboa toolchain is unavailable; set JERBUILD=/path/to/jerbuild or JERBOA_VERSION=<tag>"; \ + exit 1; \ + } + tui-shim: vendor/termbox2 @test -f $(TUI_SHIM) || \ cc -shared -fPIC -DTB_OPT_ATTR_W=32 \ @@ -91,6 +118,7 @@ help: @echo " run-tui Build shim and start the TUI" @echo " test Run tests" @echo " install Install ./jerboa-signal to ~/.local/bin" + @echo " ensure-jerboa-tools Ensure jerboa/jerbuild are available" @echo " tui-shim Build the termbox2 TUI shim" @echo " log-shim Build the SQLCipher encrypted-logging shim" @echo " clean Remove build artifacts" --- a/README.md +++ b/README.md @@ -20,7 +20,9 @@ jerboa-signal tui [-a +PHONE] # terminal UI shell ## Prerequisites - `signal-cli` on `PATH` (Homebrew: `brew install signal-cli`) -- A Jerboa checkout next to this repo at `../jerboa`, or `JERBOA_HOME` set +- Jerboa build tools. `make binary`/`make install` use project-local + `./jerbuild` first, then `.jerboa/bin`, then `../jerboa/dist`, then `PATH`, + and download the matching release artifact if none are available. - Optional, for the encrypted message log: `brew install sqlcipher`, then `make log-shim` (without it the TUI runs fine, just without logging) new file mode 100755 --- /dev/null +++ b/support/ensure-jerboa.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# Bootstrap a project-local Jerboa toolchain from SourceHut release artifacts. +# +# Usage: +# support/ensure-jerboa.sh v0.2.0 .jerboa/bin +# +# Override the artifact location with: +# JERBOA_RELEASE_BASE=https://example.org/releases/v0.2.0 +# or the SourceHut repo with: +# JERBOA_RELEASE_REPO=~lisp/jerboa +# For testing or unusual hosts, override target detection with: +# JERBOA_RELEASE_TARGET=macos-arm64 + +set -eu + +usage() { + echo "Usage: $0 VERSION [BINDIR]" >&2 +} + +[ "${1:-}" ] || { usage; exit 2; } + +version=$1 +bindir=${2:-.jerboa/bin} +repo=${JERBOA_RELEASE_REPO:-~lisp/jerboa} +origin=${JERBOA_RELEASE_ORIGIN:-https://git.sr.ht} + +if [ "${JERBOA_RELEASE_TARGET:-}" ]; then + target=$JERBOA_RELEASE_TARGET +else + os=$(uname -s) + arch=$(uname -m) + case "$os-$arch" in + Darwin-arm64) target=macos-arm64 ;; + Linux-x86_64|Linux-amd64) target=linux-amd64 ;; + Linux-aarch64|Linux-arm64) target=linux-arm64 ;; + FreeBSD-amd64|FreeBSD-x86_64) target=freebsd-amd64 ;; + *) + echo "ERROR: unsupported platform for Jerboa release artifacts: $os $arch" >&2 + echo " set JERBUILD=/path/to/jerbuild or build Jerboa locally for this host" >&2 + exit 1 + ;; + esac +fi + +case "$target" in + macos-arm64|linux-amd64|linux-arm64|freebsd-amd64) ;; + *) + echo "ERROR: unsupported release target: $target" >&2 + exit 1 + ;; +esac + +file="jerboa-${version}-${target}.tar.gz" +base=${JERBOA_RELEASE_BASE:-${origin}/${repo}/refs/download/${version}} +url="${base%/}/${file}" +sum_url="${url}.sha256" + +download() { + src=$1 + dst=$2 + if command -v curl >/dev/null 2>&1; then + curl -fsSL "$src" -o "$dst" + elif command -v fetch >/dev/null 2>&1; then + fetch -q -o "$dst" "$src" + elif command -v wget >/dev/null 2>&1; then + wget -q -O "$dst" "$src" + else + echo "ERROR: need curl, fetch, or wget to download Jerboa" >&2 + exit 1 + fi +} + +sha256_file() { + path=$1 + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$path" | awk '{print $1}' + elif command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$path" | awk '{print $1}' + elif command -v sha256 >/dev/null 2>&1; then + sha256 -q "$path" + else + echo "ERROR: need sha256sum, shasum, or sha256" >&2 + exit 1 + fi +} + +tmp=$(mktemp -d "${TMPDIR:-/tmp}/jerboa-bootstrap.XXXXXX") +trap 'rm -rf "$tmp"' EXIT HUP INT TERM + +archive="$tmp/$file" +sum_file="$tmp/$file.sha256" + +echo "fetching $url" +download "$url" "$archive" +download "$sum_url" "$sum_file" + +expected=$(awk '{print $1; exit}' "$sum_file") +actual=$(sha256_file "$archive") +if [ "$expected" != "$actual" ]; then + echo "ERROR: checksum mismatch for $file" >&2 + echo "expected: $expected" >&2 + echo "actual: $actual" >&2 + exit 1 +fi + +mkdir -p "$tmp/extract" +tar -xzf "$archive" -C "$tmp/extract" +root="$tmp/extract/jerboa-${version}-${target}" +[ -x "$root/bin/jerboa" ] || { + echo "ERROR: archive did not contain bin/jerboa" >&2 + exit 1 +} + +mkdir -p "$bindir" +cp "$root/bin/jerboa" "$bindir/jerboa" +chmod 0755 "$bindir/jerboa" +for link in jmcp jlsp jerbuild jpkg; do + ln -sf jerboa "$bindir/$link" +done + +echo "installed $bindir/{jerboa,jmcp,jlsp,jerbuild,jpkg}"