#!/usr/bin/env bash set -euo pipefail # TODO this is a complete vibe-coded hack, but the header patching at least is crucial # Prepare Rust artifacts and C header for hs-bindgen. # # 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 # 4. cabal configure - point Cabal at the Rust build artifacts # # 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). SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" RUST_DIR="$SCRIPT_DIR/rust" HEADER_NAME="garnet_rs.h" HEADER="$RUST_DIR/target/debug/$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 ===" cbindgen \ --lang c \ --crate garnet-rs \ --output "$HEADER" \ --style tag \ "$RUST_DIR" echo " Raw header written to $HEADER" # --- Step 3: Patch the header for hs-bindgen compatibility --- # # cbindgen emits: union { ... }; (anonymous) # hs-bindgen needs: union { ... } body; (named) # See: https://github.com/well-typed/hs-bindgen/issues/1649 echo "=== Patching header ===" 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" # --- Step 4: Configure Cabal --- # # 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/target/debug" echo "=== Done ===" echo "Run 'cabal run' to test."