Call Rust from Haskell with cargo-cabal and hs-bindgen
See https://sraka.xyz/posts/hs-bindgen-introduction.html. For now, this is a shell-based workflow, rather than using Nix to build everything, i.e. `nix develop` works but `nix build` doesn't. And `cargo build` has to be called manually to create the C library, rather than `cabal` being clever enough to invoke it itself. We ran `cargo cabal init` from the `rust` directory (`nix shell github:yvan-sraka/cargo-cabal`), which generated `hsbindgen.toml` (which we use), and `Setup.lhs` (which just added `extra-lib-dirs`, and with the wrong paths, so we dspecify those statically instead in `garnet.cabal`). We also follow its advice to use `staticlib`. Also, after we ran the first `cargo build` (requiring a `mkdir rust/src` before it would run), we took the generated the Haskell file, and moved the main contents in to `Main.hs` manually.
This commit is contained in:
parent
ff8826d758
commit
7bb41f6825
@ -63,10 +63,6 @@
|
|||||||
rust-analyzer
|
rust-analyzer
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
packages = {
|
|
||||||
haskell = haskell.packages."garnet:exe:garnet";
|
|
||||||
rust = rust.buildPackage { src = rust.cleanCargoSource ./rust; };
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
|
import Foreign.C.String (CString, withCString)
|
||||||
|
|
||||||
|
foreign import ccall safe "__c_hello" hello :: CString -> IO ()
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = withCString "Haskell" hello
|
||||||
putStrLn "Hello from Haskell"
|
|
||||||
|
|||||||
@ -33,5 +33,11 @@ executable garnet
|
|||||||
-threaded
|
-threaded
|
||||||
-rtsopts
|
-rtsopts
|
||||||
-with-rtsopts=-N
|
-with-rtsopts=-N
|
||||||
|
extra-lib-dirs:
|
||||||
|
-- TODO referring to parent triggers warning - maybe put Rust stuff in subdir
|
||||||
|
-- TODO bit weird to have both of these, but it's what the `cargo-cabal` setup script did
|
||||||
|
../rust/target/release
|
||||||
|
../rust/target/debug
|
||||||
|
extra-bundled-libraries: garnet_rs
|
||||||
build-depends:
|
build-depends:
|
||||||
base >= 4.14,
|
base >= 4.14,
|
||||||
|
|||||||
214
rust/Cargo.lock
generated
214
rust/Cargo.lock
generated
@ -3,5 +3,217 @@
|
|||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garnet"
|
name = "antlion"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd743dc9b5cf465db1be79d28b4bfd7fa143d289546afeea5dc933551883e1f6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "displaydoc"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.116",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "garnet-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"hs-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hs-bindgen"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e9723a81f9f23c3e52b01ce72db20c7ab384c8618b1032eea04985260d10fc7"
|
||||||
|
dependencies = [
|
||||||
|
"hs-bindgen-attribute",
|
||||||
|
"hs-bindgen-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hs-bindgen-attribute"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e57fc3cb0491f749fc50e7cf186c189b64af557edb9f78e36eb78bb9021d6624"
|
||||||
|
dependencies = [
|
||||||
|
"antlion",
|
||||||
|
"displaydoc",
|
||||||
|
"hs-bindgen-types",
|
||||||
|
"lazy_static",
|
||||||
|
"quote",
|
||||||
|
"rustc_version",
|
||||||
|
"semver 1.0.27",
|
||||||
|
"serde",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"thiserror",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hs-bindgen-traits"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e92e839254ee5975299f64183e8346548c4ba5e4ee0253a05426891a6f135a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hs-bindgen-types"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2d986de5641ea4aa8025589d7243e403961fb0f5572c4dd4764a1bb4a01768c"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.116",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.116"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.116",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garnet"
|
name = "garnet-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[[bin]]
|
[lib]
|
||||||
path = "main.rs"
|
path = "lib.rs"
|
||||||
name = "garnet"
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hs-bindgen = { version = "0.8", features = ["full"] }
|
||||||
|
|||||||
13
rust/hsbindgen.toml
Normal file
13
rust/hsbindgen.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Since the only `.cabal` format parser implementation and specification live
|
||||||
|
# in Cabal itself ... this deadly simple config file is used by `hs-bindgen`
|
||||||
|
# Rust crate to get needed data (like default exposed module name).
|
||||||
|
|
||||||
|
default = "GarnetRs"
|
||||||
|
|
||||||
|
# There is an unlikely future where instead we have a Rust `.cabal` parser,
|
||||||
|
# that most likely would rely under the hood on a Haskell static lib wrapper
|
||||||
|
# of `Cabal.Parse` or https://hackage.haskell.org/package/Cabal-syntax library.
|
||||||
|
# But even in this case, it would be nice to know the `cargo-cabal` version that
|
||||||
|
# generated the `.cabal` file used.
|
||||||
|
|
||||||
|
version = "0.8.0"
|
||||||
6
rust/lib.rs
Normal file
6
rust/lib.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use hs_bindgen::*;
|
||||||
|
|
||||||
|
#[hs_bindgen(hello :: CString -> IO (()))]
|
||||||
|
fn hello(name: &str) {
|
||||||
|
println!("Hello from Rust, {name}!");
|
||||||
|
}
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
println!("Hello from Rust");
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user