build: build jerboa-edge with installed jerbuild (no ~/mine/jerboa)
ober
0d13422cc1181982661550865b28149a6e4b0f24
new file mode 100644 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Build artifacts (jerbuild build) +/jerboa-edge +*-main.c +*.so +*.wpo +*.boot +petite_boot.h +scheme_boot.h +program_boot.h --- a/.jerbuild +++ b/.jerbuild @@ -1,10 +1,19 @@ -;; Build jerboa-edge with a standalone jerbuild binary. +;; Build jerboa-edge with a standalone jerbuild binary: `jerbuild build`. +;; +;; jerbuild bundles Chez Scheme + the jerboa stdlib + the jerboa-native Rust +;; crate, so this needs only jerbuild + a C compiler + cargo — no jerboa +;; source checkout. jerboa-native provides rustls TLS, crypto, and +;; sqlite-native (no DuckDB). (entry "edge.ss") (output "jerboa-edge") -(requires "cc" "cargo" "bundled jerboa-native-rs") -(notes "Requires jerboa-native-rs for rustls TLS, crypto, and sqlite-native. DuckDB is not required.") (libdirs ".") +;; Static binary: a custom main.c sets JERBOA_STATIC=1 so the bundled std +;; modules skip dlopen of libjerboa_native and use the symbols registered from +;; the list below (the linked-in archive members would otherwise be +;; dead-stripped / unreachable via dlsym). +(main-c "support/static-main.c") +(ffi-symbols "support/ffi-symbols.list") (rust-crates ("@bundle/jerboa-native-rs/Cargo.toml" features: "tls,crypto,sqlite" --- a/Makefile +++ b/Makefile @@ -1,71 +1,37 @@ -JERBOA_HOME ?= $(HOME)/mine/jerboa -SCHEME = scheme --libdirs $(JERBOA_HOME)/lib -NATIVE = $(JERBOA_HOME)/jerboa-native-rs/target/release -DOCKER_IMAGE = jerboa21/jerboa - -.PHONY: run run-db run-tls test clean edge-static - -## Run the webhook service on port 8080 -run: - LD_LIBRARY_PATH=$(NATIVE) $(SCHEME) --script edge.ss - -## Run with custom port and workers -## Example: make run-custom PORT=9090 WORKERS=8 -run-custom: - LD_LIBRARY_PATH=$(NATIVE) \ - EDGE_PORT=$(or $(PORT),8080) \ - EDGE_WORKERS=$(or $(WORKERS),4) \ - EDGE_SECRET=$(or $(SECRET),) \ - $(SCHEME) --script edge.ss - -## Run with SQLite persistence (events survive restart) -## Example: make run-db DB=/var/lib/edge/events.db -run-db: - LD_LIBRARY_PATH=$(NATIVE) \ - EDGE_DB_PATH=$(or $(DB),/tmp/edge.db) \ - $(SCHEME) --script edge.ss - -## Run with TLS enabled (requires cert + key PEM files) -## Example: make run-tls CERT=tls/cert.pem KEY=tls/key.pem -run-tls: - LD_LIBRARY_PATH=$(NATIVE) \ - EDGE_TLS_CERT=$(or $(CERT),tls/cert.pem) \ - EDGE_TLS_KEY=$(or $(KEY),tls/key.pem) \ - EDGE_TLS_PORT=$(or $(TLS_PORT),8443) \ - $(SCHEME) --script edge.ss - -## Build a self-contained static Linux binary via Docker (Phase 3.1) -## Produces ./edge — runs on any x86_64 Linux with zero dependencies. -## Binary size target: <25MB -## Requires Docker and the jerboa21/jerboa base image: -## docker pull jerboa21/jerboa (or: make -C $(JERBOA_HOME) docker-build) -edge-static: - @echo "=== Building static edge binary ===" - docker run --rm \ - -v $(JERBOA_HOME):/build/mine/jerboa:ro \ - -v $(PWD):/build/edge \ - -w /build/edge \ - $(DOCKER_IMAGE) \ - /build/mine/jerboa/support/build-static-script.sh edge.ss edge - @echo "=== Built: ./edge ($$(du -sh edge | cut -f1)) ===" - @echo "Run: LD_LIBRARY_PATH= ./edge" - -## Run smoke tests against a running server -test: - ./test-edge.sh - -## Run with HMAC enabled for signature tests -test-hmac: - EDGE_SECRET=test-secret ./test-edge.sh - -## Benchmark with wrk (requires wrk) -bench: - ./bench-edge.sh - -## Syntax check (no server needed) -check: - LD_LIBRARY_PATH=$(NATIVE) $(SCHEME) --compile-imported-libraries --script /dev/null 2>&1 || true - @echo "Syntax OK" +# jerbuild bundles Chez Scheme + the jerboa stdlib + the jerboa-native Rust +# crate, so building jerboa-edge needs only `jerbuild`, a C compiler, and +# cargo — no jerboa source checkout and no separately-built Chez/native lib. +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 + +NATIVE_A := $(JH)/jerboa-native-rs/target/release/libjerboa_native.a +BIN := jerboa-edge +BIN_DIR := $(HOME)/.local/bin + +.PHONY: all build binary install clean + +all: binary + +# Standalone native binary via .jerbuild (entry edge.ss -> jerboa-edge). +# Two passes: the first cargo-builds jerboa-native into jerbuild's cache; we +# then regenerate the FFI symbol list from that archive (so it matches this +# platform — e.g. epoll on Linux) and relink. A static main.c sets +# JERBOA_STATIC=1 so the std modules use the registered symbols, not dlopen. +binary: + @test -f "$(NATIVE_A)" || $(JERBUILD) build + sh support/gen-ffi-symbols.sh + $(JERBUILD) build + +build: binary + +install: binary + mkdir -p $(BIN_DIR) + install -m 0755 $(BIN) $(BIN_DIR)/$(BIN) + @echo "Installed $(BIN) to $(BIN_DIR)/$(BIN)" clean: - @echo "Nothing to clean (single-file service)" + rm -f $(BIN) $(BIN)-main.c + find . \( -name '*.so' -o -name '*.wpo' \) -delete 2>/dev/null || true --- a/edge.ss +++ b/edge.ss @@ -1,4 +1,4 @@ -#!/usr/bin/env -S scheme --libdirs lib --script +#!chezscheme ;;; Jerboa Edge — Webhook Processing Service ;;; ;;; A single-file, production-grade webhook processor demonstrating: new file mode 100644 --- /dev/null +++ b/support/ffi-symbols.list @@ -0,0 +1,115 @@ +# jerboa-native FFI symbols registered via Sforeign_symbol() (see .jerbuild). +# AUTOGENERATED by support/gen-ffi-symbols.sh from libjerboa_native.a. + +jerboa_aead_open +jerboa_aead_seal +jerboa_antidebug_check_all +jerboa_antidebug_check_breakpoint +jerboa_antidebug_check_ld_preload +jerboa_antidebug_check_tracer +jerboa_antidebug_ptrace +jerboa_antidebug_timing_check +jerboa_aproc_close +jerboa_aproc_dup +jerboa_aproc_killpg +jerboa_aproc_set_nonblock +jerboa_aproc_spawn +jerboa_aproc_spawn_pty +jerboa_aproc_wait4 +jerboa_argon2id_hash +jerboa_argon2id_verify +jerboa_chacha20_open +jerboa_chacha20_seal +jerboa_deflate +jerboa_freebsd_is_traced +jerboa_freebsd_process_count +jerboa_gunzip +jerboa_gzip +jerboa_hkdf_sha256 +jerboa_hmac_sha256 +jerboa_hmac_sha256_verify +jerboa_inflate +jerboa_integrity_hash_file +jerboa_integrity_hash_region +jerboa_integrity_hash_self +jerboa_integrity_sign_verify +jerboa_integrity_verify_hash +jerboa_kill_probe +jerboa_last_error +jerboa_md5 +jerboa_mlockall +jerboa_pbkdf2_derive +jerboa_pbkdf2_verify +jerboa_prctl_set_name +jerboa_proc_self_exe +jerboa_random_bytes +jerboa_regex_captures +jerboa_regex_compile +jerboa_regex_compile_ex +jerboa_regex_find +jerboa_regex_find_at +jerboa_regex_free +jerboa_regex_group_count +jerboa_regex_is_match +jerboa_regex_replace_all +jerboa_scrypt +jerboa_secure_alloc +jerboa_secure_free +jerboa_secure_random_fill +jerboa_secure_wipe +jerboa_setproctitle +jerboa_sha1 +jerboa_sha256 +jerboa_sha384 +jerboa_sha512 +jerboa_socks5_server_port +jerboa_socks5_server_start +jerboa_socks5_server_stats +jerboa_socks5_server_stop +jerboa_sqlite_bind_blob +jerboa_sqlite_bind_double +jerboa_sqlite_bind_int +jerboa_sqlite_bind_null +jerboa_sqlite_bind_text +jerboa_sqlite_changes +jerboa_sqlite_close +jerboa_sqlite_column_blob +jerboa_sqlite_column_count +jerboa_sqlite_column_double +jerboa_sqlite_column_int +jerboa_sqlite_column_name +jerboa_sqlite_column_text +jerboa_sqlite_column_type +jerboa_sqlite_errmsg +jerboa_sqlite_exec +jerboa_sqlite_finalize +jerboa_sqlite_last_insert_rowid +jerboa_sqlite_open +jerboa_sqlite_prepare +jerboa_sqlite_reset +jerboa_sqlite_step +jerboa_timing_safe_equal +jerboa_tls_accept +jerboa_tls_close +jerboa_tls_connect +jerboa_tls_connect_mtls +jerboa_tls_connect_mtls_mem +jerboa_tls_connect_mtls_pem_ca +jerboa_tls_connect_pinned +jerboa_tls_flush +jerboa_tls_get_fd +jerboa_tls_read +jerboa_tls_server_free +jerboa_tls_server_new +jerboa_tls_server_new_mtls +jerboa_tls_server_new_mtls_pem +jerboa_tls_server_new_pem +jerboa_tls_set_nonblock +jerboa_tls_write +jerboa_x25519_diffie_hellman +jerboa_x25519_generate_keypair +jerboa_x25519_public_from_private +jerboa_x509_cert_fingerprint +jerboa_x509_generate_self_signed +jerboa_x509_generate_self_signed_mem +jerboa_x509_generate_signed_by_ca_mem new file mode 100755 --- /dev/null +++ b/support/gen-ffi-symbols.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Regenerate support/ffi-symbols.list from the jerboa-native archive that +# jerbuild cargo-builds into its bundle cache. Run before the final +# `jerbuild build` so the static binary registers exactly the jerboa_* symbols +# present for THIS platform (e.g. epoll on Linux, kqueue on macOS). +set -e +JH="$(jerbuild --jerboa-home 2>/dev/null)" +A="$JH/jerboa-native-rs/target/release/libjerboa_native.a" +OUT="$(dirname "$0")/ffi-symbols.list" +if [ ! -f "$A" ]; then + echo "gen-ffi-symbols: $A not found (run 'jerbuild build' once first)" >&2 + exit 0 +fi +{ + echo "# jerboa-native FFI symbols registered via Sforeign_symbol() (see .jerbuild)." + echo "# AUTOGENERATED by support/gen-ffi-symbols.sh from libjerboa_native.a." + echo "" + nm -gjU "$A" 2>/dev/null | sed 's/^_//' | grep -E '^jerboa_[A-Za-z0-9_]+$' | sort -u +} > "$OUT" +echo "gen-ffi-symbols: wrote $(grep -c '^jerboa_' "$OUT") symbols to $OUT"