Compare commits

..

9 Commits
main ... wip

Author SHA1 Message Date
George Thomas
19e9aafe71 simple build script 2026-03-19 11:54:09 +00:00
George Thomas
1b45174f15 follow-up simplification 2026-03-19 11:54:09 +00:00
George Thomas
e70aac0f1b use upstream fix to avoid header patching hack 2026-03-19 11:54:09 +00:00
George Thomas
cdada4c9be symlink (plus messy comments) 2026-03-19 11:35:00 +00:00
George Thomas
c37b013467 Revert "ditch bash script for custom setup"
This reverts commit 1399946c4d582eaabb64cece292a48159b745e64.
2026-03-19 11:35:00 +00:00
George Thomas
22b6fac5b5 ditch bash script for custom setup
eugh, but this requires
"haskell.sessionLoading": "singleComponent"
2026-03-19 11:35:00 +00:00
George Thomas
927bf229a4 move bindings generation to Rust build script
bit cleaner, esp. as less hardcoding of "debug" path

instant updates all the way through to Haskell when we change Rust code
(this wasn't actually working at all before even when we did manually run the script, because TH file-dependency tracking seemed to get confused with the way that the Bash code moved a file to the header path rather than editing it)

should update to point to my comment on hs-bindgen

actually, isn't there a race condition here? the header files are generated before the new Rust code is actually compiled, and Cabal could in theory end up still linking against the old output

hardcoding "target" isn't great, though we do already do so in the Cabal file
there seems to be no env var for it though
docs suggest we're supposed to use OUT_DIR, but that has an unpredictable path... we could output the dir somewhere I suppose, and configure Cabal to use that, but that adds a fair bit of complexity

look in to https://doc.rust-lang.org/cargo/reference/build-scripts.html#change-detection?
bit blunt compared to e.g. Cabal Hooks, and anyway I think in the long run I'll be ditching `build.rs`, as discussed above
2026-03-19 11:35:00 +00:00
George Thomas
beb9e14542 drop hooks in favour of using bundled libraries properly
script addition is hacky, but I know no other way to get most of the build path, in arch/version-independent way
we'll use a custom setup or whatever eventually (_eventually_ hooks...) anyway
2026-03-19 11:35:00 +00:00
George Thomas
ffc59a418b remove cabal configure hack for lib/include dirs 2026-03-19 11:35:00 +00:00
5 changed files with 15 additions and 44 deletions

6
build
View File

@ -2,9 +2,5 @@
set -euo pipefail set -euo pipefail
cargo build --manifest-path ./rust/Cargo.toml cargo build --manifest-path ./rust/Cargo.toml
ln -sf $(pwd)/rust/target/debug/libgarnet_rs.a $(cabal list-bin . | sed -e 's=x/garnet/build/garnet/garnet=build=g')
BUNDLED_LIB_DIR=$(cabal list-bin . | sed -e 's=x/garnet/build/garnet/garnet=build=g')
mkdir -p $BUNDLED_LIB_DIR
ln -sf $(pwd)/rust/target/debug/libgarnet_rs.a $BUNDLED_LIB_DIR
cabal build cabal build

View File

@ -6,9 +6,9 @@ packages: .
source-repository-package source-repository-package
type: git type: git
location: https://github.com/well-typed/hs-bindgen location: https://github.com/well-typed/hs-bindgen
tag: 6ca94188abd756a1fb4dd8a4037de3fa7dca0765 tag: 94d74d3f3e72c8fabc85700f916387fe851ba20a
subdir: c-expr-dsl c-expr-runtime hs-bindgen hs-bindgen-runtime subdir: c-expr-dsl c-expr-runtime hs-bindgen hs-bindgen-runtime
--sha256: M+8tEZA8gsEc6gXnNdSbRpMBQ5LkH7sphcV1aR0fclA= --sha256: eM0CJj1HDAClvjkv5QUaF7aZoMwnPm4GuoLTkp8SHq8=
source-repository-package source-repository-package
type: git type: git
location: https://github.com/well-typed/libclang location: https://github.com/well-typed/libclang

View File

@ -15,7 +15,6 @@ module GarnetRs.Raw where
-- {-# LANGUAGE ExplicitLevelImports #-} -- {-# LANGUAGE ExplicitLevelImports #-}
-- import HsBindgen.Runtime.LibC qualified -- import HsBindgen.Runtime.LibC qualified
-- import splice Data.List -- import splice Data.List
-- import splice Data.Text qualified as T
-- import splice Data.Tuple.Extra -- import splice Data.Tuple.Extra
-- import splice HsBindgen.TH -- import splice HsBindgen.TH
-- import splice Language.Haskell.TH -- import splice Language.Haskell.TH

View File

@ -34,8 +34,8 @@ data Shape
| Rectangle CDouble CDouble | Rectangle CDouble CDouble
convertShape :: Shape -> Raw.Shape convertShape :: Shape -> Raw.Shape
convertShape = \case convertShape = \case
Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_body_circle $ Raw.Circle_Body r Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_anon0_circle $ Raw.Circle_Body r
Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_anon0_rectangle $ Raw.Rectangle_Body w h
data BTree a data BTree a
= Leaf a = Leaf a
@ -43,14 +43,14 @@ data BTree a
withBTree :: BTree Int64 -> (Raw.BTreeC -> IO a) -> IO a withBTree :: BTree Int64 -> (Raw.BTreeC -> IO a) -> IO a
withBTree = withBTree =
runContT . fix \f -> \case runContT . fix \f -> \case
Leaf v -> pure $ Raw.BTreeC Raw.Leaf $ Raw.set_bTreeC_body_leaf $ Raw.Leaf_Body v Leaf v -> pure $ Raw.BTreeC Raw.Leaf $ Raw.set_bTreeC_anon0_leaf $ Raw.Leaf_Body v
Fork l r -> do Fork l r -> do
lRaw <- f l lRaw <- f l
rRaw <- f r rRaw <- f r
lPtr <- ContT alloca lPtr <- ContT alloca
rPtr <- ContT alloca rPtr <- ContT alloca
lift $ poke lPtr lRaw >> poke rPtr rRaw lift $ poke lPtr lRaw >> poke rPtr rRaw
pure . Raw.BTreeC Raw.Fork . Raw.set_bTreeC_body_fork $ pure . Raw.BTreeC Raw.Fork . Raw.set_bTreeC_anon0_fork $
Raw.Fork_Body (unsafeFromPtr lPtr) (unsafeFromPtr rPtr) Raw.Fork_Body (unsafeFromPtr lPtr) (unsafeFromPtr rPtr)
hello :: ByteString -> IO () hello :: ByteString -> IO ()

View File

@ -1,43 +1,19 @@
use std::env; use std::env;
use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn main() { fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let profile = env::var("PROFILE").unwrap(); let profile = env::var("PROFILE").unwrap();
cbindgen::Builder::new()
let bindings = cbindgen::Builder::new()
.with_crate(&crate_dir) .with_crate(&crate_dir)
.with_language(cbindgen::Language::C) .with_language(cbindgen::Language::C)
.with_style(cbindgen::Style::Tag) .with_style(cbindgen::Style::Tag)
.generate() .generate()
.expect("Unable to generate bindings"); .expect("Unable to generate bindings")
.write_to_file(
// TODO vibe-coded workaround for hs-bindgen issue:
// https://github.com/well-typed/hs-bindgen/issues/1649#issuecomment-3994425922
let mut buf = Vec::new();
bindings.write(&mut buf);
let header = String::from_utf8(buf).unwrap();
let mut patched = String::new();
let mut saw_union = false;
for line in header.lines() {
if line == " };" && saw_union {
patched.push_str(" } body;\n");
saw_union = false;
continue;
}
if line == " union {" {
saw_union = true;
}
patched.push_str(line);
patched.push('\n');
}
fs::write(
PathBuf::from(&crate_dir) PathBuf::from(&crate_dir)
.join("target") .join("target")
.join(&profile) .join(&profile)
.join("garnet_rs.h"), .join("garnet_rs.h"),
patched, );
)
.unwrap();
} }