Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005567OCaml-for ocamlbuild use 16:382015-12-11 19:04
Assigned Togasche 
StatusclosedResolutionno change required 
PlatformOSOS Version
Product Version3.12.1 
Target VersionFixed in Version 
Summary0005567: automatic integration of packages used at compile time for link time

ocamlbuild is very handy when I want to include subdirectories :
$ ocamlbuild -Is Libs target.byte

However, if packages (lablgtk2, xml-light, ...) are used in Libs and declared in _tags files, I still need to mention them in the compile command :

file Libs/_tags :
<*.ml> : package(xml-light)

compile command I must run :
$ ocamlbuild -Is Libs -use-ocamlfind -pkgs xml-light hello.byte

ideal compile command :
$ ocamlbuild -Is Libs

Attached is the example.
Would it be possible to automatically integrate at link time packages used for compile time?

Best Regards,
TagsNo tags attached.
Attached Filesgz file icon hello.tar.gz [^] (591 bytes) 2012-03-29 16:38

- Relationships

-  Notes
protz (manager)
2012-03-29 16:40

I think your <*.ml> only kicks at compile-time. What about a <*.cm*> line that asks for the package too?
william (reporter)
2012-03-29 16:59

I added your line :

file Libs/_tags :
<*.ml> : package(xml-light)
<*.cm*> : package(xml-light)

But still the same error :

ocamlbuild -use-ocamlfind -Is Libs hello.d.byte --
+ /opt/Ocaml/godi-3.12-squeeze/bin/ocamlfind ocamlc -linkpkg -g Libs/my_xml.d.cmo hello.d.cmo -o hello.d.byte
File "_none_", line 1, characters 0-1:
Error: Error while linking Libs/my_xml.d.cmo:
Reference to undefined global `Xml'
Command exited with code 2.
Compilation unsuccessful after building 7 targets (0 cached) in 00:00:00.
make: *** [all-that-dont-work] Erreur 10
gasche (developer)
2012-03-29 17:03

You can understand why your build does not work by looking at ocamlbuild _log output.

> hello_xml$ cat _build/_log
> ### Starting build.
> # Target:, tags: { extension:ml,, ocaml, ocamldep, quiet }
> ocamlfind ocamldep -modules >
> # Target: Libs/, tags: { extension:ml, file:Libs/, ocaml, ocamldep, package(xml-light), quiet }
> ocamlfind ocamldep -package xml-light -modules Libs/ > Libs/
> # Target: Libs/my_xml.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:Libs/my_xml.cmo, file:Libs/, implem, ocaml, package(xml-light), quiet }
> ocamlfind ocamlc -c -package xml-light -I Libs -o Libs/my_xml.cmo Libs/
> # Target: hello.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:hello.cmo,, implem, ocaml, quiet }
> ocamlfind ocamlc -c -I Libs -o hello.cmo
> # Target: hello.d.cmo, tags: { byte, compile, debug, extension:cmo, extension:ml, file:hello.d.cmo,, implem, ocaml, quiet }
> ocamlfind ocamlc -c -g -I Libs -o hello.d.cmo
> # Target: Libs/my_xml.d.cmo, tags: { byte, compile, debug, extension:cmo, extension:ml, file:Libs/my_xml.d.cmo, file:Libs/, implem, ocaml, package(xml-light), quiet }
> ocamlfind ocamlc -c -g -package xml-light -I Libs -o Libs/my_xml.d.cmo Libs/
> # Target: hello.d.byte, tags: { byte, debug, dont_link_with, extension:byte, file:hello.d.byte, link, ocaml, program, quiet }
> ocamlfind ocamlc -linkpkg -g Libs/my_xml.d.cmo hello.d.cmo -o hello.d.byte
> + ocamlfind ocamlc -linkpkg -g Libs/my_xml.d.cmo hello.d.cmo -o hello.d.byte
> File "_none_", line 1, characters 0-1:
> Error: Error while linking Libs/my_xml.d.cmo:
> Reference to undefined global `Xml'

