linkerocamlstatic-librariesocamlbuild

OCaml how to build statically project


I've to prepare my OCaml project to compile/link/run on system where some libraries are not availible (yojson, curl, cryptokit but it's probably not so important) how may I do it?

So far I was using:

$ ocamlbuild -use-ocamlfind -pkgs curl,yojson,netstring,cryptokit,netclient,lablgtk2.auto-init,pgocaml tweetomat.native

it obviously won't work if some packages are missing. My attempt was to look for libraries path typing

$ ocamlfind printconf path

and manually copy missing libraries' folders to project's folder, here is listining of them

$ 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

Ok so I tried to compile step-by-step every single file from project and then compile everything to executable using:

$ 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

but I'm getting:

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

I googled a little and it looks like yojson is not built statically and needs 'biniou' library to fullfill dependencies (I'm not sure about statically build but it looks like that). And in fact after changing last command to (changes are marked by asterisks):

$ 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

previous error does not occur but I've new one:

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

oh god I won't include every single library on which yojson/curl/cryptokit depends >:(. Can you help me guys? Moreover does there exist some simpler way to do that using ocamlbuild?


Solution

  • Don't specify include paths for dependencies manually - let ocamlfind handle it. So the question remains on how to make that libraries available via ocamlfind.

    Either: