This issue wants to solve an initial and systematic issue found into checkseum
/digestif
and try to prepare an easily move to mirage
with dune
. To contextualize a bit the goal of this issue, you probably should look into mirage/mirage#1024.
Come back to the dunification of MirageOS, the main and fully described difference of the compilation of an unikernel with ocamlbuild
and with dune
is the option: -output-complete-obj
. The main difference is about static C libraries. Let back a bit about the diff.
Link an unikernel with ocamlbuild
+ ocamlfind
According the current status of MirageOS, a library with C stubs such as checkseum
must fill a META
file with some metadata to let the mirage
tool to choose the right static C library according the target. mirage
asks with ocamlfind
these metadata and put at the link-time with -output-obj
static libraries collected.
The compiler, at the link time and with -output-obj
does not care about static libraries described into *.cmxa
. This is why the mirage
tool/ocamlbuild
/ocaml
can chooses the right static C libraries such as -lgmp-freestanding
(for Solo5) according the target (even if zarith.cmxa
describes -lgmp
).
Link an unikernel with dune
However, dune
strictly uses a new option of the compiler, -output-complete-obj
and it seems that -output-obj
will be deprecated. This new option change the behavior of the compiler where it wants to link the final main.o
(the unikernel) with libraries described into *.cmxa
used to produce the unikernel.
A link with zarith.cmxa
with -output-complete-obj
will try (at the compiler layer) to link with libgmp.a
in any cases.
For a library such as checkseum
(and mirage-crypto
)
Of course, for any libraries which wants to provide C stubs, a compilation of the unikernel with -output-complete-obj
constraints us to:
- still continue to provide a
META
file with such metadata to be compatible with MirageOS 3.*
- provides well-formed
*.cmxa
with right C libraries such as:
checkseum_freestanding.cmxa
should link with -lcheckseum_freestanding
checkseum_xen.cmxa
should link with -lcheckseum_xen
The second point is a requirement of the compiler due to the use of -output-complete-obj
. The first point is the well-know requirement for MirageOS 3.*.
A question still exists however. Who and how we can choose between checkseum_freestanding
and checkseum_xen
according the target expected by the user? This is where dune
can come and choose one of these libraries according an explicit expected variant.
I will not try to explain, again, variant but it unlock the ability for a user to choose an implementation (compiled object for Solo5, compiled object for Xen, etc.) according a common interface according a new field. dune
is able to choose a default implementation if the field is missed (such as the unix
target).
Under the use of variant, we have the ability to produce well-formed *.cmxa
and each of them will have the same interface (technically, the same hash of the common interface).
A story about compatibility
However, if we choose to use variants and provide well-formed *.cmxa
and help a bit the compiler to link with right static C libraries, we are not able to play with the META
file. Of course, after some iterations, we did it (mostly on checkseum
): you can look it here.
The final task
At the end, if we want to use dune
to compile an unikernel, we must provides well-formed *.cmxa
because of -output-complete-obj
. The question about the way to choose which *.cmxa
we will choose according the target is the main problem:
- For MirageOS.3.*, this is done by
ocamlfind
- For a MirageOS with
dune
, it should be done by dune
at least
- An other solution exists with
duniverse
To be smooth about such a transition, the first and the second point can live together. Of course, the solution is not perfect when:
- we must hack the
META
file by ourselves
- we must use
dune
's variants
- the compilation to an executable (which uses the library with C stubs) with something else than
dune
will not properly work (due to the linking-trick).
However, I think it could be a good solution to pave the way to the dunification of MirageOS and give to use an intermediate step which is still compatible with both worlds.
Technically. what we should do
The task is to use dune
's variants, so an update of:
freestanding/dune
xen/dune
src/native/dune
is needed to specify which variants they are. Then, we must trick on the OPAM file to rightly put metadata needed by ocamlfind
such as checkseum
does.
So, for any questions, I'm free to go deeply into details and explain goals.