ocaml-rs
ocaml-rs copied to clipboard
How to opam install a package that uses ocaml-rs
Hey!
I'm trying to publish an opam package that wraps a rust library. So far I've tried the following:
- run
cargo vendor
- copy output of
cargo vendor
in.cargo/config
- add
vendor
in(dirs :standard \ "target" "vendor")
ofdune
file to avoid errors if dune files are present there (which is my case) - add all of that to the
deps
field in thedune
ruledeps (source_tree .) (source_tree .cargo) (source_tree vendor))
with all of that opam install .
still attempts to make a connection to github. Any idea of what else I might be missing?
I don’t have any experience with ocaml-rs + opam, but I believe this project is released on opam: https://github.com/c-cube/batsat-ocaml - maybe there are some hints in that repo? I can try to take a quick look at this later in the week if you’re still having issues.
Once you get something working I would be happy to add the steps to the readme!
Thanks for the pointer!
Interestingly this does a few things I didn't list or do:
- creates the
./cargo/config
as part of the dune action (this and this and this). My guess is that I'm stuck here because dune doesn't want to copy dot folders in the _build folder. BTW this should also mean that the.cargo/config
is not used in https://github.com/zshipko/ocaml-rust-starter/ - ignores the
vendor/
folder with the(ignored_subdirs
command, and not the(dirs
one (see this). According to the docs this seems like the right way of doing it (except that one should use the newdata_only_dirs
instead) - it commits
Cargo.lock
files. I didn't do it, and I had issues ascargo vendor
seems to sometimes produce some (for example with cc)
OK so I got it working with https://github.com/mimoo/randoml
Basically:
- don't add
Cargo.lock
to your.gitignore
- run
cargo vendor
and follow instructions (which will have you add stuff to your.cargo/config
file - move the content of your
.cargo/config
file to acargo-config
file (this is a necessary hack due to a limitation of dune) - use the following
dune
file:; forbid dune from building things in `target/` and `vendor/` (data_only_dirs "target" "vendor") ; creates the rust library if any rust file changes (rule (targets libXXX.a dllXXX.so) (deps (source_tree .) (source_tree vendor)) (action (progn ; this is to circumvent a dumb limitation of dune ; which prevents us from copying any .folder to _build (run mkdir -p .cargo) (run cp cargo-config.toml .cargo/config.toml) ; cargo build (run cargo build --release --offline) ; extract the produced static library ; the .so fluff is here to remove errors that we sometimes get from dune (run sh -c "mv target/release/libXXX.so ./dllXXX.so 2> /dev/null || mv target/release/libXXX.dylib ./dllXXX.so 2> /dev/null || touch dllXXX.so") (run cp target/release/libXXX.a .)))) ; the FFI OCaml lib (library (name YYY) (public_name YYY) (foreign_archives XXX))
note the fluff with the .so
which I had to write. It looks a bit different than the one you have on https://github.com/zshipko/ocaml-rust-starter/blob/master/src/dune because in my case there's never any .so produced (macOS) so I need to produce a dumb one with touch
(btw this seems to mostly work, on some distributions it doesn't: https://github.com/ocaml/opam-repository/pull/19057). I'm wondering if we could create a package like conf-rust-2018
that either contains a rust-toolchain
file or that uses a specific version when building with cargo, to see if the version is installed on the system.
which links to more discussion here: https://discuss.ocaml.org/t/cargo-opam-packaging-of-a-rust-ocaml-project/5743