Skip to content

Instantly share code, notes, and snippets.

@TheLortex
Created June 4, 2019 15:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheLortex/f3d92db831b553f6e4eaf2982e3e6427 to your computer and use it in GitHub Desktop.
Save TheLortex/f3d92db831b553f6e4eaf2982e3e6427 to your computer and use it in GitHub Desktop.

This is a recap of what is changing in the mirage world in order to switch to the dune build system. It should lead to more pleasant worlflows and paves the way for cross-compilation.

Mirage CLI

mirage config -t <target>

  • Stop generating an empty myocamlbuild.ml
  • Generate a dune file specifying the set of rules needed to build an unikernel.
  • Generate a dune-project file for the dune language and release compilation mode.
  • Generate a dune-workspace file that sets up compilation contexts with the correct C flags for each target.

mirage build

  • Execute a dune build @<target> which directly generates the unikernel according to the rules defined in the configure step.

Functoria

Executing the config.ml file was done by compiling and dynlinking it against itself: this becomes problematic when the library's source code is modified as symbols may get their names changed. The goal is to replace this by a 2-stage build using dune: the config.ml is compiled and then executed to finish the configuration step.

C flags

mirage-platform and ocaml-freestanding

These packages expose the base layer of xen an freestanding targets, with a custom ocaml runtime and a custom libc. They expose the C and ld flags as pkg-config variables, this necessary to correctly build C stubs and link the unikernel. Dune offers the possibility to gather and set these flags automatically. The dune-workspace file indeed allows to set flags globally and enables a straightforward compilation scheme.

Backend-agnostic use of flags (checkseum, digestif, nocrypto, ..)

Most projects that have C stubs can simply rely on workspace flags set up by the Mirage cli. In dune files you just need to have a c_names field to list your C files and make sure to have c_flags :standard ... to include the workspace compilation flags.

Backend-aware use of flags (zarith)

When the C stubs compilation need to depend on the target (for example zarith-xen need gmp-xen and custom compilation machinery) it's possible to fetch the flags using :include:

  • xen: :include %{lib:mirage-xen-ocaml:cflags
  • freestanding: :include %{lib:ocaml-freestanding:cflags}

Virtual libraries / variants

Virtual libraries are needed when a library is compiled with different dependencies and/or have different implementations depending on the selected backend.

mirage-os-shim

mirage-os-shim is the shared interface between mirage-xen, mirage-unix and mirage-solo5. For now it exposes an OS module with time and scheduling primitives.

The dune file for mirage-os-shim is

(library 
  (name mirage_os)
  (public_name mirage-os-shim)
  (virtual_modules OS)
  (libraries lwt))

and implementations can simply refer to it by using (implements mirage-os-shim).

zarith

zarith is a numerical library that relies on GMP. As such there's no way to transparently cross-compile GMP so gmp-xen and gmp-freestanding packages have been created. So in order to have a portable zarith to build against we have to expose zarith as a virtual library and then have zarith-xen, zarith-unix and zarith-freestanding as implementations.

Bigarray/unix dependency on 4.07

In ocaml 4.07 Bigarray has mostly been moved to Stdlib.Bigarray and the bigarray library becomes Stdlib.Bigarray + Unix.ba_map_file. This means depending on bigarray also grabs an unwanted unix dependency in the closure.

Mirage/OCamlbuild dealt with that using a -dontlink option that just ignores these libraries. We can't do that (and we don't want to do that) in dune so we need to track down and eliminate these dependencies to unix in packages that transitively have them: sexplib, ocplib-endian.

The specific solution for bigarray was to create a bigarray-compat wrapper that exposes Stdlib.Bigarray after 4.07 but still grabs unix when OCaml is less than 4.06, in order to keep compatibility for non-mirage projects.

Duniverse

In order to corrrectly build packages with C stubs we need to keep the sources locally. The tool was initially designed by @avsm, and then contributed to and maintained by @NathanReb, @Julow, @TheLortex.

Workflow:

  • mirage config -t hvt: configure the unikernel and create an opam file with dependencies.
  • duniverse init: read the opam file and compute the list of packages to download in order to build the unikernel.
  • duniverse opam-install: install dune-incompatible packages in the global opam switch
  • duniverse pull: fetch the whole dependency tree in a duniverse/ directory so that dune can use them to build the unikernel. The first pull is slow but a cache mechanism has been developped so that subsequent pulls are faster
  • mirage build: build the unikernel for the given target.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment