Access a library from within an ocamlmktop top level

I am building a top level using ocamlmktop, like so:

ocamlfind ocamlmktop -package camlpdf -linkpkg -o *.cmo

This is for a project, cpdf. which uses an exisiting library camlpdf.

Ocamlfind expands this to:

ocamlmktop -g -o -I /Users/john/.opam/4.13.1/lib/camlpdf /Users/john/.opam/4.13.1/lib/camlpdf/camlpdf.cma *.cmo

It succeeds, and we can access the cpdf functions, and they work because the camlpdf code has been included too. But we cannot access the functions from the included library camlpdf directly:

        OCaml version 4.13.1

# Cpdfcommand.go;;
- : unit -> unit = <fun>
Error: Unbound module Pdfutil

Is there a way to do so by changing my command, or are they always hidden? Do I need to re-export them manually somehow from within my source code?

As a first step, could you try passing -linkall to the ocamlmktop command ?
If the Pdfutil module is not used by the cpdf code, then it’s likely that it won’t get included when linking.
If you get the same error with -linkall or with modules that cpdf depends on, then it means that the problem is somewhere else.

Thanks. Cpdf does depend on CamlPDF. Nevertheless, I added -linkall and see no change.

Do you think that this general use-case is supposed to work, by the way?

They are always hidden. In general the toplevel built by ocamlmktop is like the vanilla toplevel in that respect: it needs to have access to the .cmi files in order to access them (ie by passing -I flags). ocamlmktop only makes sure that the implementation is linked in, the interfaces themselves are not embedded into the toplevel.

By the way, the same would be true for cpdf except that you seem to have launched the toplevel from the same directory that contains the .cmi's for these modules. Since the current directory is always part of the load path, these .cmi files were found by the toplevel without doing anything specific.


Thanks Nicolas. So there is no way to use ocamlmktop to produce a top level which is entirely self-contained - with all the .cmi files inside of it - so that I can ship it to users as a “PDF Repl”?

If not, then I think there is no purpose to installing or for the user at all: they will need a full working OCaml/ocamlfind installation, and then they can just use # require to load CamlPDF/CPDF.

There is a way, but it requires some code. See Distribute ocaml binary and cma files where it is discussed.


And in case you don’t want to read the whole thread, there is a minimal example (embedding the stdlib cmi’s) at GitHub - nojb/selfcontained-ocaml-toplevel: A self-contained ocaml toplevel (with `.cmi` files embedded in executable)


1 Like

Thanks. That looks great. I only need the stdlib, and camlpdf, so it looks doable.