Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005000OCamlOCaml tools (ocaml{lex,yacc,dep,browser,debug})public2010-03-10 17:092013-09-05 09:41
Assigned To 
PlatformOSOS Version
Product Version3.11.2 
Target Version4.01.1+devFixed in Version 
Summary0005000: ocamldep misses dependencies
DescriptionIf one has some .mli files but not for all .ml files then oamldep misses dependencies between .cmi files:

--- ---
type t = int

--- a.mli ---
type t = int

--- ---
type t = A.t

--- ---
type t = B.t

% ocamldep *.ml *.mli
a.cmo: a.cmi
a.cmx: a.cmi
b.cmo: a.cmi
b.cmx: a.cmx
c.cmo: b.cmo
c.cmx: b.cmx


--- b.mli ---
type t = A.t

% ocamldep *.ml *.mli
a.cmo: a.cmi
a.cmx: a.cmi
b.cmo: a.cmi b.cmi
b.cmx: a.cmx b.cmi
c.cmo: b.cmi
c.cmx: b.cmx
b.cmi: a.cmi

In the first case the b.cmi file is generated from and should have the same dependency (b.cmi: a.cmi) but ocamldep does not output it. As a result if a.mli is modified b.cmi is not rebuild and ocaml gives an error:

File "", line 1, characters 0-1:
Error: The files b.cmi and a.cmi make inconsistent assumptions
       over interface A
TagsNo tags attached.
Attached Files

- Relationships
related to 0004991acknowledged ocaml{c,opt} may truncate and recreate a .cmi, leading to (rare) failures of make -j 
related to 0003190acknowledged RFE: ocamldep flag to generate dependency on .cmi even when only .ml is present. 

-  Notes
xleroy (administrator)
2010-04-18 14:52

ocamldep's strategy is the following: if compilation unit B doesn't have a B.mli interface file, clients of B get a dependency on b.cmo instead of b.cmi. This way, dependency-wise, b.cmo acts as a proxy for both b.cmo and b.cmi. Look at the dependencies of c.cmo and c.cmx in your two examples to see this in action.

> As a result if a.mli is modified b.cmi is not rebuild and ocaml gives an error

I don't see that, because c.cmo depends on b.cmo which depends on a.cmi which depends on a.mli, so b.cmo is rebuilt and b.cmi along with it.

Feel free to provdie more details on the problem you actually encountered.
goswin (reporter)
2013-08-05 11:53

The problem arises when you try to fix the race condition for parallel builds and %.cmi files: [^]

I changed the rule for %.cmx files to never generate a %.cmi file like this:

--- Makefile ---
all: c.cmx

%.cmi: %.mli
        ocamlc -c -o $@ $<

%.cmo %.cmi:
        ocamlc -c -o $@ $<

        ocamlopt -c -o temp.$@ $<
        rm -f temp.$(patsubst %.cmx,%.cmi,$@)
        mv temp.$(patsubst %.cmx,%.o,$@) $(patsubst %.cmx,%.o,$@)
        mv temp.$@ $@

        rm -f *.cmi *.cmo *.cmx *.o *~

.PRECIOUS: %.cmx %.cmo %.cmi

include depends

depends: $(shell echo *.ml *.mli)
        ocamldep *.ml *.mli >depends

Editing a.mli then building c.cmx results in a.cmi, a.cmx, b.cmx and c.cmx being rebuild and fail with:

ocamlopt -c -o temp.c.cmx
File "", line 1:
Error: The files b.cmi and a.cmi make inconsistent assumptions
       over interface A
make: *** [c.cmx] Error 2

Since only b.cmo implicitly rebuilds b.cmi the above error occurs. Similary you can change the rules so %.cmo never rebuilds %.cmi and the above error would occur with c.cmo.

The problem is that using %.cmx/%.cmo as proxy for %.cmi only works if both of those actualy build %.cmi. That might not be the case as in the above example.

Full example source can be cloned from github: [^]
doligez (administrator)
2013-08-28 11:13

I'd say this is asking for trouble. If you're going to play games with the compiler like that, you should play the same game with ocamldep's output.

On a related note, I have half a mind to add a warning emitted by the compiler whenever it makes a .cmi from a .ml that doesn't have a corresponding .mli. This is bad practice and it generally gets you into a lot of trouble with various build systems.

- Issue History
Date Modified Username Field Change
2010-03-10 17:09 goswin New Issue
2010-04-18 14:52 xleroy Note Added: 0005326
2010-04-18 14:52 xleroy Status new => feedback
2010-07-22 11:53 ertai Status feedback => assigned
2010-07-22 11:53 ertai Assigned To => xclerc
2012-02-02 15:17 protz Category OCamlbuild => OCamlbuild (the tool)
2012-07-10 20:32 doligez Target Version => 4.01.0+dev
2012-07-31 13:36 doligez Target Version 4.01.0+dev => 4.00.1+dev
2012-09-17 17:52 doligez Assigned To xclerc =>
2012-09-17 17:52 doligez Status assigned => feedback
2012-09-17 17:52 doligez Category OCamlbuild (the tool) => OCaml tools (ocaml{lex,yacc,dep,browser})
2012-09-17 17:52 doligez Target Version 4.00.1+dev => 4.01.0+dev
2013-08-02 16:36 doligez Target Version 4.01.0+dev => 4.01.1+dev
2013-08-05 11:19 goswin Note Added: 0010106
2013-08-05 11:19 goswin Status feedback => new
2013-08-05 11:36 goswin Note Deleted: 0010106
2013-08-05 11:53 goswin Note Added: 0010112
2013-08-19 15:58 doligez Category OCaml tools (ocaml{lex,yacc,dep,browser}) => OCaml tools (ocaml{lex,yacc,dep,browser,debug})
2013-08-28 11:13 doligez Note Added: 0010246
2013-08-28 11:13 doligez Status new => acknowledged
2013-09-04 21:16 doligez Relationship added related to 0004991
2013-09-05 09:41 doligez Relationship added related to 0003190

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker