By Thomas Gazagnaire - 2022-02-11
Welcome to the MirageOS 4 release page.
The main change is a deep modification on how unikernels are built. One of the
purposes of MirageOS is to orchestrate a build a system in order to produce the desired
unikernel binary. Until MirageOS 4, the build system was ocamlbuild
. Now, we switched
to dune
. Following a global shift to the dune
build system, this enables us many
features that were slowing down the MirageOS development workflow.
Monorepos: unikernel sources are locally fetched to be compiled by dune
. This
implies that one can locally edit theses sources to test changes, before sending them
to the upstream repository. It replaces the usual opam pin ...
/ edit sources /
opam reinstall ...
workflow.
The monorepos are built using the opam-monorepo tool, consisting in two steps. First a lockfile is generated, performing the dependency resolution and locking packages to specific versions. Then the lockfile is used to locally fetch the sources.
Cross-compilation: one of the problems of MirageOS 3.x was the difficulty to create
new targets into the ecosystem, especially cross-archicture targets. Because opam
installs packages for the host architecture, one would have to create a parallel
repository in which packages are cross-compiled, such as
opam-cross-android or
opam-cross-esp32. That
parallel world idea has also been implemented using esy
: see
reason-mobile.
The MirageOS 4 solution takes advantage of the dune workspaces feature, which defines a global compilation environment (OCaml compiler, C compiler, flags and environment variables) to be used to build all the sources that are locally available. As a consequence, porting a new target to Mirage 4 will only rely on having a freestanding (i.e. OS-free) OCaml compiler.
Reproducible workflow: because lockfiles are used to fetch the unikernel sources,
we can ensure that the exact same sources will be used to build the unikernel as the as
the lockfile has not changed. Additional work might be required to ensure that the
rest of the tools (mirage
, dune
, ocaml-solo5
) are also locked to a specific
version.
Merlin support: dune
automatically enables the usage of merlin
to improve the
developer experience. Its editor support can be enabled for example by using the ocaml
LSP server. Due to current limitations, merlin
can be enabled either on the
config.ml
file or the unikernel files, but not both at the same time.
Note that until the next release of dune
, merlin
support must be activated manually
in the dune-workspace
file. documentation
Port to dune: since the beginning of the work on MirageOS 4, many packages have
been ported to dune. This is a requirement to be able to use it in a unikernel.
The libraries using alternative build systems (such as B0
) have been ported to dune
,
but as upstreaming the work is not expected, the MirageOS team maintains repositories
of build system forks: dune-universe/opam-overlays and dune-universe/mirage-opam-overlays.
The mission of porting and maintaining dune-built forks is assured by the dune-universe team.
Solo5 and ocaml-solo5: to support the new cross-compilation workflow,
solo5
becomes a cross-compilation toolchain (ARCH-solo5-none-static-cc
) and
ocaml-solo5
becomes an OCaml cross-compiler based on that solo5 toolchain.
C stubs compilation: the rule for C stubs compilation has also changed. Until now,
package maintainers that uses C stubs had to add some code to build the C stubs using the
solo5
flags, through the ocaml-solo5
pkg-config
file.
Now, package maintainers should only care about writing portable code once, and built it
using dune
rules.
To sum it up, here are the portable compilation rules for a package to support Mirage 4.0:
unix
dune
, and have your transitive dependencies buildable using dune
.libc
is minimal. See ocaml-solo5
's nolibc
for reference: github.com/mirage/ocaml-solo5/tree/master/nolibc/includeThe functoria devices has changed, switching from requesting objects to a function with optional parameters.
An additional dune
field can be used to have additional rules related to the device.
See this commit as an example on how to adapt the objects to the new interface.
The mirage
command-line interface hasn't fundamentally changed, but when a project is configured,
the following additional files are generated:
dune.build
and dune.config
depending on the context.opam-monorepo
.opam install
(it includes solo5
and ocaml-solo5
)To fetch and install the dependencies, make depends
is still the command to go:
opam-monorepo
the unikernel dependencies in the duniverse/
folder.To build the unikernel, mirage build
and dune build
are equivalent.
The output is available in the dist/
folder.
# Install MirageOS 4
$ opam install 'mirage>=4.0'
# Clone this website repository
$ git clone https://github.com/mirage/mirage-www
# Configure the unikernel
$ mirage configure -f mirage/config.ml -t hvt
# Fetch and install dependencies
$ make depend
# Build the unikernel
$ dune build mirage/
# Launch it (a tap interface needs to be configured for the hvt target)
$ solo5-hvt --net:service=tap100 mirage/dist/www.hvt