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 should have mode that does not make assumptions about build system #5396
Comments
Comment author: dastapov Patch against svn-trunk attached, see the output of "ocamldep -full" |
Comment author: @lefessan Thanks for the patch, dastapov. Have you been using this modified ocamldep in some context ? Which one ? In your patch, you put dependencies towards .o object files. Is there a reason for this ? In the example given in the bug report: bar.cmo: bar.ml foo.cmi bar.cmi foo.cmo there should be no dependencies towards .cmo and .o files (since they are not used by ocamlc/ocamlopt), i.e. the correct output should be: bar.cmo: bar.ml foo.cmi bar.cmi Or is there another reason why you chose to put them explicitely ? |
Comment author: dastapov I've been using this ocamldep at JaneStreet, but not extensively. It performed fine. Now let me address your questions: $ echo 'let baz = "baz"' > baz.ml $ echo 'let baz = "baz baz baz"' > baz.ml Therefore, lots of modern build systems (that check md5sum/sha1 of the targets) would behave incorrectly if the dependency is just on the .cmx 2)You are completely right about .cmo and .o, that is clearly my error. |
Comment author: @lefessan I understand the problem you show about the .cmx not changing (I think it would be worth another bug report, because many tools assume .cmx dependency is enough), but I still don't understand the need to put the .o in the .cmx dependencies. The .o is not used to build new pairs of .cmx/.o, but to build the final library or executable, so it should appear as a dependency of the .cmxa or the executable, together with the .cmx, no ? |
Comment author: @alainfrisch
Nitpicking: formally, the .cmxa does not depend on the .o files either. It is the associated .a file which depend on them. Of course, the .cmxa and the .a are built by the same rule, which should list the .o as dependencies.
Which tools? As far as I remember, default OCaml build rules shipped with omake are fine in this respect (and if this is not the case, this is a bug for omake, not ocaml). I'd be surprised if ocamlbuild was broken. |
Comment author: dastapov Now I remember why I put the .o dependency there. If you are using build system like "tup", you have an ability so say "give me all the .o that are transitive dependencies of this thing here". Then you use it to build .a. If your dependencies state that .cmx depends on .cmx and .o, then you can do it. If they don't - you would have much harder time figuring out the names of .o file (because not every source file would produce one - consider the case of lone .mli). |
Comment author: dastapov
Well, ocamlbuild is not broken specifically because it contains a workaround that adds dependecy on .o when there is dependecy on .cmx (you could check it out in the sources or try it out on my toy example that I've shown above). OMake is indeed broken because it does not have that workaround. But I don't feel like it is omake's fault. The way I see it, this turns building ocaml into an obscure art, if you will, where you either use the One Proper Tool (ocamlbuild) or you are on your own and you basically have to read through the sources of ocamlbuild, ocamldep and parts of compiler before you could use ocaml in existing project with different build system. And even then you basically have to build from scratch since there is no tool that would give you the full dependency tree of the module or binary or library or, for example, list sources from the single directory, topologically sorted. |
Comment author: @lefessan I committed your patch partially in the SVN as r12089 and r12092. It will not print the dependencies towards .o files. "-full" was replaced by "-all". I also fixed a small mistake where dependencies towards .cmo file would be printed instead of towards the .cmi file (i.e. using a proxy again). I also added an option "-sort", that prints the files in the order of their dependencies (like 'ocamlsort' would do). |
Comment author: dastapov Awesome (especially the "sort")! |
Comment author: thelema Another "Awesome!" on this improvement - I've been wishing for -sort for a long time, and it's great to now have it available as part of the standard distribution. Thank you, Fabrice! |
Original bug ID: 5396
Reporter: dastapov
Assigned to: @lefessan
Status: closed (set by @xavierleroy on 2013-08-31T10:46:19Z)
Resolution: fixed
Priority: normal
Severity: feature
Version: 3.12.1
Fixed in version: 3.13.0+dev
Category: ~DO NOT USE (was: OCaml general)
Monitored by: @gasche dastapov @lefessan mehdi @ygrek
Bug description
Right now, ocamldep (without "-modules") makes too many assumptions about build system that it would be used with. In particular"
It assumes that build system would not be able to distinguish between "ml only" and "ml+mli" cases on itself, so it uses the "cmo/cmx is a proxy for cmi" trick and outputs dependencies like "bar.cmi: foo.cmx", when in reality bar.cmi should depend on foo.cmi.
It assumes that build system only checks modification time, so it does not output dependecies on .o files at all. In reality it is possible to change a module in such a way that .o would change, but .cmx would not (its md5sum would not change), and build system that would check modification time AND md5sum of files would not do a rebuild.
It does not output dependencies on the source files
All this makes ocamldep broken and pretty much useless for general dependency processing (read: "if you are not using make, you are in a world of pain")
Let me make an example of how this could be improved. Consider the following toy project:
foo.ml:
let foo = 42
bar.ml:
let bar = Foo.foo + 1
bar.mli:
val bar : int
main.ml:
let () =
Print.printf "%d\n" Bar.bar
Here the output of "ocamldep -native *.ml *.mli":
bar.cmo: foo.cmx bar.cmi
bar.cmx: foo.cmx bar.cmi
foo.cmo:
foo.cmx:
main.cmo: bar.cmi
main.cmx: bar.cmx
bar.cmi:
With imaginary "-no-assumptions" mode the output should look like this:
foo.cmo: foo.ml
foo.cmx: foo.ml
foo.cmi: foo.ml
bar.cmi: bar.mli
bar.cmo: bar.ml foo.cmi bar.cmi foo.cmo
bar.cmx: bar.ml foo.cmi bar.cmi foo.cmx foo.o
main.cmi: main.ml
main.cmo: main.ml bar.cmi bar.cmo
main.cmx: main.ml bar.cmi bar.cmx bar.o
File attachments
The text was updated successfully, but these errors were encountered: