426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
253 lines
10 KiB
Bash
Executable File
253 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# build-riscv64-artifacts.sh — build-driver for every riscv64 cross-build
|
|
# the QEMU smoke harness consumes.
|
|
#
|
|
# Walks the same artifact list as scripts/check-riscv64-artifacts.sh and
|
|
# runs the relevant cross-build for each artifact that's missing. Each
|
|
# step is idempotent: if the output already exists and is rv64 ELF, the
|
|
# step is skipped (so callers can re-run cheaply).
|
|
#
|
|
# Gated on ELIZA_RISCV64_SMOKE=1 by default (same posture as the smoke
|
|
# harness). Unset = skip all builds.
|
|
#
|
|
# Tooling requirements (caller's job to install):
|
|
# - zig 0.14+ (Zig toolchain; provides riscv64-linux-musl — every
|
|
# cross-build here is zig/musl, so no Android NDK is needed)
|
|
# - cmake 3.21+ (drives every package's cross-build)
|
|
# - node 20+ (drives compile-libllama.mjs)
|
|
#
|
|
# Usage:
|
|
# ELIZA_RISCV64_SMOKE=1 bash scripts/build-riscv64-artifacts.sh
|
|
# ELIZA_RISCV64_SMOKE=1 bash scripts/build-riscv64-artifacts.sh --force # rebuild even if present
|
|
#
|
|
# Exit code:
|
|
# 0 — every reachable build succeeded (or already present)
|
|
# 1 — at least one build failed
|
|
# 2 — missing required toolchain (zig / cmake) — caller must install
|
|
|
|
set -euo pipefail
|
|
|
|
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$repo_root"
|
|
|
|
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
|
|
FORCE=0
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--jobs) JOBS="$2"; shift 2;;
|
|
--force) FORCE=1; shift;;
|
|
-h|--help)
|
|
awk '/^# /{print substr($0,3)} /^#$/{print ""} !/^#/{exit}' "$0"
|
|
exit 0;;
|
|
*) echo "unknown argument: $1" >&2; exit 2;;
|
|
esac
|
|
done
|
|
|
|
if [ "${ELIZA_RISCV64_SMOKE:-0}" != "1" ]; then
|
|
echo "[build-riscv64-artifacts] ELIZA_RISCV64_SMOKE not set; nothing to do."
|
|
echo "[build-riscv64-artifacts] To run: ELIZA_RISCV64_SMOKE=1 bun run build:riscv64-artifacts"
|
|
exit 0
|
|
fi
|
|
|
|
# ── Toolchain pre-flight ─────────────────────────────────────────────
|
|
ZIG_BIN="${ZIG_BIN:-$(command -v zig || true)}"
|
|
if [ -z "$ZIG_BIN" ]; then
|
|
cat >&2 <<'EOF'
|
|
[build-riscv64-artifacts] zig not on PATH.
|
|
|
|
Install Zig 0.14+ from https://ziglang.org/download/ — every cross-build in
|
|
this harness drives `zig cc --target=riscv64-linux-musl` directly.
|
|
|
|
EOF
|
|
exit 2
|
|
fi
|
|
ZIG_VERSION="$($ZIG_BIN version)"
|
|
ZIG_MAJOR_MINOR="$(printf '%s' "$ZIG_VERSION" | awk -F. '{ print $1"."$2 }')"
|
|
export ZIG_BIN
|
|
|
|
if ! command -v cmake >/dev/null 2>&1; then
|
|
echo "[build-riscv64-artifacts] cmake not on PATH. Install cmake 3.21+." >&2
|
|
exit 2
|
|
fi
|
|
|
|
NODE_BIN="${NODE_BIN:-$(command -v node || true)}"
|
|
if [ -z "$NODE_BIN" ]; then
|
|
echo "[build-riscv64-artifacts] node not on PATH. Install node 20+." >&2
|
|
exit 2
|
|
fi
|
|
RM_PATH_RECURSIVE="$repo_root/packages/scripts/rm-path-recursive.mjs"
|
|
|
|
remove_path_recursive() {
|
|
"$NODE_BIN" "$RM_PATH_RECURSIVE" "$@"
|
|
}
|
|
|
|
echo "[build-riscv64-artifacts] zig=$ZIG_VERSION cmake=$(cmake --version | head -1) node=$($NODE_BIN --version)"
|
|
echo "[build-riscv64-artifacts] jobs=$JOBS force=$FORCE"
|
|
|
|
# ── Helpers ──────────────────────────────────────────────────────────
|
|
FAIL_N=0
|
|
|
|
is_riscv64_elf() {
|
|
local f="$1"
|
|
[ -f "$f" ] || return 1
|
|
file -b "$f" 2>/dev/null | grep -q "UCB RISC-V"
|
|
}
|
|
|
|
should_build() {
|
|
# $1 = sentinel path. Returns 0 if we should build, 1 if we should skip.
|
|
local sentinel="$1"
|
|
if [ "$FORCE" = "1" ]; then return 0; fi
|
|
if [ -e "$sentinel" ]; then
|
|
echo " → up-to-date: $sentinel"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
build_native_plugin() {
|
|
local pkg="$1"; local extra_flag="${2:-}"
|
|
local pkgdir="$repo_root/packages/native/plugins/$pkg"
|
|
local builddir="$pkgdir/build/riscv64"
|
|
if [ ! -f "$pkgdir/CMakeLists.txt" ]; then
|
|
echo " ✗ $pkg: $pkgdir/CMakeLists.txt missing"
|
|
FAIL_N=$((FAIL_N+1))
|
|
return
|
|
fi
|
|
local sentinel_a="$builddir/lib${pkg%-cpu}.a"
|
|
case "$pkg" in
|
|
silero-vad-cpp) sentinel_a="$builddir/libsilero_vad.a";;
|
|
voice-classifier-cpp) sentinel_a="$builddir/libvoice_classifier.a";;
|
|
wakeword-cpp) sentinel_a="$builddir/libwakeword.a";;
|
|
yolo-cpp) sentinel_a="$builddir/libyolo.a";;
|
|
face-cpp) sentinel_a="$builddir/libface.a";;
|
|
doctr-cpp) sentinel_a="$builddir/libdoctr.a";;
|
|
polarquant-cpu) sentinel_a="$builddir/libpolarquant.a";;
|
|
turboquant-cpu) sentinel_a="$builddir/libturboquant.a";;
|
|
qjl-cpu) sentinel_a="$builddir/libqjl.a";;
|
|
esac
|
|
if ! should_build "$sentinel_a"; then return; fi
|
|
echo "→ Building $pkg (riscv64) …"
|
|
remove_path_recursive "$builddir"
|
|
mkdir -p "$builddir"
|
|
local config_log="$builddir.config.log"
|
|
local build_log="$builddir.build.log"
|
|
if [ -n "$extra_flag" ]; then
|
|
if ! cmake -S "$pkgdir" -B "$builddir" \
|
|
-DCMAKE_TOOLCHAIN_FILE="$repo_root/packages/native/cmake/toolchain-riscv64-linux-musl.cmake" \
|
|
"$extra_flag" >"$config_log" 2>&1; then
|
|
echo " ✗ $pkg: cmake configure failed (see $config_log)"
|
|
FAIL_N=$((FAIL_N+1)); return
|
|
fi
|
|
else
|
|
if ! cmake -S "$pkgdir" -B "$builddir" \
|
|
-DCMAKE_TOOLCHAIN_FILE="$repo_root/packages/native/cmake/toolchain-riscv64-linux-musl.cmake" \
|
|
>"$config_log" 2>&1; then
|
|
echo " ✗ $pkg: cmake configure failed (see $config_log)"
|
|
FAIL_N=$((FAIL_N+1)); return
|
|
fi
|
|
fi
|
|
if ! cmake --build "$builddir" -j"$JOBS" >"$build_log" 2>&1; then
|
|
echo " ✗ $pkg: cmake build failed (see $build_log)"
|
|
FAIL_N=$((FAIL_N+1)); return
|
|
fi
|
|
echo " ✓ $pkg: $builddir"
|
|
}
|
|
|
|
# RVV flag escapes for Zig 0.13 (same logic as
|
|
# scripts/verify-riscv64-buildpaths.sh). TurboQuant uses the generic
|
|
# CPU (no zvl* attribute) so LLVM's loop vectoriser emits portable
|
|
# vsetvli loops; a named core like sifive_x280 advertises VLEN=512
|
|
# via zvl512b and produces code that silently truncates at smaller
|
|
# VLEN (qemu-user reports VLEN=128, the RVV-spec minimum).
|
|
QJL_RVV=""; POLAR_RVV=""; TBQ_RVV=""
|
|
if [ "$ZIG_MAJOR_MINOR" = "0.13" ]; then
|
|
QJL_RVV="-DQJL_RVV_COMPILE_OPTIONS=-mcpu=sifive_x280;-mabi=lp64d"
|
|
POLAR_RVV="-DPOLARQUANT_RVV_COMPILE_OPTIONS=-mcpu=sifive_x280;-mabi=lp64d"
|
|
TBQ_RVV="-DTURBOQUANT_RVV_FLAGS=-mcpu=generic_rv64+v+m+a+f+d+c"
|
|
fi
|
|
|
|
# ── Native plugins ───────────────────────────────────────────────────
|
|
echo
|
|
echo "── Step 1: native plugins (CPU-side kernels + speech/vision libs) ──"
|
|
build_native_plugin qjl-cpu "$QJL_RVV"
|
|
build_native_plugin polarquant-cpu "$POLAR_RVV"
|
|
build_native_plugin turboquant-cpu "$TBQ_RVV"
|
|
build_native_plugin silero-vad-cpp ""
|
|
build_native_plugin voice-classifier-cpp ""
|
|
build_native_plugin wakeword-cpp ""
|
|
build_native_plugin yolo-cpp ""
|
|
build_native_plugin face-cpp ""
|
|
build_native_plugin doctr-cpp ""
|
|
|
|
# ── libllama family (MTP) ─────────────────────────────────────────
|
|
echo
|
|
echo "── Step 2: libllama / libggml family (MTP) ──"
|
|
COMPILE_LIBLLAMA="$repo_root/packages/app-core/scripts/aosp/compile-libllama.mjs"
|
|
if [ ! -f "$COMPILE_LIBLLAMA" ]; then
|
|
echo " ✗ compile-libllama.mjs missing at $COMPILE_LIBLLAMA"
|
|
FAIL_N=$((FAIL_N+1))
|
|
else
|
|
# compile-libllama.mjs exposes exactly one riscv64 target: android-riscv64-cpu.
|
|
# Despite the name it produces a Linux/musl shared object — zig
|
|
# `riscv64-linux-musl` driver, -DCMAKE_SYSTEM_NAME=Linux, no Android NDK in
|
|
# the compile, strip via `zig objcopy` (NDK llvm-strip is only a non-fatal
|
|
# last-resort fallback). So it is the canonical riscv64 libllama for both the
|
|
# APK and bare Linux riscv64, and it does NOT require the NDK. (There is no
|
|
# separate `linux-riscv64-cpu` libllama target; the earlier invocation of one
|
|
# always threw "unsupported --target".)
|
|
#
|
|
# repoRoot inside compile-libllama resolves to the consumer root, so
|
|
# its default --assets-dir/--src-dir would land in the wrong tree. Pin both
|
|
# to this eliza checkout so the .so installs where check-riscv64-artifacts.sh
|
|
# scans for it and the build uses the in-repo llama.cpp submodule.
|
|
libllama_assets_dir="$repo_root/packages/app-core/platforms/android/app/src/main/assets/agent"
|
|
libllama_sentinel="$libllama_assets_dir/riscv64/libllama.so"
|
|
libllama_src_args=()
|
|
if [ -f "$repo_root/plugins/plugin-local-inference/native/llama.cpp/CMakeLists.txt" ]; then
|
|
libllama_src_args=(--src-dir "$repo_root/plugins/plugin-local-inference/native/llama.cpp")
|
|
fi
|
|
if should_build "$libllama_sentinel"; then
|
|
echo "→ Building libllama (riscv64, zig/musl) …"
|
|
mkdir -p "$repo_root/build"
|
|
if "$NODE_BIN" "$COMPILE_LIBLLAMA" --target android-riscv64-cpu \
|
|
--assets-dir "$libllama_assets_dir" \
|
|
"${libllama_src_args[@]}" \
|
|
>"$repo_root/build/libllama-riscv64.log" 2>&1; then
|
|
echo " ✓ libllama riscv64"
|
|
else
|
|
echo " ✗ libllama riscv64 (see build/libllama-riscv64.log)"
|
|
FAIL_N=$((FAIL_N+1))
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# ── sigsys-handler-riscv64 ───────────────────────────────────────────
|
|
echo
|
|
echo "── Step 3: libsigsys-handler-riscv64 (Bun seccomp shim) ──"
|
|
COMPILE_SHIM="$repo_root/packages/app-core/scripts/aosp/compile-shim.mjs"
|
|
if [ ! -f "$COMPILE_SHIM" ]; then
|
|
echo " ✗ compile-shim.mjs missing at $COMPILE_SHIM"
|
|
FAIL_N=$((FAIL_N+1))
|
|
else
|
|
shim_sentinel="${HOME}/.cache/eliza-android-agent/seccomp-shim/riscv64/libsigsys-handler.so"
|
|
if should_build "$shim_sentinel"; then
|
|
echo "→ Building libsigsys-handler (riscv64) …"
|
|
mkdir -p "$repo_root/build"
|
|
if "$NODE_BIN" "$COMPILE_SHIM" --abi riscv64 >"$repo_root/build/libsigsys-handler-riscv64.log" 2>&1; then
|
|
echo " ✓ libsigsys-handler riscv64"
|
|
else
|
|
echo " ✗ libsigsys-handler riscv64 (see build/libsigsys-handler-riscv64.log)"
|
|
FAIL_N=$((FAIL_N+1))
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
if [ "$FAIL_N" -gt 0 ]; then
|
|
echo "[build-riscv64-artifacts] $FAIL_N build(s) failed."
|
|
exit 1
|
|
fi
|
|
echo "[build-riscv64-artifacts] All riscv64 artifacts built (or already present)."
|
|
exit 0
|