2026-02-19 11:08:20 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
# TODO this is a complete vibe-coded hack, but the header patching at least is crucial
|
|
|
|
|
|
2026-02-20 09:08:16 +00:00
|
|
|
# Prepare Rust artifacts and C header for hs-bindgen.
|
2026-02-19 11:08:20 +00:00
|
|
|
#
|
2026-02-19 15:00:46 +00:00
|
|
|
# Pipeline:
|
|
|
|
|
# 1. cargo build - build the Rust static library
|
|
|
|
|
# 2. cbindgen - generate a C header from the Rust source
|
|
|
|
|
# 3. awk - patch the header for hs-bindgen compatibility
|
2026-02-20 09:08:16 +00:00
|
|
|
# 4. cabal configure - point Cabal at the Rust build artifacts
|
2026-02-19 11:08:20 +00:00
|
|
|
#
|
2026-02-20 09:08:16 +00:00
|
|
|
# System include paths (needed by libclang on NixOS) are detected
|
|
|
|
|
# automatically at TH compile time by GarnetRs.Raw — no env vars needed.
|
|
|
|
|
#
|
|
|
|
|
# Prerequisites: run inside the Nix dev shell (provides gcc, cabal, cbindgen).
|
2026-02-19 11:08:20 +00:00
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
|
RUST_DIR="$SCRIPT_DIR/rust"
|
|
|
|
|
HEADER_NAME="garnet_rs.h"
|
|
|
|
|
HEADER="$RUST_DIR/$HEADER_NAME"
|
|
|
|
|
|
|
|
|
|
# --- Step 1: Build Rust static library ---
|
|
|
|
|
echo "=== Building Rust library ==="
|
|
|
|
|
cargo build --manifest-path "$RUST_DIR/Cargo.toml"
|
|
|
|
|
|
|
|
|
|
# --- Step 2: Generate C header with cbindgen ---
|
|
|
|
|
echo "=== Running cbindgen ==="
|
2026-02-19 12:56:10 +00:00
|
|
|
cbindgen \
|
2026-02-19 11:08:20 +00:00
|
|
|
--lang c \
|
|
|
|
|
--crate garnet-rs \
|
|
|
|
|
--output "$HEADER" \
|
2026-02-19 16:18:58 +00:00
|
|
|
--style tag \
|
2026-02-19 11:08:20 +00:00
|
|
|
"$RUST_DIR"
|
|
|
|
|
|
|
|
|
|
echo " Raw header written to $HEADER"
|
|
|
|
|
|
|
|
|
|
# --- Step 3: Patch the header for hs-bindgen compatibility ---
|
|
|
|
|
#
|
2026-02-19 16:17:29 +00:00
|
|
|
# cbindgen emits: union { ... }; (anonymous)
|
|
|
|
|
# hs-bindgen needs: union { ... } body; (named)
|
|
|
|
|
# See: https://github.com/well-typed/hs-bindgen/issues/1649
|
2026-02-19 15:00:46 +00:00
|
|
|
echo "=== Patching header ==="
|
2026-02-19 11:08:20 +00:00
|
|
|
awk '
|
|
|
|
|
# Name anonymous unions: }; at end of union block inside struct -> } body;
|
|
|
|
|
/^ \};$/ && saw_union {
|
|
|
|
|
print " } body;"
|
|
|
|
|
saw_union = 0
|
|
|
|
|
next
|
|
|
|
|
}
|
|
|
|
|
/^ union \{$/ {
|
|
|
|
|
saw_union = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{ print }
|
|
|
|
|
' "$HEADER" > "${HEADER}.tmp" && mv "${HEADER}.tmp" "$HEADER"
|
|
|
|
|
|
|
|
|
|
echo " Patched header at $HEADER"
|
|
|
|
|
|
2026-02-20 09:08:16 +00:00
|
|
|
# --- Step 4: Configure Cabal ---
|
2026-02-19 15:00:46 +00:00
|
|
|
#
|
|
|
|
|
# Point Cabal at the Rust static library and C header. This writes
|
|
|
|
|
# cabal.project.local (gitignored) with absolute paths derived from
|
|
|
|
|
# the current working directory, avoiding hardcoded paths in cabal.project.
|
|
|
|
|
echo "=== Configuring Cabal ==="
|
|
|
|
|
cabal configure \
|
|
|
|
|
--extra-lib-dirs="$RUST_DIR/target/debug" \
|
|
|
|
|
--extra-include-dirs="$RUST_DIR"
|
|
|
|
|
|
2026-02-19 11:08:20 +00:00
|
|
|
echo "=== Done ==="
|
2026-02-19 14:15:14 +00:00
|
|
|
echo "Run 'cabal run' to test."
|