OCaml-将程序编译为库

OCaml-将程序编译为库,ocaml,Ocaml,我有一个OCaml程序(带有一个main方法——它生成一个可执行文件),我想把它用作一个库 我是这样编译我的程序的:ocamlc-I someDir-g-unsafe lotsOfCmoFiles-o outputFile,程序运行良好 现在,我将删除使其成为可执行文件的行(类似于let),并添加-a参数来编译命令:ocamlc-a-I someDir-g-unsafe lotsOfCmoFiles-o outputFile.cma 但不知何故,我无法加载带有ocamltop的生成的.cma文件

我有一个OCaml程序(带有一个main方法——它生成一个可执行文件),我想把它用作一个库

我是这样编译我的程序的:
ocamlc-I someDir-g-unsafe lotsOfCmoFiles-o outputFile
,程序运行良好

现在,我将删除使其成为可执行文件的行(类似于
let
),并添加
-a
参数来编译命令:
ocamlc-a-I someDir-g-unsafe lotsOfCmoFiles-o outputFile.cma

但不知何故,我无法加载带有
ocamltop
的生成的.cma文件,
ocamlbrowser
显示一个空列表。当我尝试从
ocamltop
加载时:

# #load "outputFile.cma";;
Error: Reference to undefined global `Xyz'
我100%确信xyz.cmo包含在
lotsOfCmoFiles

编译时我是否给出了一些错误的参数?或者,我应该如何在ocamltop中加载我的程序?(我将在另一个程序中使用此库,我将以ocamltop输出为例)

任何帮助都将不胜感激

编辑:由于@cago,我终于能够编译并加载它,现在我可以加载我的库了,当我不删除主
行时,它会在我加载
.cma
时自动运行

但我仍然无法打开任何模块。奇怪的是,这并没有引发异常

open Main
但当我从主模块调用函数时:

# someFun;;
Error: Reference to undefined global `Main'
ocamlbrowse
仍然显示一个空列表。为什么呢

EDIT2:我意识到,
openmain
不会失败,因为我在同一个文件夹中有一个主模块(即使我没有显式加载它)。如果我将.cma文件移到其他地方并加载,它会工作(即主功能自动运行),但现在我无法打开任何模块,即使
ocamlobjinfo
显示模块

编辑3:我帮不了你:

$ ocaml
        OCaml version 4.00.1

# #load "lib.cma";;
ok
# open Lib;;
Error: Unbound module Lib
# 
$ ocaml -I libFolder    
        OCaml version 4.00.1

# #load "toylib.cma";;
ok
# open Lib;;
# fun;;
Error: Reference to undefined global `Lib'

lotsOfCmoFiles
中的一些cmo需要知道模块Xyz。您需要处理cmo文件之间的依赖关系

例如:

toto.ml:

let x = "toto"
titi.ml:

let y = Toto.x ^ " titi"

ocamlc -c toto.ml
ocamlc -c titi.ml
ocamlc -a  titi.cmo toto.cmo -o lib.cma (* here is  the probleme *)

# #load "lib.cma"
Error: Reference to undefined global `Toto'
因为titi取决于toto,所以您需要更改cmos的顺序:

ocamlc -a toto.cmo titi.cmo -o lib.cma 

# #load "lib.cma"
# Titi.y;;
 - : string = "toto titi"
编辑:

例如,如果您的cma位于子目录中,当您调用
ocaml
时,您需要指定路径:

ocaml -I subdir/ (* subdir which contains lib.cma *)

# #load "lib.cma"
# Toto.x;;
- : string = "toto"

TL;医生:确保你在治疗过程中没有任何顶级副作用

我也遇到了同样的麻烦。我的项目构建得很好,大多数模块都可用,但有一个模块不断触发对未定义全局的引用。但很明显,该模块对系统是可见的:它与它的所有值一起显示在
utop
的自动完成列表中,我可以引用它并将其导入其他模块


问题原来是加载该模块时引发的未捕获异常。异常是由于尝试加载不存在的文件造成的。在复杂化过程中它不会导致问题,但当模块实际加载时,它正在崩溃,异常在我看到它之前就被吞没了。

cma文件中ocamlobjinfo的输出是什么?我无法重现您的问题,当我打开模块Toto和Titi时,我可以毫无问题地调用值x和y。这不是我的问题,我已经可以加载带有
#load…
的.cma文件,加载的文件开始运行(
let()=…
部分自动运行),因此它可以工作,但是我不能调用任何函数或打开任何模块cmi不在cma文件中,因此您需要告诉ocaml cmi文件在哪里,这就是为什么您需要在启动顶层时指定
-I
,这与您无关
#加载“subdir/lib.cma”
好的,您能告诉我您需要的所有CMI是否都在
LibFolder
中吗?您需要告诉ocaml到CMI的每一条路径?为什么不加载
lib.cma
,只加载
toylib.cma
?因为这是缺失的.cma的典型行为。例如,尝试
打开Unix
(nor error),然后调用
Unix.time()
,您将得到相同的错误,但是如果添加
#加载“Unix.cma”
,然后再次调用
Unix.time()
,您的错误将消失。OCaml搜索路径中是否有
lib.cmi
?要在顶层使用
Lib.fun
,包含模块库的
.cma
文件不够。。。