Avoid absolute path hack
This commit is contained in:
parent
25875c7dc1
commit
ddc8b9097d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
dist*
|
||||
result
|
||||
target
|
||||
cabal.project.local*
|
||||
|
||||
@ -1,13 +1,5 @@
|
||||
packages: .
|
||||
|
||||
-- TODO a total hack
|
||||
package garnet
|
||||
extra-lib-dirs:
|
||||
/home/gthomas/code/garnet/rust/target/release
|
||||
/home/gthomas/code/garnet/rust/target/debug
|
||||
extra-include-dirs:
|
||||
/home/gthomas/code/garnet/rust
|
||||
|
||||
-- https://well-typed.com/blog/2026/02/hs-bindgen-alpha
|
||||
-- Haskell.nix doesn't seem to like `tag: release-0.1-alpha`, which the blog post suggests
|
||||
-- so we specify the equivalent commit SHAs manually instead
|
||||
|
||||
@ -5,7 +5,12 @@ set -euo pipefail
|
||||
|
||||
# Generate Haskell FFI bindings from Rust source code.
|
||||
#
|
||||
# Pipeline: cargo build -> cbindgen -> patch header -> 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. hs-bindgen-cli - generate Haskell FFI modules from the C header
|
||||
# 5. cabal configure - point Cabal at the Rust build artifacts
|
||||
#
|
||||
# Prerequisites: run inside the Nix dev shell (provides gcc, cabal, cbindgen, hs-bindgen-cli).
|
||||
|
||||
@ -30,18 +35,21 @@ cbindgen \
|
||||
echo " Raw header written to $HEADER"
|
||||
|
||||
# --- Step 3: Patch the header for hs-bindgen compatibility ---
|
||||
#
|
||||
# Two patches are needed, both due to hs-bindgen limitations with cbindgen's
|
||||
# output for #[repr(C, u8)] tagged enums:
|
||||
#
|
||||
# 1. cbindgen emits: enum Shape_Tag { Circle, Rectangle, };
|
||||
# typedef uint8_t Shape_Tag;
|
||||
# hs-bindgen needs: typedef uint8_t Shape_Tag;
|
||||
# #define Circle 0
|
||||
# #define Rectangle 1
|
||||
# See: no upstream issue yet for hs-bindgen
|
||||
#
|
||||
# 2. cbindgen emits: union { ... }; (anonymous)
|
||||
# hs-bindgen needs: union { ... } body; (named)
|
||||
# See: https://github.com/well-typed/hs-bindgen/issues/1649
|
||||
echo "=== Patching header ==="
|
||||
|
||||
# Two patches are needed:
|
||||
#
|
||||
# Patch 1: Replace cbindgen's enum pattern with typedef + #defines.
|
||||
# cbindgen emits: enum Shape_Tag { Circle, Rectangle, }; typedef uint8_t Shape_Tag;
|
||||
# hs-bindgen needs: typedef uint8_t Shape_Tag; #define Circle 0 ...
|
||||
#
|
||||
# Patch 2: Name anonymous unions inside structs.
|
||||
# cbindgen emits: union { ... };
|
||||
# hs-bindgen needs: union { ... } body;
|
||||
|
||||
awk '
|
||||
# State machine for enum->typedef+define transformation
|
||||
/^enum [A-Za-z_][A-Za-z0-9_]* \{$/ {
|
||||
@ -94,11 +102,11 @@ pending_enum && /^typedef [A-Za-z0-9_]+ / {
|
||||
echo " Patched header at $HEADER"
|
||||
|
||||
# --- Step 4: Derive system include paths for hs-bindgen's libclang ---
|
||||
echo "=== Detecting system include paths ==="
|
||||
|
||||
#
|
||||
# hs-bindgen uses libclang directly, which doesn't know about NixOS's
|
||||
# non-standard include locations. We extract them from cpp -v and pass
|
||||
# all of them — extra paths are harmless.
|
||||
echo "=== Detecting system include paths ==="
|
||||
CLANG_OPTIONS=()
|
||||
while IFS= read -r dir; do
|
||||
CLANG_OPTIONS+=("--clang-option" "-isystem$dir")
|
||||
@ -122,6 +130,17 @@ hs-bindgen-cli preprocess \
|
||||
"${CLANG_OPTIONS[@]}" \
|
||||
-I "$RUST_DIR" "$HEADER_NAME"
|
||||
|
||||
# --- Step 6: 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-lib-dirs="$RUST_DIR/target/release" \
|
||||
--extra-include-dirs="$RUST_DIR"
|
||||
|
||||
echo "=== Done ==="
|
||||
echo "Generated Haskell bindings in $HASKELL_DIR/generated/"
|
||||
echo "Run 'cabal run' to test."
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user