0

I have an OCaml library that has a C binding. The C binding has a dependency on a native component that I would like to also build with dune. At the moment, the dune file looks like:

(rule
 (deps
  (source_tree vendor))
 (targets libexample.a)
 (action
  (no-infer
   (progn
    (chdir
     vendor
     (progn (* RUN A BUILD STEP HERE *))
    (copy vendor/libexample.a libexample.a)))))

(library
 (name exampleWithNativeDep)
 (package examplePackage)
 (flags -linkall)
 (libraries base)
 (wrapped false)
 (foreign_stubs
  (language c)
  (names binding)
  ;; Note that there's a separate C binding file that relies on Dune to be built.
  ;;  This needs the libexample.a produced above but libexample is not directly targeted by OCaml.
  (flags :standard -Ivendor/Include -I.))
 (c_library_flags -lutil -lpthread)
 (foreign_archives example)

This works fine when running OCaml native builds but fails when I want to run a bytecode build. The issue is that the bytecode build wants dllexample.so to also exist.

Given that:

  • I only need the artefacts of the rule to statically link them in my OCaml consumed C binding;
  • I still want to rely on Dune to build the C binding;
  • I need the binding to be statically linked to libexample.a both when the binding is built as a static library for consumption from native builds and dynamic library for consumption from bytecode builds.

is there a way to express this kind of behaviour with in dune?

namesis
  • 157
  • 10

1 Answers1

0

If you really want to rely on dune to build your C library, then just let dune do it work. There is the foreign_library stanza exactly for this.

Put the following dune file into your vendor folder,

(foreign_library
 (archive_name example)
 (language c)
 (names example)) ; the list of C files without extension

and add (foreign_archives vendor/example) to your exampleWithNativeDep library definition.

Also, you don't need to pass -linkall as OCaml will link libexample.a by default (i.e., it will use static linking). And -linkall is actually have a different meaning, it doesn't really control static linking.

P.S., and don't forget to remove your rule stanza.

ivg
  • 34,431
  • 2
  • 35
  • 63
  • I might be misunderstanding but the above complains about the lack of `dllexample.so` when I'm trying to use the OCaml library in a bytecode executable. – namesis Aug 03 '23 at 22:42
  • Basically, libexample.a is only meant to be statically linked against the lib/dll produced for the binding of the exampleWithNativeDep. – namesis Aug 03 '23 at 22:45