Mirage OS Logo

Breaking changes

By Thomas Leonard - 2015-06-18

This page records API changes that require existing code to be updated.

2022-03-28: MirageOS 4


In Mirage 3.x, functoria devices were described by extending the base_configurable object. Custom devices are now described using the following API:

val impl :
  (* Device's package dependencies *)
  ?packages:package list ->
  ?packages_v:package list value ->
  (* Device's output artifacts to promote in the dist/ folder *)
  ?install:(info -> Install.t) ->
  ?install_v:(info -> Install.t value) ->
  (* Functoria keys *)
  ?keys:abstract_key list ->
  (* Device dependencies *)
  ?extra_deps:abstract_impl list ->
  (* [connect info modname deps] is the code to instanciate device's value given its dependencies' values and the module name *)
  ?connect:(info -> string -> string list -> string) ->
  (* Additional dune rules to generate code or artifacts *)
  ?dune:(info -> Dune.stanza list) ->
  (* Configure-time operations *)
  ?configure:(info -> unit Action.t) ->
  (* Extra files generated by configure-time operations *)
  ?files:(info -> Fpath.t list) ->
  (* Functor name *)
  string ->
  (* Functor type *)
  'a typ ->
  (* Device implementation *)
  'a impl


For each unikernel, MirageOS 4 assembles a monorepo of dependencies to locally cross-compile them using the chosen target settings. To achieve that, the tool uses dune's build context feature. The consequence of that choice is that unikernel libraries also need to be built using dune.

For most packages, porting to dune is fairly straightforward, and has the benefit of integrating with existing platform tools like merlin. The dune-universe/opam-overlays repository contains a set of packages that have been ported to dune but where the changes haven't been upstreamed.

2016-02-17: Functoria edition

Command line

The config file must be passed with the -f option (instead of being just an argument).

Deprecation: Misc functions

get_mode is deprecated. You should use keys instead. And in particular Key.target and Key.is_xen.

add_to_ocamlfind_libraries and add_to_opam_packages are deprecated. Both the foreign and the register functions now possess the ~libraries and ~packages arguments to specify libraries dependencies.


If you were using tls without the conduit combinator, you will be greeted during configuration by a message like this:

The "nocrypto" library is loaded but entropy is not enabled!
Please enable the entropy by adding a dependency to the nocrypto device.
You can do so by adding ~deps:[abstract nocrypto] to the arguments of Mirage.foreign.

Data dependencies (such as entropy initialization) are now explicit. In order to fix this, you need to declare the dependency like so:

open Mirage

let my_functor =
  let deps = [abstract nocrypto] in
  foreign ~deps "My_Functor" (foo @-> bar)

My_functor.start will now take an extra argument for each dependencies. In the case of nocrypto, this is ().

2015-06-18: HTTP servers with Mirage > 2.5

Before, you would specify your server's address in the config.ml:

let server =
  http_server (`TCP (`Port 8080)) (conduit_direct (stack default_console))

and then use it in your unikernel.ml as:

let start http =
  http (H.make ~callback ~conn_closed ())

With mirage > 2.5, the address argument is no longer present and you will get this error:

Error: This function has type
         Mirage.conduit Mirage.impl -> Mirage.http Mirage.impl
       It is applied to too many arguments; maybe you forgot a `;'.

To update, change config.ml to:

let server =
  http_server (conduit_direct (stack default_console))

and move the address to your unikernel.ml:

let start http =
  http (`TCP 8080) (H.make ~callback ~conn_closed ())

Note that the Port tag has also been removed.

This change was needed to support TLS servers, since TLS configuration (keys and certificates) is more complex and cannot be declared in the config.ml.

Commit: https://github.com/mirage/mirage/commit/56e500d4210bf7fdcdc296f3c34ce13c9f57cdf5