Opam-nix and the solo5 toolchain

I’m trying have a go with MirageOS following the uniker.nl site, but I’m using nixos with opam-nix so am running into issues with the solo5 toolchain. Opam-nix has always worked quite nicely for me with normal packages, but I guess it doesn’t handle toolchain packages well. This is with ocaml 5.5.0, and ocaml-solo5 1.3.4.

The solo5 toolchain seems to install fine and so I can compile the basic c example fine and run that. But for the next section with the ocaml hello world (Your first unikernel in OCaml — Unikernels in OCaml), it seems that ocamlfind isn’t set up correctly to find the ocaml-solo5 toolchain and I get the following errors:

$ ocamlfind -toolchain solo5 opt -c startup.c -o startup.o
ocamlfind: [WARNING] Undefined toolchain: solo5
ocamlfind: [WARNING] Cannot read directory /nix/store/j6swz321cd4fws3kj1iq0qv3zzhs3m3g-ocaml-compiler-5.5.0/lib/ocaml/../stublibs which is mentioned in ld.conf

It does actually create an object, but it just creates a regular executable in the end which I suppose is expected if it’s defaulting to the normal toolchain.

Doing a bit of digging, the ocaml-solo5 package is set in the OCAMLPATH variable, which contains /nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml/5.5.0/site-lib, and I see in this directory there’s a findlib.conf.d/solo5.conf. Setting this explicitly with the OCAMLFIND_CONF seems to remove the undefined toolchain warning, but when trying to compile the manifest.c file it is unable to find one of the headers.

manifest.c:4:10: fatal error: mft_abi.h: No such file or directory
    4 | #include "mft_abi.h"
      |          ^~~~~~~~~~~
compilation terminated.

I suspect the fact that all the packages are store independently in separate folders are causing the issues, the solo5.conf file only refers within the ocaml-solo5 package, but it seems the mft_abi.h header is in the solo5 package. The solo5.conf is as follows:

path(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/lib/ocaml:/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/lib:/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib"
destdir(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib"
stdlib(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/lib/ocaml"
ocamlopt(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/bin/ocamlopt.opt"
ocamlc(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/bin/ocamlc.opt"
ocamlmklib(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/bin/ocamlmklib"
ocamldep(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/bin/ocamldep.opt"
ocamlcp(solo5) = "/nix/store/pyzppb4bmz1ms1c3h0vgbi524rjjslbj-ocaml-solo5-1.3.4/lib/ocaml-solo5/bin/ocamlcp"

I tried a bit more to brute force my way to at least compiling an example but you get into a mess of linking all the ocaml libraries together.

Given if I do install with opam normally it does work, what could opam-nix be missing? It would be nice to get it working because it simplifies the system dependency handling and gives you reproducible builds.

Hello! You might find GitHub - RyanGibb/hillingar: Build Mirage unikernels with Nix · GitHub useful. Please open an issue if you run into this or any other issues there.

Hello, first of all, thank you for trying out our new website for building unikernels. It is still in the experimental phase and, although we presented it during our last talk, many elements relating to deployment are still missing, such as references to builds.robur.coop and to orb, which would allow us to verify the reproducibility of our unikernels.

Unfortunately, as we are not NixOS users, we do not have the expertise to get all our libraries working with opam-nix in particular.

As I understand it, we would need to make Solo5 and ocaml-solo5 compatible with Nix, particularly with regard to the generated files and their installation. However, we would be delighted to improve these two pieces of software to make them compatible with NixOS.

More broadly speaking, our approach is also to encourage a more inclusive form of contribution and collaboration from people who do not necessarily possess all the expertise required for the development and deployment of unikernels (we are referring here to a form of democratisation).

Unfortunately, I don’t think this solution is any longer suitable because, as we mentioned during our last talk, we are offering new tools (namely, unic and mfetch) to develop unikernels, rather than the one provided by Mirage.

Yes as @dinosaure said, I think the new approach should make the build a lot simpler, and hopefully something simpler than hillingar can be used in future. It would in particular be good to get development shells working so that you can do normal development workflows.

I’m not actually sure solo5 and ocaml-solo5 would need to be made compatible, I think the problem is that opam-nix would need to support toolchain packages, though I’m not entirely sure what might need changing. I was hoping to understand better what is missing atm, and then can hopefully raise PR’s to whatever components need changing.

I was not aware that robur is no longer using the mirage cli. In that case, I would say I found it very helpful to open an issue on the opam-nix repository and talk to @balsoft.