-
Notifications
You must be signed in to change notification settings - Fork 441
Description
First of all, thanks for your work on dune! This is an amazing piece of work.
I recently wanted to remove a lot of functors from MirageOS, since they're not really necessary -- we have at runtime only one thing around anyways (i.e. the network interface for xen will always be one thing -- while the network interface when compiling for unix will be something else). This sounded to me like a perfect use case for your dune variant feature. To a small scale it seemed to work fine, but once I "variantified" the TCP/IP stack, I get not very nice results.
Expected Behavior
I'd expect from a dune
file with an executable
statement that depends on some variants that those will be used across the compilation.
Actual Behavior
File "duniverse/mirage-net/unix/dune", line 4, characters 52-60:
4 | (libraries common logs macaddr cstruct cstruct-lwt lwt.unix tuntap)
^^^^^^^^
Error: Library "lwt.unix" in _build/solo5/duniverse/lwt/src/unix is hidden
(optional with unavailable dependencies).
-> required by library "mirage-net.unix" in
_build/solo5/duniverse/mirage-net/unix
-> required by library "tcpip.icmpv4-direct" in
_build/solo5/duniverse/mirage-tcpip/src/icmp/direct
So, instead of the variant specified in the executable
statement, the default variant is used. :(
Reproduction
Unfortunately, this is rather big at the moment, but let me try:
- OCaml 4.14.2
- dune 3.15.0
- mirage from https://github.com/hannesm/mirage/tree/mirage-logs-no-clock
- mirage-net from https://github.com/hannesm/mirage-net/tree/variants
- ethernet from https://github.com/hannesm/ethernet/tree/variants
- arp from https://github.com/hannesm/arp/tree/variants
- mirage-clock from https://github.com/hannesm/mirage-clock/tree/variants
- mirage-time from https://github.com/hannesm/mirage-time/tree/variants
- mirage-logs from https://github.com/hannesm/mirage-logs/tree/clock-variants
- mirage-solo5 from https://github.com/hannesm/mirage-solo5/tree/variants
- mirage-crypto-rng-mirage from https://github.com/hannesm/mirage-crypto/tree/rng-defunctor
- tcpip from https://github.com/hannesm/mirage-tcpip/tree/defunctorise
With all of that, I try to compile the "device-usage/network" unikernel from https://github.com/hannesm/mirage-skeleton/tree/variants
So, the step(s) to reproduce is:
- install a fresh switch (OCaml 4.14.2)
- opam pin the mirage utility
- clone the mirage-skeleton repository from my branch above
- opam pin add -n for the above list
- cd mirage-skeleton/device-usage/network ; mirage configure -t solo5 ; make lock pull build
Variant specifications
At the moment, I specify the default_implementation to be "mirage-net.unix", but in the generated dune file, there is: (libraries ... mirage-net.solo5 ...
.
I have no idea, why, as seen above, dune thinks that tcp.icmpv4-direct requires a mirage-net implementation at all, and furthermore how it decides to try the .unix
one.
Debug avenues - remove default_implementation
I tried to remove the default_implementation
from the above mentioned packages. This results in the following error:
dune build --profile release --root . ./dist
Error: No implementation found for virtual library "mirage-net" in
_build/solo5/duniverse/mirage-net/src.
-> required by library "ethernet" in _build/solo5/duniverse/ethernet/src
-> required by library "tcpip.ipv4" in
_build/solo5/duniverse/mirage-tcpip/src/ipv4/interface
-> required by library "tcpip.icmpv4-direct" in
_build/solo5/duniverse/mirage-tcpip/src/icmp/direct
-> required by executable main in dune.build:11
-> required by _build/solo5/main.exe
-> required by _build/solo5/network.hvt
-> required by _build/solo5/dist/network.hvt
-> required by alias dist/all (context solo5)
-> required by alias dist/default (context solo5)
Still, mirage-net.solo5
is a dependency in the dune
file.
Move all default_implementations to those I want to use
Yes, this indeed works. But it is pretty unpleasant (would need a shell script for postprocessing), since I had hoped the variant feature would exactly provide me with this:
- I define virtual libraries and default implementation
- My library code uses virtual libraries
- The only thing is at top-level (linking time, where I specify the executable) selecting the concrete implementation.
Quo vadis?
So, any pointers how I can debug this issue further? Or do I hit an intended limit of dune variants that I was not aware of?
Thanks a lot for your time reading this issue. 🐫 🐫