What you learn by looking at this is that the flag package(xml-light)
is indeed passed to everything in Libs, so your local _tags file works
beautifully, *but* it is not passed to the final linking step of
hello.d.byte (producing an executable). So indeed, this final step
fails (because the linker needs the object code from xml-light), and
your fix make it work because you pass xml-light globally, including
to hello compilation.

But this is not a bug: ocamlbuild behaves as you specified (xml-light
is used only when compiling targets inside Libs/), which is itself not

If, instead of hello.d.byte, you asked to compile hello.cmo (which
does not need this final linking step), then your present
configuration would work.
gasche (developer)
2012-03-29 17:09

I'm marking this as resolved to take it off the bugtracker radar. Do not hesitate, though, to ask additional questions on the matter.

(There *might* be some change that could be done to make what you're doing work as you believe it should. Frankly, I don't think so, as I think the semantics is rather clear here. If someone comes up with a very good explanation of how it should behave to make this work, and it is as simple and easy to implement as the current one, why not, but one shouldn't count on it too much.)
william (reporter)
2012-03-29 17:19

The log is clear indeed.
So, this would be a bad solution to pass the "package(xml-light)" up for the target hello.d.byte ? Any executable that wants to use Libs/my_xml.d.cmo will need the tag "package(xml-light)"...
gasche (developer)
2012-03-29 17:41

If I understand it correctly, the current way ocamlbuild computes tags to apply for a particular compilation command is to look at all the rules that match the *target* of the compilation (here hello.d.byte). What you expected is that those tags also apply to compilations that have these Libs/foo.cmo files as *dependency* rather that target. Or, conversely, that Libs/foo.cmo could specify tags for files that use it, in addition to its own compilation.

That could make sense, but it seems it would incur some redesign of the ocamlbuild semantics (which is currently simply defined in terms of target). I mean, you don't want to add dubious heuristics that would fire in some cases but not in others: you want rules that are general and simple to describe and apply. I'm not sure what that could be here.

PS: there could be cases where you want to link an ocamlfind package for compilation, but it is not needed for linking: if the ocamlfind package only exports type and interfaces, but no executable code (admittedly this is not too common). You could also include ocamlfind packages that export syntax extensions, and again once the file has been preprocessed, the next targets that depend on it need not know about this package.

If you really feel that would be an important improvement to ocamlbuild, I could reflag this as a feature request. Quite frankly, it looks like it would be a lot of work to do it right (and we don't want to do it wrong and have to support it forever), and the current state is reasonable, so that would not be high-priority. On the other hand, if you are interested in experimenting with this / implementing something like this, this could be discussed -- help implementing other feature requests or fixing bugs is also appreciated, of course.
william (reporter)
2012-03-29 18:08

ok, what you say is that this feature is not compatible with the actual design of ocamlbuild, and it does no worth making big changes for this, which I fully understand.


- Issue History
Date Modified Username Field Change
2012-03-29 16:38 william New Issue
2012-03-29 16:38 william File Added: hello.tar.gz
2012-03-29 16:40 protz Note Added: 0007239
2012-03-29 16:40 protz Status new => feedback
2012-03-29 16:59 william Note Added: 0007240
2012-03-29 16:59 william Status feedback => new
2012-03-29 17:03 gasche Note Added: 0007241
2012-03-29 17:09 gasche Note Added: 0007242
2012-03-29 17:09 gasche Status new => resolved
2012-03-29 17:09 gasche Resolution open => no change required
2012-03-29 17:09 gasche Assigned To => gasche
2012-03-29 17:19 william Note Added: 0007243
2012-03-29 17:41 gasche Note Added: 0007244
2012-03-29 18:08 william Note Added: 0007248
2015-12-11 19:04 xleroy Status resolved => closed
2017-02-23 16:34 doligez Category OCamlbuild (the tool) => for ocamlbuild use [^]
2017-02-23 16:44 doligez Category for ocamlbuild use [^] => -for ocamlbuild use [^]

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker