Ocamlfind : No implementations provided for the following modules: Dream

opam version : 2.1.5

I am trying to compile a minimal project with ocamlfind and ocamlopt to make a dream server

let () =
  Dream.run (fun _ ->
    Dream.html "Good morning, world!")

When lauching the following commands

eval $(opam config env)
ocamlfind ocamlopt -thread -package dream server.ml -o server

I get from the command line :

File "server.ml", line 1:
Error: No implementations provided for the following modules:
         Dream referenced from server.cmx

while dream is installed with opam and is shown when listing library with ocamlfind list

Could you try adding -linkpkg switch?

Thank you for your response

No, actually it changes the error message but ocaml still complain dream is not linked
the error is now

Error: No implementations provided for the following modules:
         Digestif referenced from /home/frederic/.opam/4.13.1/lib/dream/http/dream__http.cmxa(Dream__http__Http)

while digestif is installed and the compile command is updated to

ocamlfind ocamlopt -thread -linkpkg -package dream,digestif test.ml -o test

Hi, is there any strong reason why you are not using dune? Dream works very well with dune especially because dune’s watch mode can automatically recompile and restart your server on code change. And Dream’s livereload feature will also automatically force a page reload. It’s a very productive workflow.

Yes, I have to include some library store in my local file system that are not compile with dune. I use the -I ../../lib flag with ocamlfind to include such dependency. As far as I know dune is not good to include custom dependency ‘<>.cmxa’ so I fall back to the standard ocamlfind build process

Seems like it wouldn’t be very difficult: Dune with external Ocaml library - #2 by nojb

Ie place the archive in a specific location and write a META file for it. Then dune will find it using findlib conventions.

Eg a META file output by dune:

version = "v3.0.1"
description = ""
requires = "dream"
archive(byte) = "dream_html.cma"
archive(native) = "dream_html.cmxa"
plugin(byte) = "dream_html.cma"
plugin(native) = "dream_html.cmxs"

my intended library contains only generation.cmx, generation.cmi, generation.o file, how could they be linked with archive and plugin ?

EDIT: the first proposed solution with the -linkpkg switch does not work, see response above

Unfortunately this turned out to be more difficult than I thought. I made some progress but got stuck on a dead end. Maybe someone smarter than me can figure out how to make it work. Here are my steps in case anyone wants to reproduce (I am assuming a standard setup with an opam switch and dune):

# Set up project
mkdir cmxproj
cd cmxproj
echo '(lang dune 3.6)' >dune-project
mkdir cmxpkg bin

# Set up a fake cmx-only 'library' for testing
cd cmxpkg
echo 'let x = 1' >cmxpkg.ml
ocamlopt -c cmxpkg.ml -o cmxpkg.o
cat <<EOF >META
version = "0.0.1"
description = ""
archive(native) = "cmxpkg.cmxa"
EOF

# Create the archive files
ocamlopt -a cmxpkg.cmx cmxpkg.o -o cmxpkg.cmxa cmxpkg.a

# Install the fake 'library' in the switch
ocamlfind install cmxpkg META cmxpkg.a cmxpkg.cmi cmxpkg.cmx cmxpkg.cmxa cmxpkg.a

# Use the fake library
cd ../bin
echo '(executable (name bin) (libraries cmxpkg))' >dune
echo 'let () = print_int Cmxpkg.x' >bin.ml

# Build
cd ..
dune build

Here’s the error I get:

File "bin/dune", line 2, characters 7-10:
2 |  (name bin)
           ^^^
clang: error: no such file or directory: 'cmx.o'
clang: error: no such file or directory: 'cmx.a'
File "caml_startup", line 1:
Error: Error during linking (exit code 1)

Which I can’t figure out because both of the mentioned files are installed in the cmxpkg package directory by ocamlfind. And Google is not particularly helpful here because it looks like approximately no one is doing this :slight_smile:

For this specific issue, you must choose an implementation of digestif:

  • the C implementation (fast)
  • the OCaml implementation (portable and usable with js_of_ocaml)

With ocamlfind, it consists to put in front of any other packages (to the -packages argument) digestif.c or digestif.ocaml.

2 Likes