我正在尝试研究如何使用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工具对我来说有点神秘,所以任何指针都是最受欢迎的。
答案 0 :(得分:7)
$ 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安装愚蠢的库,然后通过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
本机和字节版本已准备就绪。 BTW ocamlc -custom
是deprecated。
希望揭开神秘面纱。
答案 1 :(得分:1)
OCaml工具有点神秘 对我来说,
我也这么认为。 你为什么不用omake? omake使构建序列变得简单。 http://omake.metaprl.org/manual/omake-build.html#@fun272
答案 2 :(得分:1)
我是OCaml背后的版本,但看起来silly.cma
已将sillystubs
动态链接 ,因此您可能需要
-ccopt -L${PWD}
在最后一行。
另外,我没有看到你正在做的任何事情要求ocamlfind
的额外力量 - 你也可以直接致电ocamlc
。