I’m wondering if I am compiling and linking a simple one-file Fortran sublibrary correctly into my OCaml library. Ideally I would like to be able to make my library installable on linux and macos with a simple opam install.
After some fiddling and googling I have arrived at the project structure shown below, which seems to work for loading the Fortran library via ctypes like so:
integrate_mvnd.ml
open Containers
open Ctypes
[...]
let mvnd =
match
Sys.getenv "CAML_LD_LIBRARY_PATH"
|> String.split_on_char ':'
|> List.cons (Sys.getcwd ())
|> List.find_map (fun p ->
try
let filename = p ^ "/dllmvnd.so" in
Some (Dl.dlopen ~flags:Dl.[RTLD_NOW;] ~filename)
with Dl.DL_error _ -> None)
with
| Some l -> l
| None -> failwith "unable to load mvnd shared library"
let ocaml_mvnd arg1 arg2 [...] =
Foreign.foreign ~from:mvnd "mvnormaldist" (ptr.integer @-> [...])
Some points I’m not content with:
- I have to manually check for the
CAML_LD_LIBRARY_PATH
- I have to build a static library although afaict this will never work the way the library is loaded, because otherwise dune complains
- I am using hardcoded dll filenames, but when trying
@{dll_ext}
in dune that also gave.so
on macos not.dylib
as i had expected.
Am I using dune correctly? Is there a way to switch to either fully static linking of the fortran sublibrary or only dynamic linking?
Relevant project structure bits follow:
dune:
(data_only_dirs fortran-lib)
(library
(name vbar)
(public_name vbar)
(modules vbar)
(libraries [...]))
(rule
(deps (source_tree fortran-lib))
(targets dllmvnd.so libmvnd.a)
(action
(no-infer
(progn
(chdir fortran-lib (run make))
(copy fortran-lib/dllmvnd.so dllmvnd.so)
(copy fortran-lib/libmvnd.a libmvnd.a)))))
(library
(name integrate_mvnd)
(public_name vbar.integrate_mvnd)
(modules integrate_mvnd)
(libraries [...] ctypes ctypes.foreign)
(foreign_archives mvnd))
[...]
fortran-lib/Makefile:
.PHONY: clean all
all: mvnd.dylib libmvnd.a
mvnd.dylib:
gfortran -shared -O3 -fPIC -fcheck=bounds -std=f2008 -w -o dllmvnd.so mvndstpack_mod.f
libmvnd.a:
gfortran -c -O3 -fPIC -fcheck=bounds -std=f2008 -w mvndstpack_mod.f
ar -rcs libmvnd.a mvndstpack_mod.o
clean:
rm -f *.o *.mod *.a *.dylib
12 posts - 2 participants