.cma,.cmo,.cmx文件之间的区别以及如何在编译中正确使用它们?

Qui*_*ieh 4 c++ ocaml compilation

我是OCaml的新手,我对.cma,.cmo.cmx的文件感到困惑.有时我必须在编译命令中包含.cma文件,但有时我必须包含.cmo文件.

为什么图书馆会有这样的差异?它是C++中与库相同的概念并包含路径吗?

示例:ocamlc -o executable str.cma extstring.cmo mycode.ml

谢谢

nom*_*ddo 6

你可能认为那.cmo是图书馆,但事实并非如此.

  • .cmo是字节码对象文件.就像.class在Java中一样.
  • .cma是字节码库.它是通过存档一些.cmo来制作的.cma
  • .cmxocamlopt(本机代码编译器)生成.主要输出文件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.mllib.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:也是本机对象文件,但它主要用于跨文件内联函数!