solvuu-build
solvuu-build copied to clipboard
improve dependency handling for cmi files
$ ls
a.ml b.ml b.mli
$ cat a.ml
type t = int
let x = 42
$ cat b.mli
val y : A.t
$ cat b.ml
let y = A.x
Now, run ocamldep:
$ ocamldep *
a.cmo :
a.cmx :
b.cmo : a.cmo b.cmi
b.cmx : a.cmx b.cmi
b.cmi : a.cmo
The dependency of b.cmi
is listed as a.cmo
, which is true if you're byte compiling. However, what if you only want to compile to native code, this introduces a wrong dependency, and surely ocamlopt would only expect a.cmx
to previously be compiled.
So could use the -native
option:
$ ocamldep -native *
a.cmo :
a.cmx :
b.cmo : a.cmx b.cmi
b.cmx : a.cmx b.cmi
b.cmi : a.cmx
Now we see that it does produce a.cmx
correctly. (Strangely it still prints out lines for .cmo
s even though the documentation for -native
says specifically "(no .cmo files)".)
The logically correct dependency for b.cmi
is "a.cmo or a.cmx".
If I follow your last remark, it means there is no correct way to handle the problem: you don't want the -native
option when you're byte-compiling only, right? Also, it seems to me that while the dependency is indeed wrong, it still permits a correct (only suboptimal) compilation.
it still permits a correct (only suboptimal) compilation
Right. I guess the .cmi
gets regenerated when it is not strictly necessary to do so. I haven't tested the affect on total compilation time, which isn't much concern to me since during development I almost always do byte compilation only.
If I follow your last remark, it means there is no correct way to handle the problem
I can think of a couple of solutions (which are probably not worth implementing):
- Provide a way to specify if byte and/or native compilation are being requested, e.g. by defining an environment variable. Inspect these variables and adjust the rules that get registered accordingly:
- If either byte or native mode are requested, but not both, then add a rule to build the .cmi.
- If both byte and native are requested, be sure to add this rule only once.
- Maybe a dynamic rule would work. The action that is registered could itself check if the
.cmi
already exists and is out of date, build the.cmi
only if necessary.