ocaml-rs icon indicating copy to clipboard operation
ocaml-rs copied to clipboard

How to opam install a package that uses ocaml-rs

Open mimoo opened this issue 2 years ago • 5 comments

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") of dune file to avoid errors if dune files are present there (which is my case)
  • add all of that to the deps field in the dune rule
    deps
      (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?

mimoo avatar Jul 13 '21 16:07 mimoo

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!

zshipko avatar Jul 13 '21 17:07 zshipko

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 new data_only_dirs instead)
    • "The dirs stanza allows specifying the sub-directories dune will include in a build" (doc)
    • "One may also specify data only directories using the ignored_subdirs stanza" (doc)
  • it commits Cargo.lock files. I didn't do it, and I had issues as cargo vendor seems to sometimes produce some (for example with cc)

mimoo avatar Jul 13 '21 18:07 mimoo

OK so I got it working with https://github.com/mimoo/randoml

Basically:

  1. don't add Cargo.lock to your .gitignore
  2. run cargo vendor and follow instructions (which will have you add stuff to your .cargo/config file
  3. move the content of your .cargo/config file to a cargo-config file (this is a necessary hack due to a limitation of dune)
  4. 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

mimoo avatar Jul 14 '21 12:07 mimoo

(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.

mimoo avatar Jul 14 '21 17:07 mimoo

which links to more discussion here: https://discuss.ocaml.org/t/cargo-opam-packaging-of-a-rust-ocaml-project/5743

mimoo avatar Jul 15 '21 11:07 mimoo