2010-05-10 47 views
4

我想了解如何使用ocamlfind編譯C庫和使用該C庫的OCaml可執行文件。使用它編譯C庫和OCaml的exe,全部使用ocamlfind

我把一組相當愚蠢的示例文件放在一起。

% 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工具對我來說有點神祕,所以任何指針都會受到歡迎。

+1

爲了便於人們進行復制和粘貼,請更正將ocamlc拼寫爲ocmalc的錯誤。 – 2010-05-11 06:11:47

回答

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但參考silly_silly在silly.mli定義caml_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 -customdeprecated

我希望揭開神祕面紗。

1

我的背後是對OCaml的一個版本,但它看起來像silly.cma已經sillystubs動態,所以你可能在最後一行需要一個

-ccopt -L${PWD} 

另外,我沒有看到任何你要做的事情,需要額外的力量ocamlfind —你可以直接撥打ocamlc

+0

我試着添加'-ccopt -L $ {PWD}';錯誤消息保持不變。我也不認爲'silly.cma'的鏈接會動態鏈接到'sillystubs',但我不確定。 這是一個簡單的例子,我可以構造這個例子來說明使用OCaml工具進行鏈接的問題。在我正在進行的項目中,我需要'ocamlfind'的力量。 – Magnus 2010-05-11 05:37:51

+0

你確實是對的,我確實需要一個'-ccopt -L $ {PWD}',它不能在命令行的任何地方! – Magnus 2010-05-11 06:29:02