ocamlbuild icon indicating copy to clipboard operation
ocamlbuild copied to clipboard

unix.cmxa included twice when myocamlbuild.ml is present

Open dariusf opened this issue 9 years ago • 3 comments

I get this error when trying to build a project with -package unix:

$ ocamlbuild -clean
Finished, 0 targets (0 cached) in 00:00:00.

$ ocamlbuild -package unix main.byte
+ /usr/local/bin/ocamlopt.opt unix.cmxa -I /usr/local/lib/ocaml/ocamlbuild /usr/local/lib/ocaml/ocamlbuild/ocamlbuildlib.cmxa -I /usr/local/lib/ocaml /usr/local/lib/ocaml/unix.cmxa myocamlbuild.ml /usr/local/lib/ocaml/ocamlbuild/ocamlbuild.cmx -o myocamlbuild
File "myocamlbuild.ml", line 1:
Error: Files /usr/local/lib/ocaml/unix.cmxa
       and /usr/local/lib/ocaml/unix.cmxa both define a module named Unix
Command exited with code 2.
Compilation unsuccessful after building 1 target (0 cached) in 00:00:00.
make: *** [all] Error 10

For some reason, unix.cmxa seems to be included twice in the invocation above.

Minimal repro here. It happens as long as myocamlbuild.ml is present (even when it's empty), and also with -lib unix. Doesn't happen with other OCaml libraries (tried str, num). I'm on 4.02.3, OS X 10.11.

dariusf avatar Mar 18 '16 15:03 dariusf

I remember this problem happening when I introduced -plugin-tag (the plugin already links with Unix, so passing it -package unix would double-link) but I thought that I had eliminated the problem back then.

In fact, what is happening is that the -package option has two different implementations: one when you use -use-ocamlfind, one when you don't. It does not work when you do not use ocamlfind, and we should fix it, but I think it is in fact a mistake on your end: you should really be using -use-ocamlfind.

For the sake of completeness and future reference, here are two workarounds without using -use-ocamlfind:

The first is to build the plugin first, without passing any tag, using the -just-plugin option, then build the project. When building the project, ocamlbuild will notice that the plugin is up to date and not rebuild it.

ocamlbuild -just-plugin
ocamlbuild -package unix main.byte # or just "make"

The second work-around is to use the confusingly named -plugin-option option. This flag passes the option following it to the plugin once it is compiled (and not to the plugin compilation), so you can do the very ugly

ocamlbuild -plugin-option -package -plugin-option unix main.byte

(I know this second one is horrible, but I thought it was worth mentioning still.)

gasche avatar Mar 18 '16 21:03 gasche

PS: and many thanks for going to the trouble of building a repro case. This is very useful and saves me a surprising amount of time.

gasche avatar Mar 18 '16 21:03 gasche

No worries, and thanks for the advice. Incidentally, I forgot to add that this also doesn't work:

ocamlbuild -use-ocamlfind -lib unix main.byte

... while the -package version works as you said. Hope it's the same issue.

The reason for using -lib and not -use-ocamlfind is that it's a legacy project. I'll try to help upgrade it. :sweat_smile:

dariusf avatar Mar 19 '16 01:03 dariusf