#!/bin/sh set -eu script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd) bootstrap_root=$(CDPATH= cd -- "$script_dir/.." && pwd) builder_root_default=$HOME/.local/opt/fruix-builder builder_root=${FRUIX_BUILDER_ROOT:-$builder_root_default} guile_prefix=${FRUIX_BUILDER_GUILE_PREFIX:-$builder_root/guile} guile_extra_prefix=${FRUIX_BUILDER_GUILE_EXTRA_PREFIX:-$builder_root/guile-extra} shepherd_prefix=${FRUIX_BUILDER_SHEPHERD_PREFIX:-$builder_root/shepherd} guix_source_dir=${GUIX_SOURCE_DIR:-$builder_root/src/guix} guix_source_url=${GUIX_SOURCE_URL:-https://git.teralink.net/tribes/guix.git} guile_repo=${FRUIX_BOOTSTRAP_GUILE_REPO:-https://codeberg.org/guile/guile.git} guile_commit=${FRUIX_BOOTSTRAP_GUILE_COMMIT:-bbf2baa10f6cc8dfdd9e4ea14b503d748287a03d} fruix_channel_url=${FRUIX_CHANNEL_URL:-https://git.teralink.net/self/fruix.git} install_host_deps=1 jobs=${JOBS:-$(sysctl -n hw.ncpu 2>/dev/null || echo 4)} usage() { cat <&2 usage >&2 exit 1 ;; esac done guile_prefix=$builder_root/guile guile_extra_prefix=$builder_root/guile-extra shepherd_prefix=$builder_root/shepherd state_dir=$builder_root/state logs_dir=$builder_root/logs mkdir -p "$builder_root" "$state_dir" "$logs_dir" metadata_file=$builder_root/prepare-builder-metadata.txt env_file=$builder_root/env.sh have_working_guile() { [ -x "$guile_prefix/bin/guile" ] || return 1 EXPECT_GUILE_SUBPROCESS_CRASH=0 \ GUILE_BIN="$guile_prefix/bin/guile" \ "$bootstrap_root/tests/guile/run-subprocess-diagnostics.sh" >/dev/null 2>&1 } guile_module_probe() { module_code=$1 [ -x "$guile_prefix/bin/guile" ] || return 1 guile_bin=$guile_prefix/bin/guile guile_version=$(LD_LIBRARY_PATH="$guile_prefix/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" "$guile_bin" -c '(display (effective-version))') site_dir=$guile_extra_prefix/share/guile/site/$guile_version site_ccache_dir=$guile_extra_prefix/lib/guile/$guile_version/site-ccache extensions_dir=$guile_extra_prefix/lib/guile/$guile_version/extensions gui_load_path=${site_dir} gui_load_compiled_path=${site_ccache_dir} gui_extensions_path=${extensions_dir} env \ LD_LIBRARY_PATH="$guile_extra_prefix/lib:$guile_prefix/lib:/usr/local/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \ GUILE_LOAD_PATH="$gui_load_path" \ GUILE_LOAD_COMPILED_PATH="$gui_load_compiled_path" \ GUILE_EXTENSIONS_PATH="$gui_extensions_path" \ "$guile_bin" -c "$module_code" >/dev/null 2>&1 } have_shepherd() { [ -x "$shepherd_prefix/bin/shepherd" ] || return 1 [ -x "$shepherd_prefix/bin/herd" ] || return 1 guile_module_probe '(use-modules (fibers) (shepherd service)) (display "ok") (newline)' } run_step() { name=$1 shift printf '\n== %s ==\n' "$name" "$@" } if [ "$install_host_deps" -eq 1 ]; then run_step install-host-deps "$script_dir/install-host-deps.sh" fi if have_working_guile; then printf '\nUsing existing working Guile at %s\n' "$guile_prefix/bin/guile" else run_step build-local-guile env \ FRUIX_BOOTSTRAP_GUILE_REPO="$guile_repo" \ FRUIX_BOOTSTRAP_GUILE_COMMIT="$guile_commit" \ INSTALL_PREFIX="$guile_prefix" \ JOBS="$jobs" \ METADATA_OUT="$logs_dir/local-guile-build-metadata.txt" \ ENV_OUT="$logs_dir/local-guile-env.sh" \ "$script_dir/build-local-guile.sh" fi run_step setup-guix-source env \ GUIX_SOURCE_URL="$guix_source_url" \ GUIX_SOURCE_DIR="$guix_source_dir" \ METADATA_OUT="$logs_dir/guix-source-metadata.txt" \ "$script_dir/setup-guix-source.sh" if guile_module_probe '(use-modules (gnutls)) (display "ok") (newline)'; then printf '\nGuile (gnutls) already present in %s\n' "$guile_extra_prefix" else run_step build-local-guile-gnutls env \ GUILE_BIN="$guile_prefix/bin/guile" \ INSTALL_PREFIX="$guile_extra_prefix" \ GUIX_SOURCE_DIR="$guix_source_dir" \ JOBS="$jobs" \ "$bootstrap_root/tests/guix/build-local-guile-gnutls.sh" fi if guile_module_probe '(use-modules (bytestructures guile) (git)) (display "ok") (newline)'; then printf '\nGuile-Git stack already present in %s\n' "$guile_extra_prefix" else run_step build-local-guile-git env \ GUILE_BIN="$guile_prefix/bin/guile" \ INSTALL_PREFIX="$guile_extra_prefix" \ JOBS="$jobs" \ "$bootstrap_root/tests/guix/build-local-guile-git.sh" fi if guile_module_probe '(use-modules (json)) (display "ok") (newline)'; then printf '\nGuile-JSON already present in %s\n' "$guile_extra_prefix" else run_step build-local-guile-json env \ GUILE_BIN="$guile_prefix/bin/guile" \ INSTALL_PREFIX="$guile_extra_prefix" \ GUIX_SOURCE_DIR="$guix_source_dir" \ JOBS="$jobs" \ "$bootstrap_root/tests/guix/build-local-guile-json.sh" fi if guile_module_probe '(use-modules (sqlite3) (gcrypt hash) (lzlib) (semver)) (display "ok") (newline)'; then printf '\nGuile configure-time dependency modules already present in %s\n' "$guile_extra_prefix" else run_step build-local-guile-configure-deps env \ GUILE_BIN="$guile_prefix/bin/guile" \ INSTALL_PREFIX="$guile_extra_prefix" \ GUIX_SOURCE_DIR="$guix_source_dir" \ JOBS="$jobs" \ "$bootstrap_root/tests/guix/build-local-guile-configure-deps.sh" fi if guile_module_probe '(use-modules (fibers)) (display "ok") (newline)'; then printf '\nGuile Fibers already present in %s\n' "$guile_extra_prefix" else run_step build-local-guile-fibers env \ GUILE_BIN="$guile_prefix/bin/guile" \ INSTALL_PREFIX="$guile_extra_prefix" \ JOBS="$jobs" \ "$bootstrap_root/tests/shepherd/build-local-guile-fibers.sh" fi if have_shepherd; then printf '\nShepherd already present in %s\n' "$shepherd_prefix" else run_step build-local-shepherd env \ GUILE_BIN="$guile_prefix/bin/guile" \ GUILE_EXTRA_PREFIX="$guile_extra_prefix" \ INSTALL_PREFIX="$shepherd_prefix" \ GUIX_SOURCE_DIR="$guix_source_dir" \ JOBS="$jobs" \ "$bootstrap_root/tests/shepherd/build-local-shepherd.sh" fi guile_bin=$guile_prefix/bin/guile guile_version=$(LD_LIBRARY_PATH="$guile_prefix/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" "$guile_bin" -c '(display (effective-version))') site_dir=$guile_extra_prefix/share/guile/site/$guile_version site_ccache_dir=$guile_extra_prefix/lib/guile/$guile_version/site-ccache extensions_dir=$guile_extra_prefix/lib/guile/$guile_version/extensions guix_commit=$(git -C "$guix_source_dir" rev-parse HEAD) cat >"$env_file" <"$metadata_file" <