Reputation: 5540
I want to optimise the compilation time of my makefile
. One problem that waists my time is, after modifying one single file, make
returns for instance,
File "frontend/parser_e.ml", line 1:
Error: The files expression/rc.cmi and frontend/gen/lexer_ref.cmi
make inconsistent assumptions over interface Utility
make: *** [frontend/parser_e.cmx] Error 2
rm frontend/parser_name.ml
Note that the files in trouble may change, but it happens quite often. What I have to do is make clean
and then make
, as a consequence it is not an incremental build and takes time.
So does anyone know what I should check in my makefile
to reduce the chance of having this kind of error?
Edit 1:
Actually, all my ml-related files are in depth 1
, except frontend/gen/*
, which are in depth 2. Following the answer of @camlspotter, I modified a little bit the ocamldep
part of my makefile
. Now it looks like follows:
DIRS= -I frontend -I frontend/gen -I lib ...
depend: $(AUTOGEN)
# ocamldep -native $(DIRS) */*.ml */*.mli > depend # this is what was written before, I don't hink it is correct
ocamldep -native $(DIRS) *.ml *.mli > depend
As a consequence, make
following another make
gives immediately an inconsistence error.
One remark is I don't have AUTOGEN
, is it normal?
Another remark is that make depend
generates a depend
that has 0 character, is it normal?
Edit 2:
I modified depend:
by following Makefile
of OCaml source code:
beforedepend:: */*.ml
depend: beforedepend
(for d in \
frontend frontend/gen lib ... ; \
do ocamldep $(DIRS) $$d/*.mli $$d/*.ml; \
done) > depend
I have actually around 20 folders, each has 1-5 ml files. This time, make
rangs over for d in ...
, and does not want to stop. But if I remove 3-4 folders, it succeeds to create a depend
after several seconds.
Upvotes: 1
Views: 1596
Reputation: 9040
Your Makefile does not cover all the necessary dependencies between modules.
The meaning of
File "frontend/parser_e.ml", line 1:
Error: The files expression/rc.cmi and frontend/gen/lexer_ref.cmi
make inconsistent assumptions over interface Utility
is:
frontend/parser_e.ml
depends on expression/rc.ml
and frontend/gen/lexer_ref.ml
expression/rc.ml
and frontend/gen/lexer_ref.ml
use module named Utility
expression/rc.ml
and frontend/gen/lexer_ref.ml
must agree with the type (interface) of Utility
, but did not.I think of two possibilities to cause this state:
utility.ml
, for example dir_a/utility.ml
and dir_b/utility.ml
. OCaml does not allow linking modules with the same name. You can workaround this using packed modules (see -pack
compiler option). Your case is not this.utility.ml
but the dependencies may not be perfectly known to your Makefile. This is your case.A possible scenario of the second case is:
utility.ml
or utility.mli
and its interface (.cmi
file) has been changed.expression/rc.ml
and frontend/gen/lexer_ref.ml
is recompiled against this new interface of Utility
, but the other IS NOT, since the dependency is not known.frontend/parser_e.ml
.For fix, you have to run ocamldep
to capture all the necessary module dependencies and inform it to make
. Note that:
-I
option several times..ml
and .mli
files are really generated before ocamldep
runs. Since you seem to have .mly
and .mll
files and you have the issue around them, I suspect you miss something around here.A good example of the dependency analysis of OCaml modules is found at OCaml compiler source code itself. It is good to check around its lines with beforedepend
, depend
and include .depend
.
General hints:
include .depend
to your Makefile and capture all the module dependencies into this .depend
file, using ocamldep
.ml
and .mli
files of your project must be scanned by ocamldep
. Do not forget to add -I
options properly or it misses some dependencies.ocamldep
, make sure auto-generated .ml
and .mli
files such as the output of .mly
and .mll
are generated. Or it misses some dependencies.Typical Makefile looks like:
beforedepend:: x.ml
x.ml: x.mly
ocamlyacc x.mly
beforedepend:: y.ml
y.ml: y.mll
ocamllex y.mll
depend: beforedepend
ocamldep -I <dir1> -I <dir2> <all the ml and mli paths> > .depend
include .depend
Upvotes: 2