7

假设我有一组模块,每个模块都带有子模块。

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

此外,我希望这些灌木中的每一个都位于一个主模块下。

Home.M1
Home.M2
Home.M3

现在,很容易为每个M1M2M3使用 OasisPack:选项构建项目目录。特别是,我喜欢并试图解决的是(a)以标准.ml/.mli格式布置文件的能力和(b)ocamldoc生成正确链接的文档。

但是由于我想在一个公共模块层次结构下分发每个M1,M2M3在同一个库中,我不能使用Pack:,而是被迫将整个该死的东西放入一个文件中,以便 (a) 不会意外破坏全局命名空间,(b) 不会意外地在整个Home.命名空间中扩散不打算直接使用的模块,以及 (c) 不会破坏 ocamldoc 链接。

所以我的问题是,根据上述建议的目标,我如何使用 Oasis 创建具有这种形式的分层模块的包?

一些额外的限制包括:

  • M1., M2., 和M3.命名空间下的模块发生冲突绝非偶然——在真实情况下也会发生这种情况!
  • M2.和命名空间中的模块M3.依赖于命名空间中的模块M1.

我的偏好将能够得出一个解决方案,该解决方案还允许合理的文件布局,例如

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
             |
             ...

也有可能这对 Oasis 来说是不可能的。在这种情况下,关于如何使用其他构建工具的建议是可以接受和欢迎的。假设我对其他工具知之甚少……因为这可能是真的!

4

1 回答 1

7

有绿洲

packinoasis有点损坏,因为它通过将所有路径包含到搜索路径中来破坏命名空间。有一个长期接受的错误请求,但事情仍然存在。但是,如果它工作正常,它可以帮助你,因为它会创建一个库命名空间,允许你在不同的文件夹中拥有同名的模块。但是,它不起作用,所以我们应该忘记它。

我们在BAP项目中采用的方法是使用丑陋的bap_subproject_前缀来破坏所有模块名称,这样可以保护我们免受与我们自己的模块的冲突,以及来自外部库的冲突。对于每一个bap_subproject,我们都有一个文件夹,其中包含所有名称混乱的实现模块和一个总括模块来管理它们。该模块存储在文件bap_subproject.ml中,它为要导出的所有模块和类型定义别名。通常它包含以下条目:

module X = Bap_subproject_x

还有一个大Bap项目,它将所有子库联合在一个命名空间下Bap.Std,并重新导出它需要的所有内容,这样之后open Bap.Std你就可以访问Insn定义在bap_disasm/bap_disasm_insn.ml[i]

没有绿洲

免责声明:如果您使用插件扩展此解决方案,它可能仍适用于 oasis。

我们在一个项目中使用了这种方法,不幸的是它是封闭源代码,所以我无法提供链接。每个子项目都存在于它自己的子文件夹中,在它自己的命名空间中(我们parser在每个子文件夹中都有模块,没有任何破坏)。对于每个子项目,文件夹中都有一个mlpack文件top

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

的内容expr.mlpack是:

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

ocamlbuild将其expr.mlpack视为一个独立的模块,其中定义了Lexer,Parser等子模块(并且可以访问为,例如Expr.Lexer)。并且与也有的同级项目没有冲突,也Lexer没有与ocaml-libs任何其他 external冲突Lexer,因为该expr文件夹实际上从未包含在搜索路径中。

如果您需要在系统中添加另一层,例如一个包一个包,那么您有三个选择:

  1. mlpack递归地使用相同的方法,即创建另一个超级文件夹,其中包含mllib指向子文件夹的文件。
  2. 只需添加big.mlpack引用所有顶级mlpack'ed模块
  3. 创建big.ml重新引入所有模块。

最后两种方法当然需要顶级打包模块具有不同的名称。但通常这是足够公平的。

于 2015-02-25T15:49:54.523 回答