I’m trying to make an OCaml binding to a C++ library and use it as an ocamlfind
package.
My goal is to avoid having to deal with the DLL paths when using the library.
It works well when using the bytecode library, but it is failing when using the native one.
It seems to me that I misunderstood the dllXXX.so convention
The library is currently built with ocamlmklib
with something like:
ocamlfind ocamlmklib -o myLib -package my,package,list -lDependentLib object_file.o module.cmo module.cmx
and installed with ocamlfind
:
ocamlfind install mypackage META myLib.a myLib.cma myLib.cmxa module.cmi module.cmt module.cmx -dll dllmyLib.so
dllmyLib.so
is stored in curret $CAML_LD_LIBRARY_PATH
directory.
Library usage:
$ ls
test_program.ml
$ touch _tags
$ ocamlbuild -use-ocamlfind -pkg mypackage test_program.byte
The bytecode version of my test_program compiles and work. Nice.
But the native version is failing to compile. My interpretation is that -cclib -lmyLib' was stored in the
.cmxa`:
$ ocamlbuild -use-ocamlfind -pkg mypackage test_program.native
+ ocamlfind ocamlopt -linkpkg -package mypackage test_program.cmx -o test_program.native
/usr/bin/ld : ne peut trouver -lmyLib
collect2: error: ld returned 1 exit status
File "caml_startup", line 1:
Error: Error during linking
Command exited with code 2.
Compilation unsuccessful after building 4 targets (0 cached) in 00:00:00.
I’m not sure how this can be solved?
One solution could be to generate myLib by hand, with a libmyLib.so
instead of dllmyLib.so
?
But it departs from the apparent conventions…
Thanks for any explanation of the rationale for the dllXXX.so convention, and how to make use of it in my case?
Other solution, and other interrogations
I went on with the libmyLib.so
. Here is my Makefile:
ccliblibs = $(patsubst %,-cclib %, $(DEPENDENT_LIBS))
my_stubs.o: my_stubs.cpp
gcc -c -Wall -fPIC $< -o $@
module.cmo: module.ml
ocamlfind ocamlc -c -annot -bin-annot -package needed_packages $<
module.cmx: module.ml
ocamlfind ocamlopt -c -annot -bin-annot -package needed_packages $<
libmyLib.so: my_stubs.o
gcc -shared -std=gnu99 -O2 -fno-strict-aliasing -fwrapv -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT -fPIC -o $@ $< $(DEPENDENT_LIBS)
myLib.cma : module.cmo libmyLib.so
ocamlfind ocamlc -a -o $@ -package needed_packages module.cmo -cclib -lmylib -dllib libmyLib.so $(ccliblibs)
myLib.cmxa : occt.cmx libocOcct.so
ocamlfind ocamlopt -a -o $@ -package needed_packages module.cmx -cclib -lmyLib -ccopt -L$(CAML_LD_LIBRARY_PATH) -ccopt -Wl,-rpath=$(CAML_LD_LIBRARY_PATH) $(ccliblibs)
install: myLib.cma myLib.cmxa
ocamlfind install mylib META myLib.a myLib.cma myLib.cmxa module.cmi module.cmt module.cmx -dll libmyLib.so
After the mylib
package has been installed, I can use it from utop
, or when compiling a native version of a small test program.
Except that for the native version to work, I had to add linkopts(native)="-cclib -lmyLib"
in the META file, which I do not understand, since it should be stored inside the .cmxa?