You may be misunderstanding this bit, taken from the dune docs
(modules <modules>)
specifies what modules are part of the library. By default, Dune will use all the .ml/.re
files in the same directory as the dune
file. This includes ones present in the file system as well as ones generated by user rules. You can restrict this list by using a (modules <modules>)
field. <modules>
uses the Ordered Set Language, where elements are module names and don’t need to start with an uppercase letter. For instance, to exclude module Foo
, use (modules (:standard \ foo))
So by default Dune uses all ml files in the same directory as the dune
file. If you have only a single stanza per directory, it will be fine because no module in that directory is shared across stanzas in that dune file.
If your source directory looks like this,
bin
-- dune
-- hello.ml
-- goodbye.ml
-- shared.ml
-- math.ml
and you’re dune file looks like this:
(executables
(names hello goodbye))
It is fine…Shared
and Math
can be used by the others. But if your dune filed looks like this:
(executables
(names hello goodbye)
(libraries cool_lib))
(library
(name cool_lib))
It will not work…you will get an error about modules being used in several stanzas (ie two stanzas here). You fix it a couple of ways. Sticking with the first thing is fine. Or by restricting the modules used for each stanza with modules
like this:
(executables
(names hello goodbye)
(modules
;; Ignore the math and shared modules in this stanza
(:standard \ math shared))
(libraries cool_lib))
(library
(name cool_lib)
;; Only use math and shared modules in this stanza
(modules math shared))
Or by putting library code in a separate directory with its own dune file.
bin/
-- dune
-- hello.ml
-- goodbye.ml
lib/
-- dune
-- math.ml
-- shared.ml
With this method, bin/dune
is just one stanza
(executables
(names hello goodbye)
(libraries cool_lib))
and lib/dune
is also one stanza
(library
(name cool_lib))
and you will be okay.