Reputation: 1395
How can I compile a jocaml source file which needs the cryptokit package (successfully compiled with the companion ocaml) with the ocamlbuild tool?
When I execute the command ocamlbuild -pkg cryptokit -use-jocaml a.native
I get this error:
Warning: tag "package" does not expect a parameter, but is used with parameter "cryptokit"¬
+ jocamlopt -I /prefix/lib/ocaml -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/unix.cmxa /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native¬
File "_none_", line 1:¬
Error: Files /prefix/lib/ocaml/unix.cmxa¬
and /prefix/lib/ocaml/unix.cmxa¬
both define a module named Unix¬
Command exited with code 2.¬
Compilation unsuccessful after building 4 targets (3 cached) in 00:00:00.
Essentially, the ocaml Unix module clashes with himself.
This error only pops when I include Cryptokit (with -pkg cryptokit
) probably because Cryptokit requires Unix. a.ml
can in fact be empty and still reproduce the error.
I tried to add the -use-ocamlfind
flag but as it also uses ocamlfind to get the compiler, it selects the ocaml compiler instead of the jocaml one.
By executing sequentially the same commands as ocamlbuild (displayed by -verbose 1
), I got that when I execute the last one without /.../unix.cmxa
then there is no more clash, but the wrong Unix module is loaded: it's the one from ocaml and not from jocaml, so it it completely crashes when I use any jocaml feature in a.ml
:
jocamlopt -I /prefix/lib/ocaml -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native
However, when I also remove the -I /prefix/lib/ocaml
part, then it compiles successfully:
jocamlopt -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native
To summarize, I got it to work by executing manually a modification of the last command, but I would like to get ocamlbuild working.
I think this error has to do with the fact that Cryptokit requires the Unix module: as I compiled it with ocaml and not jocaml, at the linking stage it tries to link with the ocaml stdlib one (which needs to be included) and not the jocaml stdlib one (which is implicitly included as part of the stdlib).
Upvotes: 0
Views: 307
Reputation: 1395
Elaborating on the -use-ocamlfind
option as suggested by gasche, I got it to work with the addition of a small nasty hack: removing "unix"
from the requires
field of the META
file of the cryptokit
package. It works because jocaml links everything with threads
and unix
by default (a real solution would have been to disable this behavior, but it seems a lot harder). So the working compilation command is:
ocamlbuild -use-ocamlfind -use-jocaml -pkg cryptokit a.ml
I think it is possible to generalize this to any package that uses either unix
or threads
when compiling with jocaml. A subsidiary question is whether it is possible to do this dynamically with a _tags
or myocamlbuild.ml
file (note: comment if this remark needs to be moved).
Upvotes: 0
Reputation: 31469
I had no idea there were active users of the ocamlbuild+JOcaml combination! By curiosity, would you say a bit more about what you are using JOCaml+cryptokit for?
I don't know much about Cryptokit or JOCaml, but it looks like your main problem is not related to ocamlbuild. If I understand correctly, (1) Cryptokit needs Unix and (2) JOCaml needs to use its own variant of Unix. If this is correct, compiling Cryptokit against ocaml's Unix and expecting it to work when linked with a JOCaml program that itself requires JOCaml's Unix is bound to create a lot of trouble. If this work in your case, it must be because either the part of Cryptokit you use doesn't actually require Unix, or the JOCaml program you are testing with does not actually require JOCaml's Unix. In the long run, it would probably be best to compile Cryptokit with JOCaml directly (I don't know how comfortable you are with the OCaml ecosystem in general, but I would personally try to build an OPAM switch where ocaml{c,opt}
are aliases for jocaml{c,opt}
and build programs from that).
Regarding the ocamlbuild specific part, it's hard to give any accurate advice without a tarball to be able to reproduce your setup and experiment with it. But I would try one of the two following options:
-use-ocamlfind
and teach ocamlfind
to use jocaml
instead of ocaml
by using the OCAMLFIND_COMMANDS
environment variable (see man ocamlfind
)-use-ocamlfind
entirely and instead call ocamlfind
as a command-line tool to get the location of the cryptokit library (ocamlfind query cryptokit
). You would then not use -pkg cryptokit
but pass the path yourself (with -lflags
and -cflags
or by modifying your myocamlbuild.ml
configuration file).Upvotes: 1