2014-02-25 96 views
2

我已閱讀this question等, 但我的編譯問題尚未解決。OCaml模塊的單獨編譯

我測試單獨的編譯與這些文件:

testmoda.ml

module Testmoda = struct 
    let greeter() = print_endline "greetings from module a" 
end 

testmodb.ml

module Testmodb = struct 
    let dogreet() = print_endline "Modul B:"; Testmoda.greeter() 
end 

testmod.ml

let main() = 
    print_endline "Calling modules now..."; 
    Testmoda.greeter(); 
    Testmodb.dogreet(); 
    print_endline "End." 
;; 
let _ = main() 

現在我產生.mli fil e

ocamlc -c -i testmoda.ml >testmoda.mli 

和testmoda.cmi在那裏。

接下來,我創建一個沒有錯誤的.c​​mo文件:

ocamlc -c testmoda.ml 

很好,所以做同樣的testmodb.ml:

[email protected]:~/Ocaml/ml/testmod> ocamlc -c -i testmodb.ml >testmodb.mli 
File "testmodb.ml", line 3, characters 45-61: 
Error: Unbound value Testmoda.greeter 

闖闖:

[email protected]:~/Ocaml/ml/testmod> ocamlc -c testmoda.cmo testmodb.ml 
File "testmodb.ml", line 3, characters 45-61: 
Error: Unbound value Testmoda.greeter 

其他組合也失敗了。

如何編譯testmodb.ml和testmod.ml?這應該很容易 - 沒有ocamlbuild/omake/ 綠洲,我想。在文件

語法錯誤被排除在外, 如果我的貓在一起,以一個文件(之間所需的空間)彙編 和完美的執行。

回答

5

OCaml在每個源文件的頂層爲您提供一個免費的模塊。所以你的第一個模塊實際上被命名爲Testmoda.Testmoda,該函數被命名爲Testmoda.Testmoda.greeter,依此類推。如果你的文件只包含函數定義,情況會更好。

作爲一個方面的評論,如果你打算使用由ocamlc -i生成的界面,你真的不需要mli文件。缺少mli文件的界面與ocamlc -i生成的界面相同。如果您不想使用默認界面,則使用ocamlc -i爲您的mli文件提供了一個很好的起點。但是對於這樣一個簡單的例子來說,它使事情看起來比實際情況複雜得多(恕我直言)。

如果您修改文件爲我描述(除去多餘的模塊聲明),你可以編譯並從頭開始運行如下:

$ ls 
testmod.ml testmoda.ml testmodb.ml 
$ cat testmoda.ml 
let greeter() = print_endline "greetings from module a" 
$ cat testmodb.ml 
let dogreet() = print_endline "Modul B:"; Testmoda.greeter() 
$ ocamlc -o testmod testmoda.ml testmodb.ml testmod.ml 
$ ./testmod 
Calling modules now... 
greetings from module a 
Modul B: 
greetings from module a 
End. 

如果已經編制了一份文件(ocamlc -c file.ml)可以代替.ml.cmo在上述命令。即使所有的文件名都是.cmo文件,這也是有效的;在這種情況下,ocamlc只是將它們鏈接在一起。

+0

哦奇蹟,沒有明確的模塊定義它按預期工作,'ocamlc -c testmoda.ml'創建.cmi和。cmo,後者可用於編譯testmod.ml - 單獨編譯。 –

+1

(無法編輯評論)所以在這裏單獨編譯:'ocamlc -c testmoda.ml; ocamlc -c testmodb.ml; ocamlc -o testmod testmoda.cmo testmodb.cmo testmod.ml' –

+0

請注意,我給出的單個命令也會分開編譯:-)它完全等同於這三個命令。但是,當然有時候你只想編譯一個源文件。它也適用於'testmod.ml'。 –