Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocamldep misses dependencies #5000

Closed
vicuna opened this issue Mar 10, 2010 · 4 comments
Closed

ocamldep misses dependencies #5000

vicuna opened this issue Mar 10, 2010 · 4 comments
Milestone

Comments

@vicuna
Copy link

vicuna commented Mar 10, 2010

Original bug ID: 5000
Reporter: goswin
Status: closed (set by @xavierleroy on 2015-12-11T18:27:58Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 3.11.2
Target version: 4.02.0+dev
Category: tools (ocaml{lex,yacc,dep,debug,...})
Related to: #3190 #4991
Monitored by: @Chris00

Bug description

If one has some .mli files but not for all .ml files then oamldep misses dependencies between .cmi files:

--- a.ml ---
type t = int

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

--- b.ml ---
type t = A.t

--- c.ml ---
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
a.cmi:

Adding

--- 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
a.cmi:
b.cmi: a.cmi

In the first case the b.cmi file is generated from b.ml 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 "c.ml", line 1, characters 0-1:
Error: The files b.cmi and a.cmi make inconsistent assumptions
over interface A

@vicuna
Copy link
Author

vicuna commented Apr 18, 2010

Comment author: @xavierleroy

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.

@vicuna
Copy link
Author

vicuna commented Aug 5, 2013

Comment author: goswin

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

#4991

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: %.ml
ocamlc -c -o $@ $<

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

clean:
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 c.ml
File "c.ml", 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:
https://github.com/mrvn/ocam-problems/tree/ocamldep

@vicuna
Copy link
Author

vicuna commented Aug 28, 2013

Comment author: @damiendoligez

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.

@vicuna
Copy link
Author

vicuna commented Jun 5, 2014

Comment author: @xavierleroy

After re-reading this thread, I believe it's best to leave ocamldep's output as it is today and work on the .cmi atomicity issue described in #4991.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant