Working with application data in packages

If I want to package up an application along with some associated data files, how do I refer to the data from within my app? I found the share field in the opam docs, but I couldn’t find any examples for how it’s used in practice.

1 Like

If you use dune to build your application, this is a convenient way to distribute and use additional files that your application can load at runtime : How to Load Additional Files at Runtime — dune documentation

2 Likes

thanks, that looks like just what i need! i notice it’s marked “experimental”, and presumably pretty new - was this just a problem with no good prescribed solution before that?

As far as I know, there was indeed no prescribed way to do that before, and every application had its own logic for what and how to install additional files, and how to find them at runtime.

I’ve generally preferred ocaml-crunch for this. It slurps up all of the files within a given source directory (subject to filters, if you specify them), and generates a regular OCaml module that holds sits contents. This yields a very easy-to-use, prebaked API for accessing the contents of that directory at runtime.

Just a rule in a dune file will do it:

(rule
 (target resources.ml)
 (deps (source_tree resources))
 (action (with-stdout-to %{target}
           (run ocaml-crunch -m plain resources))))

This generates a Resources module carrying the entire contents of a resources subdirectory. You can then access what was a file in that subdirectory very easily:

let file = Resources.read "path/to/file.js" in ...
8 Likes

@cemerick how does it relate to opam - ocp-ocamlres

Note that the dune sites feature is only relevant if your users are installing your package with dune or opam: How to Load Additional Files at Runtime — dune documentation

Chances are, if you’re talking about packaging up your application, you mean as just an executable and some associated files, which users would install without having to know about OCaml toolchain. In that case, the sites feature is not really relevant.

3 Likes

Why wouldn’t using findlib suffice ? Just use findlib to get the package directory ?

isn’t findlib part of the compile/link toolchain? never thought of using it at runtime.

ocamlfind is an executable that is part of the compile/link toolchain. And it’s built on findlib. But you can use findlib independently.

IIRC, I learned of ocaml-crunch first, and setting it up was very easy, so I never tried ocp-ocamlres.

1 Like