How to get OCaml linker flags to link with C++ cma

2019-07-22 21:40发布

问题:

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.

回答1:

I may not fully grasp your problem but here are some points that could be relevant :

  1. 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
  2. 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)
  3. 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
  4. 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)