ocamlocamlfind

ocamlfind complains no implementation provided for modules installed through opam


I was messing around with the OCaml FFI to try to figure out how it goes about inferring the width of a C enum (which I think is implementation-defined for C) and am trying to insert a type of the wrong width to see what blows up at runtime. That's the motivation, but the actual issue I ran into is much more mundane.

I have a simple OCaml file that uses the C FFI to call a trivial function in example.c that converts an enum to an int.

open Printf;;

let (@->) = Ctypes.(@->);;
let returning = Ctypes.returning;;

let foreign = Foreign.foreign;;

(* deliberately use the wrong scalar type for argument *)
let wrong_int64_of_color =
  foreign "int_of_color" (Ctypes.int64_t @-> returning Ctypes.int64_t);;

let main () =
  printf "%Ld\n" (wrong_int64_of_color (Int64.of_int 100));;

let () = main ();;

I configured opam and installed Ctypes and Ctypes.Foreign

    % opam config env | sed -e 's/=.*/=/'
CAML_LD_LIBRARY_PATH=
OPAMUTF8MSGS=
MANPATH=
PERL5LIB=
OCAML_TOPLEVEL_PATH=
PATH=

% opam list | grep ctypes
ctypes                      0.6.2  Combinators for binding to C libraries withou
ctypes-foreign              0.4.0  Virtual package for enabling the ctypes.forei

The two usual incantations I use for compiling a simple .ml script have both failed me and I'm out of ideas. ocamlfind and corebuild (which I think is a wrapper on top of ocamlbuild)

ocamlfind can't seem to find ctypes and foreign. However, it doesn't complain that about not being able to locate the packages so I'm guessing ctypes and ctypes.foreign are the correct names for these packages in the weird findlib namespace.

% ocamlfind ocamlopt -package findlib,ctypes,ctypes.foreign -thread call_example.ml
File "_none_", line 1:
Warning 58: no cmx file was found in path for module Foreign, and its interface was not compiled with -opaque
File "call_example.ml", line 1:
Error: No implementations provided for the following modules:
         Ctypes referenced from call_example.cmx
         Foreign referenced from call_example.cmx

Why can't ocamlfind locate these modules? I have no problem loading them into the toplevel.

─( 22:30:42 )─< command 0 
utop # #require "ctypes";;
─( 22:30:42 )─< command 1 
utop # open Ctypes;;
─( 22:30:55 )─< command 2 
utop # #require "ctypes.foreign";;
─( 22:31:00 )─< command 3 
utop # open Ctypes;;

Solution

  • It seems to me that you forget to add -linkpkg ocamlfind option to instruct the compiler actually link the libraries from the packages to build the executable.