假设我有一组模块,每个模块都是#34;浓密的"与子模块。
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
现在,使用Oasis'为M1
,M2
和M3
中的每一个构建项目目录都很容易。 Pack:
选项。特别是,我喜欢和想要解决的问题是:(a)能够以标准.ml
/ .mli
格式布置我的文件和(b)正确生成ocamldoc
链接文档。
但是,由于我希望将M1
,M2
和M3
中的每一个分布在公共模块层次结构下的同一个库中,因此我无法使用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也可能无法做到这一点。在这种情况下,关于如何使用其他构建工具的建议是可接受的并且是受欢迎的。假设我对其他工具的理解很少......因为它可能是真的!
答案 0 :(得分:7)
pack
中的oasis
有点破碎,因为它通过将所有路径包含在搜索路径中来破坏命名空间。有一个长期存在的错误请求,但事情仍然存在。但是,如果它正常工作,它可以帮助您,因为它将创建一个库命名空间,允许您在不同的文件夹中具有相同名称的模块。但是,它不起作用,所以我们应该忘记它。
我们在BAP项目中采用的方法是使用丑陋的bap_subproject_
前缀来破坏所有模块名称,以保护我们免受与我们自己的模块的冲突,以及来自外部库的冲突。对于每个bap_subproject
,我们有一个文件夹,其中包含所有具有错位名称的实现模块和一个伞形模块来统治它们。此模块存储在文件bap_subproject.ml
中,它定义了要导出的所有模块和类型的别名。通常它包含如下条目:
module X = Bap_subproject_x
还有一个很大的Bap
项目,它将所有子库联合在一个名称空间Bap.Std
下,然后重新导出它需要的所有内容,以便在一个open Bap.Std
之后拥有并访问{{ 1}} Insn
免责声明:如果您使用插件扩展,此解决方案仍可以使用oasis。
我们在一个项目中使用过这种方法,遗憾的是闭源,所以我无法提供链接。每个子项目都存在于自己的子文件夹中,在它自己的命名空间内(我们在每个子文件夹中都有bap_disasm/bap_disasm_insn.ml[i]
模块,没有任何破坏程序)。对于每个子项目,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
冲突,因为Lexer
文件夹实际上从不包含在搜索路径中。
如果您需要在系统中添加另一个图层,例如包装包,那么您有三种选择:
expr
或mlpack
个文件。mllib
'ed modules big.mlpack
mlpack
。 最后两种方法要求顶级打包模块当然具有不同的名称。但通常这是公平的。