I do have a lib/dune file that says (library (name mylib)), so that would mean the module in lib/mylib.ml would be available as Mylib.Mylib and the module in lib/mymod.ml would be available as Mylib.Mymod. But that isn’t the case, i.e. this fails:
let _ = assert (Mylib.Mylib.one = 1)
let _ = assert (Mylib.Mymod.two = 2)
Instead, if I change (library (name mylib)) to (library (name foo)) (and modify test/dune accordingly), then these are suddenly available as Foo.Mylib and Foo.Mymod, i.e. this works:
let _ = assert (Foo.Mylib.one = 1)
let _ = assert (Foo.Mymod.two = 2)
If you create a mylib.ml file for a lib named mylib in the dune file, it does not behave as a submodule but rather allows you to define the content of the top-level Mylib module. This allows you to re-export some submodules for instance, with a different name.
I think so. If you want top-level values (or types) to appear in Mylib, then I think you need an explicit mylib.ml. And if you do that, then you need to define module aliases to export the inner modules.
I tried to find the relevant info in the dune documentation but it seems this is only mentioned in passing at the beginning of the documentation of the library stanza.
This matter is tentatively addressed in the new (draft) tutorial Libraries With Dune, which I have just announced. As @K_N noticed, this wasn’t very well documented.