-
Notifications
You must be signed in to change notification settings - Fork 248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mirage 4.0, dune and cross-compilation #1195
Comments
This scheme looks good to me. I'd just note that @dra27 is also working on integration of cross-compilation directly upstream in OCaml, so the situation with the dune forks should hopefully be constrained to a few releases of upstream OCaml before we can use the native support directly. |
Thanks for your high-level overview. Are there any further details available? Especially taking mirage/mirage-xen#23 into account: how are CFLAGS being passed around (at the moment via pkg-config, will the new workflow be different?)? If I understand correctly, solo5 and ocaml-freestanding will still be built using "the host opam"? What are more specifically the pain libraries when it comes to cross-compilation? I imagine gmp-freestanding & zarith(-freestanding) that do not use dune (yet?), it'd be nice to more clearly lay out the strategy for them. Will the opam file generated by I guess it boils down to: considering all the dependencies are using dune, is |
CFLAGS that are common to all Solo5 targets are configured in the cross-compiler
Yes, and installed as usual using
Indeed these are the pain libraries. The goal is to have single packages (
The goal is to keep that workflow possible or at least very similar. For now, all generated artifacts are required to build the unikernel, including the dependencies locally fetched by |
GMP and ZarithFor zarith cross compilation, I have a patch on top of the zarith for duniverse
Also for gmp, but gmp is quite straightforward to cross compile
Cross CompileCurrently unix unikernels can easily be cross compiled with this patches as it may at esy-mirage-kernel who is building Mirage for a couple of platforms, Android, FreeBSD, iOS and Linux |
Two weeks have passed, and after some testing and implementations I feel confident pushing forward and to start submitting the PRs. I just want to enumerate the issues I encountered, and make sure everyone agrees with how changes will be performed. Specific issuesMirage-skeleton/testingTo test the mirage 4 tool, I focused on building unikernels from the mirage-skeleton on the GMP/ZarithGMP/Zarith are the pain libraries of this update because of a complex configure script and the quantity of C stubs. Because the unikernel dependency tree has to be built with Dune, I had to wrap the Mirage CLITool-specific changes will be discussed in the appropriate PR. In summary:
Dune/cross-compilationA lot of changes are based from this issue: ocaml/dune#3917. Release planMain changes see a major/minor version bump. Packages that have the ocaml/dune#3917 issue may see a patch version bump. Packages that have C stubs (and thus -freestanding, -unix variations) will be broken on solo5 targets with mirage 4, so they should have a major version bump. PackagesMain changes
Updates
TestingThe work can be tested by using the following opam repositories and packages:
I'm asking for feedback, especially on the mirage tool changes because that's what impacts directly the user workflow. |
@TheLortex could you open a PR for the Base deps change? That will have some lead time to get into a release, so it would be good to get it done early. |
First of all, thanks for your amazing work on this topic.
The most convenient is to release from the bottom up to opam repository -- i.e. those packages that work fine with the current opam repository. See #1159 (comment) how we did the last release.
I use the opam file generated by
With your work, I'm slightly scared that "duniverse" is a dependency which (a) is unreleased, (b) uses some "opam overlays" (with an unclear maintenance status or how&whether the changes will be upstreamed (e.g. num is still at 1.3, zarith at 1.9)) (c) has still a rather unclear purpose from my point of view (similarly to opam it downloads packages). See my earlier attempt at using the "MirageOS+dune+duniverse" at #1153 (comment) -- are the issues fixed now, should I test it again? What is the story about how sources are gathered? I prefer - similar to what we have now - a way to "download sources" and a separate step to build and install the unikernel -- i.e. no network access during the build & install phase. Maybe the way to move forward is having mirage emit a |
If you're talking about janestreet/base#100 it's already open ! I'm planning to continue opening PRs this week.
(a) I agree that duniverse needs to be released before releasing mirage 4.
I think you can test it but the "deploy" part that you described is missing, so you might prefer to wait a little. Most of the issues are fixed. To answer your questions, the steps are:
It's not possible to use duniverse in opam Now that the "deployment" workflow is clearer to me, I'll try and come up with a solution ! |
FWIW with tcpip 6.0.0 (and #1204 being merged) there's no need for customization of tcpip (now the checksum stubs are provided by mirage-solo5 / mirage-xen -- tcpip's build system was simplified) |
There are three sets of packages which are needed for the release:
At the moment, all of these packages live in https://github.com/mirage/mirage-dev/tree/master/packages ; my short-term plan is to:
|
I'm closing this issue now, the remaining bits of the release are tracked on #1261 |
Hi, this issue introduces the final changes we need to have
dune
to build unikernels in mirage.It comes in the continuation of #969. These changes have been partially implemented for testing purposes, this issue exists to make sure everyone is aware of the update plan.
Feel free to comment on this issue if you need precisions on a specific point !
The changes
The unikernel build is now done in two steps:
duniverse
anddune
.Step 1: cross-compilers
As most mirage targets actually build for the same architecture as the host, we don't actually need cross-compilation to build unikernels. However it has the advantage of having a simpler mental model. Code that needs to run on the host system are made with the host compiler, and code that needs to be run in the unikernel are built with the target compiler (the cross-compiler). Having first-class cross-compilation support easily enables new targets such as
esp32
orrisc-v
. Ocaml cross-compilation is not a nice story, it's still hard in 4.11.1 to build a cross-compiler: a lot of tweaks have to be done to be able to build one correctly. Therefore the biggest changes are inocaml-freestanding
: it is split in two, libc and cross-compiler, so that the configuration step of the cross-compiler can be done with the installation path of the libc.This is the summary of changes:
unix
or cross-compiled. Cross-compiled backends may require to install toolchains with opam (ocaml-freestanding
,solo5-bindings-<x>
).solo5-headers
opam package.solo5-libc
package containingnolibc
andopenlibm
.ocaml-freestanding
becomes a cross-compiler based on solo5 headers and libc. It is installed in<opam-switch-root>/freestanding-sysroot/
, and can be refered to usingocamlfind -toolchain freestanding <command>
.Step 2: duniverse
The opam tooling is not ready for cross-compilation, so we need to rely exclusively on dune to perform unikernel builds. This means that a tool was needed to fetch and download all the required dependencies of the unikernel. This is the role of
duniverse
.duniverse
, now known as the opam pluginopam monorepo
, uses opam to parse the dependency file and locate all the required sources, before downloading them in a./duniverse
folder.When the sources are fetched, dune is configured to have one build context per mirage target, set up to use the correct compiler for each target. Then a single
dune build
command is able to build all the required dependencies to produce the requested unikernels.This is the summary of changes:
mirage configure -t <target>
generates:dune
: build rulesdune-project
: general dune configurationdune-workspace
: definition of build contexts, that's how installed cross-compilers are detected by dune<unikernel>-hvt.opam
: opam file definition, declaring dependencies (runtime, build and toolchain). Toolchain dependencies are guarded by a newbuild-context
variable and aim to be installed by opam.mirage.context
: command line arguments for mirage configureMakefile
Duniverse is now an opam plugin, called
opam monorepo
. It parses an opam file to compute the transitive closure of a project's dependencies, and locally fetches them. It uses the opam resolver so it supports opam pins and repos.opam monorepo lock
: solve the dependencies and find where to fetch each project, generating a<unikernel>.opam.lock
file.opam monorepo pull
: download the dependencies according to the lockfile.Workflows
Build a unikernel from scratch
opam install mirage
mirage configure -t <target>
: generates build / install files (see earlier)make depend
ormirage depend
: install dependencies:env OPAMVAR_build_context=1 opam install . --deps-only
)duniverse
(equivalent toopam monorepo lock && opam monorepo pull
)dune build
: build the unikernel for all requested targets, located in_build/mirage-<target>/
.Then, it's possible to:
unikernel.ml
to modify the app:dune build
config.ml
to change the configuration:mirage configure -t <target> && make depends
dune build
dune install
.Updating libraries
opam update
to get the latest packages in the current switch.duniverse/
dir:mirage configure -t <target> && make depends
.dune build
to rebuild the unikernel.Locally editing a package in the dependency tree
cd duniverse && rm -rf <package> && opam source <package>
(or do a local clone of the corresponding git repository)dune build && dune test
) at the repository rootconfig.ml
to add a new pin-depends to share the changes with others.Use a custom opam repository
opam repo add <name> <url>
make depends
: duniverse will pick up the newly configured opam repository.Specific points
Testing packages / CI ?
A problem is the fact that packages destined to be built with
duniverse
only (such asmirage-solo5
) will still be published on opam, and their installation has no meaning anymore. However publishing them on opam means that they still can be tested by the opam CI. Packages that aim to be cross-compiled (thus installed by duniverse) must not have any non-dune dependency. So to test these packages, non-dune dependencies (such asocaml-freestanding
) need to be set as{with-test}
dependencies.I'm currently experimenting with an ocurrent pipeline that uses mirage-dev and mirage-skeleton to test unikernel builds: https://github.com/TheLortex/mirage-ci.
Dune
A big change in the mirage workflow is that the whole unikernel dependency tree must be built with
dune
. As a consequence, non-dune dependencies have been forked, these forks being picked up byduniverse
using an overlay repository: https://github.com/dune-universe/opam-overlays.For now, we have to maintain forks, but other solutions are to be discussed:
For a general-purpose library to be mirage-compatible, there are several requirements:
unix
library or target-specific mirage libraries such asmirage-solo5
,mirage-xen
.{build}
) on packages that are not built by dune.test
dependencies are not constrained because they are installed by opam.For target-specific mirage libraries, the requirements are the following:
{build}
) on packages that are not built by dune.test
dependencies.The text was updated successfully, but these errors were encountered: