This document details the details of the compilation process for MirageOS unikernels. It outlines the steps required to prepare, compile, and manage dependencies for Mirage applications.
Developing a simple application with Mirage involves starting with two primary files:
config.ml
: Contains the configuration of your unikernel.unikernel.ml
: The main application code.
The usual workflow to configure and compile an unikernel is to run the following commands:
$ mirage configure <configure-options>
$ make depends
$ dune build
$ ls dist/
<unikernel binaries>
While hidden to the end-user, mirage configure
is actually split into several lower-level key steps, described below.
Executing mirage configure --init-config
generates the essential scaffolding needed for compiling and executing config.exe
. This process creates the following files, if they don't already exist:
Makefile
dune-project
dune-workspace
dune.config
dune
These files are generic and independent of the specific content within config.ml
. Their primary role is to enable the compilation of config.exe
, which provides a runnable description of the unikernel. For example:
$ ./config.exe query name
<unikernel-name>
For additional options and details, see the output of ./config.exe --help
. The config.exe
binary drives the remaining setup process.
The mirage
command-line tool supports multiple sub-commands, designed to be used in a specific sequence. For example:
Copy code
$ mirage configure <options>
...
$ mirage describe
...
$ mirage clean
In this workflow, users expect that mirage describe
will detail the unikernel as configured, not in its generic form. Similarly, mirage clean
should remove all files generated during the configuration step. This implies that the CLI maintains state across invocations by remembering the options passed to mirage configure
. To do this, mirage configure <options>
records the specified options in a .mirage
file.
Note: The
.mirage
file is exclusively created by themirage configure
command. Whileconfig.exe
may read from this file, it will not modify or create it.
The command mirage configure --init-lib
lays down the scaffolding necessary for compiling the unikernel functor as a library. This action is also achievable by running ./config.exe configure --init-lib
.
This step modifies the existing dune
file with specific rules to compile the provided functor as a library. The output is an OCaml library with the same name as the unikernel defined in config.ml
.
Running mirage configure --init-app ...
with the desired CLI options configures the final application. This can also be done through ./config.exe configure --init-app ...
.
This generates a new mirage
directory, containing all files required to compile and package the application:
mirage/main.ml
mirage/app.opam
mirage/dune
mirage/...
If a generated file already exists, its potential overwriting follows these rules:
- Files starting with
;; generated by mirage <version>
will be overwritten. - Files without this header will not be modified.
The mirage clean
command also uses these rules to determine which files to delete or retain. Files marked as generated are removed, while others are left untouched. If you wish to edit and preserve any generated file, ensure to remove the "generated by" header.
To use PPX extensions or libraries within config.ml
, first edit dune.config
by removing the "generated by" header. Then, customize the compilation rules as needed.
Note: This section may evolve with future
dune pkg
updates.
Generated dune files include an alias for creating lock files, which are crucial for packaging: execute dune build @lock
(or make lock
)
During development, it could be beneficial to have a single lock file for all the unikernels in the repository. Use make dev-lock
to create one such file.
An alias in the generated dune files allows for pulling dependencies into a local duniverse
folder: run dune build @pull
(or make pull
).
During development, it could be useful to pull all dependencies of all the unikernels. Use dune build @dev-pull
or make dev-pull
to achieve this.
TODO