OCaml如何构建静态项目

时间:2014-02-12 16:58:16

标签: compiler-construction linker ocaml static-libraries ocamlbuild

我要准备我的OCaml项目来编译/链接/运行系统,其中某些库不可用(yojson,curl,cryptokit但它可能不那么重要)我该怎么做?

到目前为止,我正在使用:

$ ocamlbuild -use-ocamlfind -pkgs curl,yojson,netstring,cryptokit,netclient,lablgtk2.auto-init,pgocaml tweetomat.native
如果缺少某些软件包,它显然无效。我的尝试是寻找库路径输入

$ ocamlfind printconf path

并手动将缺少的库文件夹复制到项目文件夹,这里列出了它们

$ tree -r libs

libs/
├── yojson
│   ├── yojson.o
│   ├── yojson.mli
│   ├── yojson.cmx
│   ├── yojson.cmo
│   ├── yojson.cmi
│   ├── yojson_biniou.o
│   ├── yojson_biniou.mli
│   ├── yojson_biniou.cmx
│   ├── yojson_biniou.cmo
│   ├── yojson_biniou.cmi
│   └── META
├── curl
│   ├── META
│   ├── libcurl-helper.a
│   ├── curl.mli
│   ├── curl.cmxa
│   ├── curl.cmi
│   ├── curl.cma
│   └── curl.a
└── cryptokit
    ├── META
    ├── libcryptokit_stubs.a
    ├── cryptokit.mli
    ├── cryptokit.cmxs
    ├── cryptokit.cmxa
    ├── cryptokit.cmx
    ├── cryptokit.cmi
    ├── cryptokit.cma
    └── cryptokit.a

好的,所以我尝试逐步编译项目中的每个文件,然后使用以下命令将所有内容编译为可执行文件:

$ ocamlc -c twitter_oauth.mli
$ ocamlfind ocamlc -package netstring,netclient -I ./libs/cryptokit/ \
    -c twitter_oauth.ml
$ ocamlc -c connection.mli
$ ocamlfind ocamlc -I ./libs/curl/ -c connection.ml
$ ocamlfind ocamlc -I ./libs/yojson/ -c parser.ml
$ ocamlfind ocamlc -package pgocaml -c sql.ml
$ ocamlfind ocamlc -package lablgtk2.auto-init,pgocaml -c gui.ml
$ ocamlfind ocamlc -package lablgtk2.auto-init,pgocaml,netstring,netclient \
    -I ./libs/cryptokit/ -I ./libs/curl/ -I ./libs/yojson/ -o tweetomat \
    yojson.cmo curl.cma cryptokit.cma \
    twitter_oauth.cmo connection.cmo parser.cmo sql.cmo gui.cmo

但我得到了:

File "_none_", line 1:
Error: Error while linking ./libs/yojson/yojson.cmo:
Reference to undefined global `Bi_outbuf'

我google了一下,看起来yojson不是静态构建的,需要'biniou'库来满足依赖性(我不确定静态构建但看起来像那样)。事实上,在将最后一个命令更改为(更改以星号标记)之后:

$ ocamlfind ocamlc -package lablgtk2.auto-init,**biniou**,pgocaml,netstring,netclient \
    -I ./libs/cryptokit/ -I ./libs/curl/ -I ./libs/yojson/ -o tweetomat \
    **biniou.cma** yojson.cmo curl.cma cryptokit.cma \
    twitter_oauth.cmo connection.cmo parser.cmo sql.cmo gui.cmo

以前的错误没有发生,但我有新的错误:

File "_none_", line 1:
Error: Error while linking ./libs/yojson/yojson.cmo:
Reference to undefined global `Easy_format'

天哪,我不会包括yojson / curl / cryptokit所依赖的每个库> :(。 你能帮帮我们吗?此外,使用ocamlbuild还有一些更简单的方法吗?

1 个答案:

答案 0 :(得分:2)

不要手动指定依赖项的包含路径 - 让ocamlfind处理它。所以问题仍然是如何通过ocamlfind提供这些库。

或者:

  • 使用opam下载并安装缺少的依赖项
  • 如果opam依赖项不是一个选项 - 将其他库作为tarball与项目一起分发,并使构建脚本解压缩并在需要时构建它们(每个库的构建步骤可能不同) - 以及像往常一样安装(通过ocamlfind)。

    可能存在ocamlfindroot可写入系统目录的问题。这可以通过设置环境变量来处理,告诉ocamlfind安装到另一个目录并从中查找。

    这是手动捆绑,直到我们从opam一天自动进行捆绑。