2014-02-25 58 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'。 –