diff --git a/README.md b/README.md index 2cadf4d..33a6528 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,76 @@ --- -Integrating components written in different languages (like Haskell/Rust/C). +This repository is a small Rust/Haskell interop demo. -Current demo work lives in `haskell/` and `rust/`. +The current project demonstrates communication in both directions: -- `haskell/` contains a small Cabal project with a Haskell executable that calls into Rust and a foreign library that Rust can call back into. -- `rust/` contains the Rust C ABI exports plus a CLI path for Rust calling the Haskell foreign library. +- Haskell calling into Rust through a C ABI exposed by the Rust crate +- Rust calling back into Haskell through a Cabal `foreign-library` + +The code is intentionally small. The goal is to show the main integration mechanics and the main failure points without adding code generation or a large build stack. + +## What The Demo Contains + +- `rust/` - Rust exports a C ABI for Haskell and provides a CLI path that loads and calls the Haskell shared library +- `haskell/` - Haskell contains a small Cabal project with: + - an executable that calls Rust + - a shared foreign library that Rust calls + - small pure tests for the shared Haskell-side logic + +The boundary is deliberately C-shaped: + +- integers +- a shared struct layout +- owned C strings with explicit free functions on each side + +## Why The Build Uses Both Static And Shared Libraries + +This demo uses different library styles for the two directions because that keeps each path simpler: + +- Haskell -> Rust uses the Rust crate as a static library +- Rust -> Haskell uses a Haskell shared foreign library that Rust loads at runtime + +That is not the only possible design. It is just a practical one for a two-way demo. + +## Build And Run + +Build the Haskell project and the Rust library it links against: + +```sh +make haskell-build +``` + +Run the Haskell -> Rust demo: + +```sh +make haskell-run +``` + +Run the Rust -> Haskell demo: + +```sh +make rust-calls-haskell +``` + +You can also run the underlying commands directly: + +```sh +cargo test +``` + +```sh +cd haskell +CABAL_DIR=$PWD/../.cabal XDG_STATE_HOME=$PWD/../.cabal/state XDG_CACHE_HOME=$PWD/../.cabal/cache XDG_CONFIG_HOME=$PWD/../.cabal/config cabal test --project-file=cabal.project +``` + +## What This Project Demonstrates + +- the ABI boundary must stay simple and explicit +- Rust and Haskell do not share ownership rules automatically +- struct layout must match on both sides +- Rust calling Haskell is the harder direction because it must initialize the GHC runtime correctly +- build tooling is part of the integration problem, not just an implementation detail ### License