2012-10-07 165 views
5

我是Ocaml的新手,並試圖編寫一些小示例應用程序。我在Linux Ubuntu 10.04下使用ocamlc版本3.11.2。我想編譯兩個文件:編譯多個Ocaml文件

a.ml 
b.ml 

文件b.ml使用的定義從a.ml。據我所知,我只能使用ocamlc -c來執行編譯。當我將所有.cmo文件鏈接到可執行文件時,我可以最後一次致電ocamlc。另外,編譯使用另一個文件定義的文件時,我必須告訴編譯器在哪個文件中找到外部定義。

所以我的想法是使用:

ocamlc -i -c a.ml > a.mli 
ocamlc -c a.mli b.ml 
ocamlc -o b a.cmo b.cmo 

的第一步作品,併產生文件a.mlia.cmo,但運行第二步,當我得到

File "b.ml", line 1, characters 28-31: 
Error: Unbound value foo 

其中foo是一個函數,在a.ml中定義並在b.ml中調用。

所以我的問題是:我如何分別編譯每個源文件並指定要在命令行上導入的接口?我一直在查看文檔,並且據我所知,我必須指定要包含的.mli文件,但我不知道如何。

編輯

這裏一些更多的細節。文件a.ml包含

let foo = 5;; 

文件b.ml包含表達

print_string (string_of_int foo)^"\n";; 

真正的例子是大,但這些文件我已經有我上面報告錯誤的定義。

EDIT 2

我已經編輯文件b.mlA.foo更換foo和這個工程(foo是可見b.ml即使我有另一個編譯錯誤,這並不重要,這個問題)。我想這是明確寫我自己的.mli文件,如

+1

您是否打開A中的B ?,因爲否則這沒有任何意義。 –

+0

不需要在A中定義一個模塊並在B中打開它嗎?目前,A中的所有定義都是全局的(我沒有模塊)。 – Giorgio

+1

每個OCaml文件都有一個隱式模塊。所以你的文件'a.ml'定義了一個名爲'A'的模塊。 –

回答

5

建議,如果你顯示的代碼不工作,這將更清晰。正如Kristopher指出的那樣,最可能的問題是您沒有指定模塊foo所在的模塊。您可以明確指定模塊,如A.foo。或者您可以使用open A,並使用名稱foo

對於一個小例子它並不重要,但對於一個大項目,您應該小心,不要太自由地使用open。你想要在模塊中使用好名字的自由,如果你打開太多的名字,好名字可能會相互衝突。

5

首先修復unbound value問題,正如Jeffrey的答案所解釋的那樣。 這是對您正在使用的命令的評論。

分幾步分解編譯是瞭解發生了什麼的好方法。 如果你想編寫你自己的a.mli,最有可能隱藏模塊A的一些值,那麼你的命令ocaml -i -c a.ml > a.mli是獲得該文件的第一版本然後編輯它的好方法。但是,如果你不接觸a.mli,那麼你並不需要生成它:您也可以直接輸入

ocamlc -o foo a.ml b.ml 

這將產生a.cmob.cmo和exectuable foo

(這也將產生a.cmi,這是a.mli的編譯版本,您通過發行ocamlc -c a.mli得到,同樣也會產生b.cmi)。

請注意,訂單很重要:您需要在命令行上提供b.ml之前的a.ml。這樣,在編譯b.ml時,編譯器已經看到了a.ml並知道在哪裏可以找到模塊A


一些更多的評論:

  • 你就在你 「據我瞭解」 的段落。
  • 你真的不包括一個單獨的文件,它更像進口在Python:模塊A的值是可用的,但在名稱A.fooa.ml的內容尚未被複制粘貼到b.ml中,而是訪問了a.ml中定義的模塊A的值以及編譯後的版本a.cmo
  • 如果你在b.ml使用此模塊A,您可以b.ml前通過任何命令行上以下內容:
    • a.mli,如果你已經將編譯到a.cmi
    • a.cmi編譯a.mlia.cmi
    • a.ml或它的編譯版本a.cmo,如果你不需要編寫自己的a.mli,也就是說,如果模塊的默認界面適合你。 (這個接口只是每個值a.ml)。