使用ocamlc独立编译库
Using ocamlc to compile libraries independently
我有三个文件:
$ ls
lib.ml desk.ml test.ml
$ cat lib.ml
let myfunction () = print_endline "Hello world"
$ cat desk.ml
module Liberty = Lib
$ cat test.ml
Desk.Liberty.myfunction ()
我想编译一个 desk.cma
不 公开模块 Lib
,但能够使用它。例如,我试过:
$ ocamlc -a lib.ml -o lib.cma
$ ocamlc -a lib.cma desk.ml -o desk.cma
$ ocamlc desk.cma test.ml -o test.byte
不幸的是,如果您将 test.ml
更改为 Lib.myfunction ()
,相同的编译步骤就可以正常工作。我想要它,这样 Lib
就不会暴露给 test.ml
而只暴露给 desk.ml
。有谁知道如何做到这一点?非常感谢!
您要求 Lib
成为 Desk
可以使用的 desk.cma
的模块,但不能使用其他模块。我很确定 cma 文件的结构不提供这种控制。
如果您在 Desk
中定义 Lib
,您可以将其设为隐藏细节。
$ ls
desk.ml desk.mli test1.ml test2.ml test3.ml
$ cat desk.ml
module Lib = struct
let myfunction () = print_endline "Hello world"
end
module Liberty = Lib
$ cat desk.mli
module Liberty : sig
val myfunction : unit -> unit
end
$ cat test1.ml
Desk.Liberty.myfunction ()
$ cat test2.ml
Lib.myfunction ()
$ cat test3.ml
Desk.Lib.myfunction ()
Liberty 模块对测试程序可见,但 Lib 模块不可见:
$ ocamlc -c desk.mli
$ ocamlc -a desk.ml -o desk.cma
$ ocamlc desk.cma test1.ml -o test1.byte
$ ./test1.byte
Hello world
$ ocamlc desk.cma test2.ml -o test2.byte
File "test2.ml", line 1, characters 0-14:
Error: Unbound module Lib
$ ocamlc desk.cma test3.ml -o test3.byte
File "test3.ml", line 1, characters 0-19:
Error: Unbound module Desk.Lib
您可以在单独的文件中实现 Lib,然后 include
将其放入 Desk.Lib
模块的定义中。
我怀疑这不是一个完全令人满意的答案,但我希望它有所帮助。
您似乎在寻找 OCaml 的 -pack
机制。这允许您从多个编译单元(如 pack.cma
库)创建 pack.cmo
(或 pack.cmx
用于本机编译),但具有额外的优势,您可以拥有相应的 pack.mli
界面,您可以使用该界面隐藏本应属于 pack
的部分。在你的例子中,你可以有:
--lib.ml--
let myfunction () = print_endline "Hello world"
--liberty.ml--
include Lib
--desk.mli--
(* No module Lib: Lib will not be seen outside of the pack. *)
module Liberty: sig
val myfunction: unit -> unit
end
然后你可以用
编译它
ocamlc -for-pack Desk -c lib.ml
ocamlc -for-pack Desk -c liberty.ml
ocamlc desk.mli
ocamlc -pack -o desk.cmo lib.cmo liberty.cmo
这将为您提供一个模块 Desk
,其中仅包含 Liberty
个 sub-module。当然,desk.mli
可以用来获得更多的 fine-grained 限制,例如与
module Lib: sig end
module Liberty: sig val myfunction: unit -> unit end
你用空签名导出 Lib
,从而隐藏了 Lib
.
中的一个(尽管是示例中唯一的一个 ;-P)函数
我有三个文件:
$ ls
lib.ml desk.ml test.ml
$ cat lib.ml
let myfunction () = print_endline "Hello world"
$ cat desk.ml
module Liberty = Lib
$ cat test.ml
Desk.Liberty.myfunction ()
我想编译一个 desk.cma
不 公开模块 Lib
,但能够使用它。例如,我试过:
$ ocamlc -a lib.ml -o lib.cma
$ ocamlc -a lib.cma desk.ml -o desk.cma
$ ocamlc desk.cma test.ml -o test.byte
不幸的是,如果您将 test.ml
更改为 Lib.myfunction ()
,相同的编译步骤就可以正常工作。我想要它,这样 Lib
就不会暴露给 test.ml
而只暴露给 desk.ml
。有谁知道如何做到这一点?非常感谢!
您要求 Lib
成为 Desk
可以使用的 desk.cma
的模块,但不能使用其他模块。我很确定 cma 文件的结构不提供这种控制。
如果您在 Desk
中定义 Lib
,您可以将其设为隐藏细节。
$ ls
desk.ml desk.mli test1.ml test2.ml test3.ml
$ cat desk.ml
module Lib = struct
let myfunction () = print_endline "Hello world"
end
module Liberty = Lib
$ cat desk.mli
module Liberty : sig
val myfunction : unit -> unit
end
$ cat test1.ml
Desk.Liberty.myfunction ()
$ cat test2.ml
Lib.myfunction ()
$ cat test3.ml
Desk.Lib.myfunction ()
Liberty 模块对测试程序可见,但 Lib 模块不可见:
$ ocamlc -c desk.mli
$ ocamlc -a desk.ml -o desk.cma
$ ocamlc desk.cma test1.ml -o test1.byte
$ ./test1.byte
Hello world
$ ocamlc desk.cma test2.ml -o test2.byte
File "test2.ml", line 1, characters 0-14:
Error: Unbound module Lib
$ ocamlc desk.cma test3.ml -o test3.byte
File "test3.ml", line 1, characters 0-19:
Error: Unbound module Desk.Lib
您可以在单独的文件中实现 Lib,然后 include
将其放入 Desk.Lib
模块的定义中。
我怀疑这不是一个完全令人满意的答案,但我希望它有所帮助。
您似乎在寻找 OCaml 的 -pack
机制。这允许您从多个编译单元(如 pack.cma
库)创建 pack.cmo
(或 pack.cmx
用于本机编译),但具有额外的优势,您可以拥有相应的 pack.mli
界面,您可以使用该界面隐藏本应属于 pack
的部分。在你的例子中,你可以有:
--lib.ml--
let myfunction () = print_endline "Hello world"
--liberty.ml--
include Lib
--desk.mli--
(* No module Lib: Lib will not be seen outside of the pack. *)
module Liberty: sig
val myfunction: unit -> unit
end
然后你可以用
编译它ocamlc -for-pack Desk -c lib.ml
ocamlc -for-pack Desk -c liberty.ml
ocamlc desk.mli
ocamlc -pack -o desk.cmo lib.cmo liberty.cmo
这将为您提供一个模块 Desk
,其中仅包含 Liberty
个 sub-module。当然,desk.mli
可以用来获得更多的 fine-grained 限制,例如与
module Lib: sig end
module Liberty: sig val myfunction: unit -> unit end
你用空签名导出 Lib
,从而隐藏了 Lib
.