2017-02-07 3 views
0

Ich habe drei Dateien:Mit ocamlc Bibliotheken kompilieren unabhängig

$ 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() 

Ich möchte ein desk.cma kompilieren, die nicht Setzen Sie das Modul Lib, macht aber in der Lage, davon Gebrauch zu machen. Zum Beispiel habe ich versucht:

$ ocamlc -a lib.ml -o lib.cma 
$ ocamlc -a lib.cma desk.ml -o desk.cma 
$ ocamlc desk.cma test.ml -o test.byte 

Leider, wenn Sie test.ml ändern Lib.myfunction() die gleichen Schritten erstellt werden gut funktionieren. Ich möchte es so, dass Lib nicht test.ml ausgesetzt ist und nur desk.ml ausgesetzt. Weiß jemand, wie man das macht? Vielen Dank!

Antwort

1

Es sieht so aus, als ob Sie nach dem -pack Mechanismus von OCaml suchen. Dies ermöglicht es Ihnen, eine pack.cmo (oder pack.cmx für native Kompilierung) aus mehreren Kompilierungseinheiten, wie einer pack.cma Bibliothek, aber mit dem zusätzlichen Vorteil, dass Sie eine entsprechende pack.mli Schnittstelle haben können, mit der Sie die Teile verstecken können, die intern sein sollten pack. In Ihrem Beispiel könnten Sie zum Beispiel haben:

- 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 

Dann können Sie das kompilieren mit

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 

Dadurch erhalten Sie ein Modul Desk, das nur Liberty ein Untermodul enthält. Natürlich kann desk.mli verwendet werden, um eine feinkörnigere Beschränkung, z. mit

module Lib: sig end 

module Liberty: sig val myfunction: unit -> unit end 

Sie Lib mit einer leeren Unterschrift exportieren, so dass ein einzigen (wenn auch die einzigen im Beispiel ;-P) Funktion von Lib versteckt.

+0

Cool danke sehr! – Kites

0

Sie fragen, dass Lib ein Modul desk.cma ist, das Desk verwenden kann, aber keine anderen Module. Ich bin mir ziemlich sicher, dass die Struktur einer CMA-Datei diese Art von Kontrolle nicht bietet.

Wenn Sie Lib innerhalb Desk definieren, können Sie es zu einem versteckten Detail machen.

$ 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() 

Die Liberty-Modul ist auf die Testprogramme sichtbar, aber der Lib-Modul ist nicht:

$ 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 

Sie Lib in einer separaten Datei implementieren können, ist es dann include in die Definition der Desk.Lib Modul.

Ich vermute, das ist keine befriedigende Antwort, aber ich hoffe, es ist hilfreich.

Verwandte Themen