Qui*_*ieh 4 c++ ocaml compilation
我是OCaml的新手,我对.cma,.cmo和.cmx的文件感到困惑.有时我必须在编译命令中包含.cma文件,但有时我必须包含.cmo文件.
为什么图书馆会有这样的差异?它是C++中与库相同的概念并包含路径吗?
示例:ocamlc -o executable str.cma extstring.cmo mycode.ml
谢谢
你可能认为那.cmo是图书馆,但事实并非如此.
.cmo是字节码对象文件.就像.class在Java中一样..cma是字节码库.它是通过存档一些.cmo来制作的.cma.cmx由ocamlopt(本机代码编译器)生成.主要输出文件ocamlopt就是.o,但ocamlopt也产生了.要创建可执行文件,我们会安排.cmo并.cma喜欢ocamlc -o executable lib.cma a.cmo b.cmo ...链接它们.
你可以写.ml,而不是在这里.cmo,但它是一样的编译.ml与-c和链接.cmo和其他文件.
对于你的深层不足,最好检查每个文件(与ocaml相关)是如何产生的.
让我们看看ocamlc和生成什么文件ocamlopt.
[/tmp/test] ls
test.ml
[/tmp/test] cat ./test.ml
let id x = x
[/tmp/test] ocamlc -c /tmp/test/test.ml
[/tmp/test] ls
test.cmi test.cmo test.ml
[/tmp/test]
Run Code Online (Sandbox Code Playgroud)
现在我编译test.ml文件并ocamlc使用-c选项编译它(test.ml这里的内容无关紧要).你看到ocamlc输出两个文件:
test.cmi:编译的接口文件.该文件包括函数的类型信息,test.ml用于单独编译的变量.test.cmo:字节码对象文件:它就像.classJava中的文件一样.我们使用.cmo文件来创建可执行文件.
[/tmp/test] ocamlc -c test.ml
[/tmp/test] ocamlc -o a.out test.cmo
[/tmp/test] ls
a.out test.cmi test.cmo test.ml
Run Code Online (Sandbox Code Playgroud)
您看到a.out文件是通过该.cmo文件生成的.
.cma是库文件.这些是通过组合多个.cmo文件产生的.
[/tmp/test] ls
test.ml lib.ml
[/tmp/test] cat lib.ml
let i = Test.id 1
let j = Test.id 2
[/tmp/test] ocamlc -c test.ml; ocamlc -c lib.ml
[/tmp/test] ls
lib.cmi lib.cmo lib.ml test.cmi test.cmo test.ml
[/tmp/test] ocamlc -a -o testlib.cma ./test.cmo lib.cmo
[/tmp/test] ls
lib.cmi lib.cmo lib.ml test.cmi test.cmo test.ml testlib.cma
Run Code Online (Sandbox Code Playgroud)
现在,我创建lib.ml(使用id功能test.ml)和编译test.ml和lib.ml,然后将它们链接到创建testlib.cma(选项-a意味着创建一个库).
你可以看到.cma只是包含.cmo文件.
要使用该库,我们只需将其与其他目标文件一起排列.
[/tmp/test] cat user.ml
let _ = print_int (Lib.i + Lib.j)
[/tmp/test] ocamlc -c user.ml
[/tmp/test] ocamlc -o a.out testlib.cma user.cmo
Run Code Online (Sandbox Code Playgroud)
最后,让我们检查一下哪些文件产生了ocamlopt.
[/tmp/test] ocamlopt -c ./test.ml
[/tmp/test] ls
test.cmi test.cmx test.ml test.o
Run Code Online (Sandbox Code Playgroud)
ocamlopt 产生
test.o:本机对象文件test.cmi:编译的交互面文件test.cmx:也是本机对象文件,但它主要用于跨文件内联函数!