How to create a hierarchy of a tiered module with (or without) Oasis

Suppose I have a set of modules, each of which is rather "dense" with submodules.

M1.X M2.X M3.X M1.Y M2.Y M3.Y M1.Z M2.Z M3.Z M1.W M2.W M3.W M1.Q M2.Q M3.Q M1.P M2.P M3.P 

In addition, I would like each of these bushes to sit under one main module.

 Home.M1 Home.M2 Home.M3 

Now it is easy to structure the project directory for each of M1 , M2 and M3 using the Oasis Pack: option. In particular, what I like and I’m trying to solve is (a) the ability to upload my files in the standard .ml / .mli and (b) have ocamldoc to create properly linked documentation.

But since I would like to distribute each of M1 , M2 and M3 in the same library under a common hierarchy of modules, I cannot use Pack: and instead I have to drop the whole damn thing into one file so that (a) it’s not accidental to bring down global namespace; (b) do not propagate modules throughout the Home. namespace Home. which are not intended for direct use, and (c) do not break the ocamldoc binding.

So my question is, given the goals suggested above, how can I use Oasis to create a package with hierarchical modules of this form?

Some additional restrictions include:

  • It is no coincidence that the modules under the namespaces M1. , M2. and M3. conflict - this happens in a real situation!
  • Modules in the M2. namespace M2. and M3. depend on modules in the M1. namespace M1. .

My preference would be to come up with a solution that also allows a reasonable arrangement of files, for example.

 src -+ +-- m1 -+ | +-- x.ml | +-- x.mli | +-- y.ml | +-- y.mli | +-- z.ml | +-- z.mli | | | ... | | +-- m2 -+ | +-- x.ml | +-- x.mli | +-- y.ml | +-- y.mli | +-- z.ml | +-- z.mli | | | ... | | +-- m3 -+ +-- x.ml +-- x.mli +-- y.ml +-- y.mli +-- z.ml +-- z.mli | ... 

It is also possible that this is not possible with Oasis. In this case, suggestions on how to use other build tools are acceptable and welcome. Suppose I have little understanding of other tools ... because that is probably true!

+7
module ocaml oasis
source share
1 answer

With an oasis

pack in oasis bit broken as it compresses the namespace, including all paths in the search path. There is a long-awaited accepted error request, but still stays where they are. But if it worked correctly, it can help you, as it will create library namespaces, allowing you to have modules with the same name in a different folder. But this does not work, so we must forget about it.

The approach we took in the BAP project was to cripple all module names with the ugly bap_subproject_ prefix, which protects us from conflicts with our own modules, as well as from conflicts coming from external libraries. For each bap_subproject , we have a folder with all implementation modules with malformed names and one umbrella module to manage them all. This module is stored in the bap_subproject.ml file, where it defines aliases for all modules and types that it is going to export. It usually contains entries like:

 module X = Bap_subproject_x 

There is also a large Bap project that consolidates all subareas under one Bap.Std namespace and re-exports everything it needs, so after one open Bap.Std you have access to the Insn module, which is defined in bap_disasm/bap_disasm_insn.ml[i]

No oasis

Disclaimer: This solution may still work with the oasis if you expand it with the plugin.

We used this approach in one project, which, unfortunately, is closed, so I can not provide a link. Each subproject lives in its own subfolder, within its own namespace (we had a parser module in each subfolder, without any clobber). For each subproject, the mlpack file is mlpack in the top folder:

  root + | +-- expr.mlpack +-- expr -+ | +- lexer.* +- parser.* +- ast.* +- ... +-- cameo.mlpack +-- cameo-+ | +- lexer.* +- parser.* +- ast.* +- ... 

The content of expr.mlpack :

  expr/Lexer expr/Parser expr/Ast ... 

ocamlbuild sees this expr.mlpack as a standalone module that has Lexer , parser , etc. submodules defined in it (and available as, for example, Expr.Lexer ). And there are no conflicts with the sibling project, which also has Lexer , and also does not conflict with ocaml-libs or any other external Lexer , since the expr folder is never really included in the search path.

If you need to add another layer to your system, for example a package for packages, then you have three options:

  • use the same approach recursively, i.e. create another super-folder in which there are mlpack or mllib files pointing to the child folder.
  • just add big.mlpack which references all toplevel mlpack 'ed modules
  • create big.ml , which re-introduces all the modules.

The last two approaches require that top-level packaged modules have different names. But this is usually true.

+7
source share

All Articles