When making a toplevel, module names are not allowed to conflict with internal compiler libs.
What are some strategies for fixing this sorts of module name collisions?
Ideally, is it possible to pass some argument to ocamlc
to instruct it to "mangle" the names of all the modules to use a custom prefix like MyProject_
? (from the perspective of the OCaml ABI, not literally changing source files)
Full example below:
Sqrt.ml
contains
let sqrt x = x ** 0.5
Sqrt.mli
contains
val sqrt : float -> float
mktop
contains
#!/bin/bash
ocamlc -c Sqrt.mli -o Sqrt.cmi
ocamlc -c Sqrt.ml -o Sqrt.cmo
ocamlmktop -o sqrt_toplevel Sqrt.cmo
And I can produce a toplevel containing the function I want.
% ./sqrt_toplevel
OCaml version 4.04.0
# Sqrt.sqrt 4.5;;
- : float = 2.12132034355964239
If I rename the Sqrt
module to Parse
by changing the file names, the name conflicts with an internal library and the toplevel fails to link.
mktop
is now
#!/bin/bash
ocamlc -c Parse.mli -o Parse.cmi
ocamlc -c Parse.ml -o Parse.cmo
ocamlmktop -o parse_toplevel Parse.cmo
with the other files simply renamed to Parse.ml
and Parse.mli
.
If I do this, I get a naming conflict with a compiler lib.
% ./mktop |& sed -e s:"$HOME":~:
File "Parse.cmo", line 1:
Warning 31: files Parse.cmo and ~/.opam/4.04.0/lib/ocaml/compiler-libs/ocamlcommon.cma(Parse) both define a module named Parse
File "_none_", line 1:
Error: Some fatal warnings were triggered (1 occurrences)
Exit 2
I don't see a documented way to avoid this problem other than by using names that don't conflict with internal modules.
Here are Unix commands to list all the forbidden names, which is at least something:
$ cd ~/.opam/4.04.0/lib/ocaml/compiler-libs
$ ocamlobjinfo ocamlbytecomp.cma ocamlcommon.cma ocamltoplevel.cma |
awk '/^Unit name:/ { print $3}' | sort
For me (using OCaml 4.03.0 right now) there are 96 forbidden names. I wrote a script to verify that all 96 are really forbidden.
As a side comment, the toplevel is in fact generated in spite of the reported error. And, in a quick test, it seems to work. The function Parse.sqrt
(for example) exists and computes the right answers. But possibly there are problems that I just didn't happen to encounter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With