Foreign_archives: no static libraries, .dylib on mac

For anyone that stumbles across this thread. I adapted the advice from @syaiful6 and @nojb as follows.

I added the following command to the CMakeLists.txt file of the vendored library:

if(CMAKE_SHARED_LIBRARY_SUFFIX STREQUAL ".dylib")
    set(CMAKE_SHARED_LIBRARY_SUFFIX  ".so")
endif()

Now, the built shared libraries always have the .so extension, even on macOS.

I generated rules (libortools.inc) to copy the built shared library files into the package directory. I also generated a list of shared library files to install (libortools_files.sexp). Finally, through a process of reading the dune docs, reading the OCaml docs, working by trial and error, and conversing with an AI (what can I say…), I came up with the following incantation.

(dynamic_include ../libortools-build/libortools.inc)

(library
  (name ortools_solvers)
  (public_name ortools_solvers)
  (synopsis "Call Google OR-Tools solvers")
  (modules ortools_solvers)
  (foreign_stubs
    (language c)
    (names ocaml_ortools_solvers)
    (flags :standard
           -I../libortools
           -I../libortools-build/build
           ; hack to ensure that libortools.so is copied to this
           ; directory by the rule in libortools.inc <sigh>
           -DDUNE_DEP=%{dep:libortools.so}))
  (libraries ortools)
  (library_flags :standard
                 -ccopt "-L$CAMLORIGIN"
                 -ccopt "-Wl,-rpath,$CAMLORIGIN")
  (c_library_flags :standard
                   -lortools -Lortools_solvers
                   "-Wl,-rpath,'$ORIGIN/../ortools_solvers/'"
                   -Wl,-rpath,@loader_path/../ortools_solvers/)
)

(install
   (files (include ../libortools-build/libortools_files.sexp))
   (section libexec)
   (package ortools_solvers)
)

I’m not confident enough in my understanding to properly summarize the links between the foreign_stubs, libraries, library_flags, and c_library_flags commands and the resulting invocations of the underlying ocaml tools. As suggested by @nojb, running dune with the --display=verbose option, and adding -verbose to the various flags fields in the above file is very helpful.

The %{dep:} is regrettable. It would have been preferable to declare it with (deps …).

The options for -rpath are needed for both native and bytecode builds to work on both Linux and macOS. Unfortunately, they only work properly once the library is installed and used with ocamlfind. Test building executables with dune exec fails because it uses relative paths and $CAMLORIGIN is thus not set correctly.

1 Like