I'm trying to link some C++/cmake code with some OCaml code. If the C++ side were simple, I'd just add its object file to ocamlopt. If the OCaml side were simple, I'd add its object file to cmake. But they're both complex programs with lots of dependencies.
Currently, I have it working, but it's a bit of a hack:
I run ocamlopt -output-obj
to get the main OCaml object:
add_custom_command(
OUTPUT ocaml_main.o
DEPENDS ocaml.ml
COMMAND ocamlfind ocamlopt -package mylib -linkpkg -output-obj -o ocaml_main.o ocaml.ml
)
I run ocamlopt again with -o
and $PATH
set to include a fake gcc
executable. This fake gcc
removes the initial -o ocaml_main.o
argument and all .o
files except for std_exit.o
and prints out the rest.
This output is added to the CMake arguments (using target_link_libraries
).
Is there a cleaner way to do this (i.e. get all of the OCaml dependencies, recursively, ready for linking)? Using plain ocamlfind query
gets me part of the way, but misses e.g. the extra linker flags embedded in the cmxa files.
I may not fully grasp your problem but here are some points that could be relevant :
- I feel that it is easier to start from ocaml and link c++ code in than vice versa, probably because ocaml is more high level and c++ build artifacts are simpler, so there is less linking logic to handle
- Linking your own c++ code into ocaml project is no different to linking c code, just add -xc++ to gcc flags and store code in .c files so that
ocamlopt
and ocamlbuild
pick them up as such (and include -lstdc++
in the list of linked libraries)
- Linking third party c++ code is easier if one keeps all c++ code as separate library archive and writes OCaml bindings to that, then links those bindings as usual OCaml library via
ocamlfind
to the main project
Here is an example - bindings for the hypertable c++ library : http://hypertable.forge.ocamlcore.org/
All the linking magic is contained in _oasis :
CCopt: -x c++ -O2 -Wno-deprecated -I/opt/hypertable/current/include
CClib: -L/opt/hypertable/current/lib -failsafe -lstdc++ -lHypertable -lHyperComm -lHyperDfsBroker -lHyperCommon -lHyperspace -lHyperTools -llog4cpp -lexpat -lboost_thread -lboost_iostreams -lboost_program_options -lboost_system -lsigar-amd64-linux -lz -lcurses -lrrd -lboost_filesystem
CSources: hypertable_stubs.c, cxx_wrapped.h
(of course use pkg-config
if the library provides it)