| Anonymous | Login | Signup for a new account | 2013-05-25 06:35 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | ||||||
| 0005624 | OCaml | OCaml typing | public | 2012-05-25 15:12 | 2012-09-21 14:26 | ||||||
| Reporter | frisch | ||||||||||
| Assigned To | |||||||||||
| Priority | normal | Severity | minor | Reproducibility | have not tried | ||||||
| Status | feedback | Resolution | open | ||||||||
| Platform | OS | OS Version | |||||||||
| Product Version | |||||||||||
| Target Version | 4.01.0+dev | Fixed in Version | |||||||||
| Summary | 0005624: Some dependencies cannot be detected by ocamldep | ||||||||||
| Description | ocamldep, because it operates purely syntactically on the source files, misses some dependencies need to unroll type abbreviations. Example: c.ml refers to a type B.t, which is defined in b.mli by "type t = A.t"; if c.ml does not otherwise refer to module A, there is no possibility for ocamldep to detect a dependency from c.cmo to a.cmi. Nevertheless, the compiler will indeed need a.cmi when compiling c.cmo. Usually, this is not problematic, but it can be with non-trivial build rules which copy files around. Example: foo/a.mli: type t = int foo/b.mli: type t = A.t c.ml: let x : B.t = 2 and the following Makefile =================================================================== ## Implicit compilation rules .SUFFIXES: .ml .mli .cmi .cmo .mli.cmi: ocamlc -c -I $(shell dirname $<) $< .ml.cmo: ocamlc -c -I $(shell dirname $<) $< ## Installation rules a.cmi: foo/a.cmi cp $< $@ b.cmi: foo/b.cmi cp $< $@ ## Dependencies (as understood by ocamldep) c.cmo: b.cmi foo/b.cmi: foo/a.cmi =================================================================== Dependencies have been obtained with "ocamldep -modules", and then translated to file dependencies according to the corresponding -I flags used for compilation (this is how ocamldep, and -- I assume -- ocamlbuild work). The inferred dependencies are: foo/a.mli: foo/b.mli: A c.ml: B Then "make c.cmo" fails because of a missing dependency from c.cmo to a.cmi. Several approaches are possible to "fix" this: - Prevent the compiler from looking for a file a.cmi unless "ocamldep -modules" finds a dependency to module A (i.e. run the dependency analysis before type-checking). This is not very nice, since some type abbreviations are interpreted as abstract types, and this can break type-checking in ways which are not straightforward to understand (the fix is to add a dummy reference to A if the abbreviation is needed). This is the approach we follow at LexiFi. - Include dependent .cmi. In the example above, b.cmi would contain a copy of a.cmi. Of course, this can lead to very large .cmi files. - An optimization is to inline only the required external type abbreviations in the .cmi files (in the example above, b.cmi would be extended to include the fact that "A.t = int"). Note that this solution can also improve compilation time, because the compiler doesn't need to search and open .cmi files only to expand abbreviations. | ||||||||||
| Tags | No tags attached. | ||||||||||
| Attached Files | |||||||||||
Notes |
|
|
(0007464) gasche (developer) 2012-05-25 17:58 |
ocamldep is an heuristic tool based on some assumptions about how OCaml users typically organize their development. I'm not sure it is reasonable to try to evolve it into an omniscient tool capable of dealing with your sophisticated file manipulations. That's what "by hand" compilation scripts (or special-case tools designed hand-in-hand with your quite specific build system) are for: absolute flexibility. I'm not convinced in particular that doing deep modification to the semantics of .cmi files and/or the compilation process to work around limitations of ocamldep is such a good idea. I would rather welcome richer ways to inform the compiler of the mapping from Ocaml world compilation unit names to filesystem object files than the current rules allow; and/or potentially a type-checker design facilitating discovery of dependencies and interaction with library providers and build systems (implement what currently is ocamldep as a layer between parsing and type-checking, that resolves such mapping, is able to access existing .cmi files for semantically accurate naming information, and to make asynchronous queries to a build system for the missing .cmi). |
|
(0007465) frisch (developer) 2012-05-25 18:10 |
I don't think it is reasonable to expect large code base to be based on a manual analysis of dependencies across the project: this needs to be automated. At least omake (and maybe ocamlbuild, I don't know) allows using customized rules (compiling individual files with different flags and -I dirs, copying rules, code generation like ocamlyacc and even when the generator tool itself is part of the project, etc) and still supports automatic analysis of dependencies. It really works well, except for the specific issue I raise here. Only my first proposal changes the "semantics" of the system. The second and third ones should not introduce any bad behavior. That said, I agree with you. More advanced build tools that communicate directly with the compilers would open new doors. |
|
(0007612) doligez (manager) 2012-06-26 18:12 |
I'm setting this PR to "feedback" because a fix is not obvious and it still needs discussion. Everyone's input is welcome. |
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2012-05-25 15:12 | frisch | New Issue | |
| 2012-05-25 17:58 | gasche | Note Added: 0007464 | |
| 2012-05-25 18:10 | frisch | Note Added: 0007465 | |
| 2012-06-26 18:12 | doligez | Note Added: 0007612 | |
| 2012-06-26 18:12 | doligez | Status | new => feedback |
| 2012-07-09 14:54 | 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-21 14:26 | doligez | Target Version | 4.00.1+dev => 4.01.0+dev |
| Copyright © 2000 - 2011 MantisBT Group |