Dune:构建库并在另一个项目中访问它并隐藏或使无法访问的私有或实现模块

问题描述

我正在使用 Dune 来构建 OCaml 项目,我想构建一个独立的库以便在其他项目中重用它。

库的根文件夹是 mylib,库初始化为 dune init lib mylib src(在 cd mylib 之后)。

项目根目录mylib的目录树如下:

mylib
+---dune-project
│
+---src
        dune
        priv.ml
        mymodule.ml
        mymodule.mli

这里是文件内容

mylib/dune-project

(lang dune 2.7)

mylib/src/dune

(library
 (name mylib))

mylib/src/priv.ml

let rec loop a accu i =
  let n = Array.length a in
  if i = n then
    accu
  else
    loop a (accu + Array.unsafe_get a i) (succ i)

mylib/src/mymodule.mli

val sum : int array -> int

mylib/src/mymodule.ml

let sum a =
  Priv.loop a 0 0

在给出上下文并显示这个玩具示例的每个文件内容后,问题如下:

  1. 如何构建库 mylib 并在另一个单独的项目中使用它?

(例如,在另一个项目中,我会使用以下内容使用该库:

Open Mylib
let () =
  print_int (Mymodule.sum [1;2;3])

let () =
  print_int (Mylib.Mymodule.sum [1;2;3])

)

对于 Dune,给定可执行文件 main,您将编写以下 dune 文件以使用库 mylib(如果它在 Opam 上发布)。

沙丘

(executable
 (name main)
 (libraries mylib))
  1. 成功构建库并将其链接到另一个项目后,如何隐藏或不公开某些模块?例如,鉴于之前的玩具库 mylib,我不想暴露模块 Priv 并使模块不可访问(这样 Priv 只能在 {{1} 的模块内使用}} - 就像 Java/C# 中的受保护/内部类一样)。

我尝试在 Real World OCamlCornell CS3110 textbookDune documentationOCaml Learn 上进行搜索,但是,除非嵌套很深,否则我一无所获。

非常感谢您的帮助,如果我没有解释清楚,请追问,我会尽量解释得更好。

解决方法

  1. 在根目录中,这些应该是一个名为 mylib.opam 的文件,其内容类似于 this one。然后,应将 (public_name mylib) s 表达式添加到 mylib/src/dune 中的 library。最后,确保在项目的根目录中,库应使用 dune build 构建并使用 opam install . 安装。
    要在另一个项目中实际使用该库,即使在不同的沙丘工作区中,只需将 (libraries mylib) 添加到将使用该库的项目的沙丘文件中。
  2. 应该将 (private_modules priv) s 表达式添加到 mylib/src/dune 中的 library。然后,需要使用以下内容创建 mylib.mlmodule Mymodule = Mymodule:这将确保只有 Mymodule 会在包 Mylib 下公开。