  Compiling applications as unikernels allows them to be tailored to diverse
execution environments. Dependency on a monolithic operating system is replaced
with linkage against libraries that provide specific services. Doing so in
practice has revealed a major barrier: managing the configuration matrix across
heterogenous execution targets. A realistic unikernel application depends on
hundreds of libraries, each of which may place different demands on the
different target execution platforms (e.g.,~cryptographic acceleration).
  We propose a modular approach to structuring large scale codebases that
cleanly separates configuration, application and operating system logic. Our
implementation is built on the \mirage unikernel framework, using the \ocaml
language's powerful abstraction and metaprogramming facilities. Leveraging
modules allows us to build many components independently, with only loose
coupling through a set of standardised signatures. Components can be
parameterized by other components and composed. Our approach accounts for
state, dependency ordering, and error management, and our usage over the years
has demonstrated significant efficiency benefits by leveraging compiler
features such as global link-time optimisation during the configuration
process. We describe our application architecture and experiences via some
practical applications of our approach, and discuss how library development in
\mirage can facilitate adoption in other unikernel frameworks and programming
languages.
