4

我正在尝试研究如何使用ocamlfind该 C 库编译 C 库和 OCaml 可执行文件。

我整理了一组相当愚蠢的示例文件。

% cat sillystubs.c
#include <stdio.h>

#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/custom.h>

value
caml_silly_silly( value unit )
{
    CAMLparam1( unit );
    printf( "%s\n", __FILE__ );
    CAMLreturn( Val_unit );
}

% cat silly.mli 
external silly : unit -> unit = "silly_silly"

% cat foo.ml
open Silly
open String

let _ =
    print_string "About to call into silly";
    silly ();
    print_string "Called into silly"

我相信以下是编译库的方法:

% ocamlfind ocamlc -c sillystubs.c
% ar rc libsillystubs.a sillystubs.o
% ocamlfind ocamlc -c silly.mli
% ocamlfind ocamlc -a -o silly.cma -ccopt -L${PWD} -cclib -lsillystubs

现在我似乎无法使用创建的库:

% ocamlfind ocamlc -custom -o foo foo.cmo silly.cma
/usr/bin/ld: cannot find -lsillystubs
collect2: ld returned 1 exit status
File "_none_", line 1, characters 0-1:
Error: Error while building custom runtime system

OCaml 工具对我来说有点神秘,所以任何指针都会受到欢迎。

4

3 回答 3

7

ocamlmklib 来救援。一步步:

$ ocamlc -verbose -c sillystubs.c
$ ocamlmklib -verbose sillystubs.o silly.mli -o silly
$ ocamlc -verbose silly.cma foo.ml -o foo
File "foo.ml", line 1, characters 0-1:
Error: Error while linking foo.cmo:
The external function `silly_silly' is not available

糟糕,您在 sillystubs.c 中定义了 caml_silly_silly,但在 silly.mli 中引用了 silly_silly(太傻了 :) 修复:

$ cat silly.mli 
external silly : unit -> unit = "caml_silly_silly"
$ ocamlmklib -verbose sillystubs.o silly.mli -o silly
$ ocamlc -custom -verbose silly.cma foo.ml -o foo
/usr/bin/ld: cannot find -lsilly
collect2: ld returned 1 exit status
File "foo.ml", line 1, characters 0-1:
Error: Error while building custom runtime system

还是没有运气?添加-I.以查找所需的库。

$ ocamlc -I . -verbose silly.cma foo.ml -o foo.byte
$ ocamlc -I . -verbose -custom silly.cma foo.ml -o foo.byte.custom
$ ocamlopt -I . -verbose silly.cmxa foo.ml -o foo.native

但是在“真实”设置中,您确实想使用 ocamlfind 安装 silly 库,然后通过 ocamlfind 运行编译将放置所需的命令行选项,一切都会自动运行。从头开始,整个过程如下所示:

$ ocamlc -verbose -c sillystubs.c
$ ocamlmklib -verbose sillystubs.o silly.mli -o silly
$ cat META
version="0"
description="quite silly"
archive(byte)="silly.cma"
archive(native)="silly.cmxa"
$ ocamlfind install silly META silly.cm* *.mli *.a *.so
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.a
Installed /usr/local/lib/ocaml/3.11.2/silly/libsilly.a
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.mli
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.cmxa
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.cmi
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.cma
Installed /usr/local/lib/ocaml/3.11.2/silly/META
Installed /usr/local/lib/ocaml/3.11.2/stublibs/dllsilly.so
Installed /usr/local/lib/ocaml/3.11.2/stublibs/dllsilly.so.owner
$ rm *.cm* *.a *.so *.o
$ ocamlfind ocamlopt -linkpkg -package silly foo.ml -o foo.native
$ ocamlfind ocamlc -custom -linkpkg -package silly foo.ml -o foo.byte.custom
$ ocamlfind ocamlc -linkpkg -package silly foo.ml -o foo.byte

本机和字节版本已准备就绪。顺便说ocamlc -custom一句弃用

我希望揭开谜底。

于 2010-05-11T08:29:56.820 回答
1

我是 OCaml 的落后版本,但它看起来像silly.cma动态sillystubs链接,所以你可能需要一个

-ccopt -L${PWD} 

在最后一行。

另外,我看不出你正在做的任何事情都需要额外的力量ocamlfind——你不妨ocamlc直接打电话。

于 2010-05-11T00:31:24.527 回答
1

OCaml 工具对我来说有点神秘,

我也这么认为。你为什么不使用omake?omake 使构建序列变得简单。 http://omake.metaprl.org/manual/omake-build.html#@fun272

于 2010-05-10T23:22:12.000 回答