使用它编译C lib和OCaml exe,全部使用ocamlfind

发布于 2024-09-01 04:54:07 字数 1154 浏览 10 评论 0原文

我正在尝试弄清楚如何使用 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 工具对我来说有点神秘,所以任何指针都会受到欢迎。

I'm trying to work out how to use ocamlfind to compile a C library and an OCaml executable using that C library.

I put together a set of rather silly example files.

% 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"

I believe the following is the way to compile up the library:

% 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

Now I don't seem to be able to use the created library though:

% 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

The OCaml tools are somewhat mysterious to me, so any pointers would be most welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雨巷深深 2024-09-08 04:54:07

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 安装愚蠢的库,然后通过 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已弃用。

希望谜底揭开。

ocamlmklib to the rescue. Step by step:

$ 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

Oops, you defined caml_silly_silly in sillystubs.c but reference silly_silly in silly.mli (so much silly :) Repairing :

$ 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

Still no luck? Add -I. to find needed libraries.

$ 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

But in "real" setup you indeed want to install silly library with ocamlfind and then running compilation via ocamlfind will put needed command-line options in place and everything works automatically. Starting from scratch the whole procedure looks as follows :

$ 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

Native and byte versions are ready. BTW ocamlc -custom is deprecated.

Mystery unveiled I hope.

花期渐远 2024-09-08 04:54:07

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

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

The OCaml tools are somewhat mysterious
to me,

I think so, too.
why don't you use omake? omake makes the build sequences simple.
http://omake.metaprl.org/manual/omake-build.html#@fun272

丿*梦醉红颜 2024-09-08 04:54:07

我的 OCaml 版本落后,但看起来 silly.cmasillystubs 动态链接,因此您可能需要

-ccopt -L${PWD} 

最后 一个线。

另外,我没有看到您所做的任何事情需要 ocamlfind 的额外功能 - 您也可以直接调用 ocamlc

I'm a version behind on OCaml, but it looks like silly.cma has sillystubs linked dynamically, so you may need a

-ccopt -L${PWD} 

on that last line.

Also, I don't see anything you're doing that calls for the extra power of ocamlfind—you may as well call ocamlc directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文