#!/usr/bin/env bash # # build.sh - Compile the Neuron soul-binary. # # Pipeline: # 1. elb resolves the import graph from soul.el and runs `elc ` per # module, emitting one .c file per .el into dist/. # 2. cc links all dist/*.c plus el_runtime.c into a single native binary # (dist/neuron). elb's own link step does not pass -I for the runtime # headers, so we run cc ourselves. # 3. Refresh dist/soul-el so the launchctl plist (which execs dist/soul -> # dist/soul-el -> dist/neuron) picks up the new binary. # # Usage: # ./build.sh - build dist/neuron and refresh dist/soul-el # ./build.sh --kickstart - also kickstart the launchctl service # # Environment overrides: # EL_HOME - path to foundation/el (default: ../foundation/el) set -euo pipefail cd "$(dirname "$0")" NEURON_DIR=$(pwd) EL_HOME="${EL_HOME:-${NEURON_DIR}/../foundation/el}" ELB="${EL_HOME}/dist/platform/elb" ELC="${EL_HOME}/dist/platform/elc" RUNTIME_DIR="${EL_HOME}/el-compiler/runtime" if [ ! -x "${ELB}" ] || [ ! -x "${ELC}" ]; then echo "elb/elc not found in ${EL_HOME}/dist/platform" >&2 exit 1 fi if [ ! -f "${RUNTIME_DIR}/el_runtime.c" ]; then echo "runtime not found at ${RUNTIME_DIR}" >&2 exit 1 fi mkdir -p dist rm -f dist/*.c dist/*.elh echo "==> elb compile (manifest entry: soul.el)" PATH="${EL_HOME}/dist/platform:${PATH}" "${ELB}" --runtime="${RUNTIME_DIR}" \ > /tmp/neuron-elb.log 2>&1 || true # elb's link step lacks -I for the runtime headers, so we always re-link # manually below regardless of what elb reported. OUT="dist/neuron" echo "==> cc link -> ${OUT}" cc -O2 -I "${RUNTIME_DIR}" \ -o "${OUT}" \ dist/*.c \ "${RUNTIME_DIR}/el_runtime.c" \ -lcurl -lpthread echo "==> refresh dist/soul-el -> dist/neuron" ( cd dist && ln -sf neuron soul-el ) echo "==> built $(stat -f '%z' ${OUT}) bytes -> ${OUT}" if [ "${1:-}" = "--kickstart" ]; then echo "==> launchctl kickstart soul" launchctl kickstart -k "gui/$(id -u)/ai.neurontechnologies.soul" fi