如何让OCamlbuild编译并将C文件链接到OCaml项目?

时间:2013-10-28 20:26:34

标签: c ocaml ocamlbuild

我正在尝试从main.native构建一个OCaml二进制main.ml,它依赖于单个C文件custom.c来实现一个新原语。需要编译和链接此C文件。有没有办法只使用_tags文件?显而易见的问题是OCamlbuild在扫描main.ml时没有检测到依赖关系,因此需要明确告知依赖关系。

ocamlbuild main.native

OCamlbuild知道将* .c文件编译为* .o文件的规则,但我不知道如何添加依赖项。

2 个答案:

答案 0 :(得分:6)

有一个number of resources out there

首先,您需要标记main.native以创建对c-stub的依赖关系并相应地进行链接。 (顺便说一句,这假设c库被称为cstub,但它可以是你想要的任何东西。

_tags

<*.{byte,native}> : use_cstub
<**/*.cm{x,}a>    : use_cstub

然后,在myocamlbuild.ml中创建一个c-library与标记的东西的依赖关系,

dep ["link";"ocaml";"use_cstub"] ["libcstub.a"]

OCamlbuild has rules for creating library files(* .so和* .a),但您需要在.clib文件中添加要构建的文件列表,

cstub.clib

cobjfile1.o
cobjfile2.o
...

还需要将任何头文件从主目录复制到_build/目录。这是通过指定它们是对c中编译的依赖来完成的(在myocamlbuild.ml中,其中headers是一个命名项目中头文件的字符串列表。

dep ["c"; "compile"] headers;

最后,在我们将项目与c-stub库链接时添加标记(也在myocamlbuild.ml中),

flag ["link";"ocaml";"use_cstub"] (S[A"-dllib";A"-lcstub";A"-cclib";A"-lcstub"]);

答案 1 :(得分:2)

我已接受上述答案,但想记录解决方案。正如评论中所述,我使用linkdep()创建了一个新的参数化标记myocamlbuild.ml

open Ocamlbuild_plugin;;

dispatch 
    ( function 
    | After_rules -> pdep ["link"] "linkdep" (fun param -> [param])
    | _           -> ()
    )

_tags中使用新创建的标记来添加链接依赖项:

<*.ml>:     annot
<*.byte>:   linkdep(custom_unix_stubs.o),custom
<*.native>: linkdep(custom_unix_stubs.o)

这依赖于内置规则将C文件编译为目标文件。但是,这仍然会遗漏对头文件的依赖(我没有)。