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

automatic integration of packages used at compile time for link time #5567

Closed
vicuna opened this issue Mar 29, 2012 · 7 comments
Closed

automatic integration of packages used at compile time for link time #5567

vicuna opened this issue Mar 29, 2012 · 7 comments

Comments

@vicuna
Copy link

vicuna commented Mar 29, 2012

Original bug ID: 5567
Reporter: william
Assigned to: @gasche
Status: closed (set by @xavierleroy on 2015-12-11T18:04:26Z)
Resolution: not a bug
Priority: low
Severity: feature
Version: 3.12.1
Category: -for ocamlbuild use https://github.com/ocaml/ocamlbuild/issues

Bug description

Hello,

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,
William

File attachments

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: @protz

I think your <.ml> only kicks at compile-time. What about a <.cm*> line that asks for the package too?

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: william

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

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: @gasche

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

hello_xml$ cat _build/_log

Starting build.

Target: hello.ml.depends, tags: { extension:ml, file:hello.ml, ocaml, ocamldep, quiet }

ocamlfind ocamldep -modules hello.ml > hello.ml.depends

Target: Libs/my_xml.ml.depends, tags: { extension:ml, file:Libs/my_xml.ml, ocaml, ocamldep, package(xml-light), quiet }

ocamlfind ocamldep -package xml-light -modules Libs/my_xml.ml > Libs/my_xml.ml.depends

Target: Libs/my_xml.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:Libs/my_xml.cmo, file:Libs/my_xml.ml, implem, ocaml, package(xml-light), quiet }

ocamlfind ocamlc -c -package xml-light -I Libs -o Libs/my_xml.cmo Libs/my_xml.ml

Target: hello.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:hello.cmo, file:hello.ml, implem, ocaml, quiet }

ocamlfind ocamlc -c -I Libs -o hello.cmo hello.ml

Target: hello.d.cmo, tags: { byte, compile, debug, extension:cmo, extension:ml, file:hello.d.cmo, file:hello.ml, implem, ocaml, quiet }

ocamlfind ocamlc -c -g -I Libs -o hello.d.cmo hello.ml

Target: Libs/my_xml.d.cmo, tags: { byte, compile, debug, extension:cmo, extension:ml, file:Libs/my_xml.d.cmo, file:Libs/my_xml.ml, implem, ocaml, package(xml-light), quiet }

ocamlfind ocamlc -c -g -package xml-light -I Libs -o Libs/my_xml.d.cmo Libs/my_xml.ml

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
correct.

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.

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: @gasche

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.)

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: william

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)"...

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: @gasche

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.

@vicuna
Copy link
Author

vicuna commented Mar 29, 2012

Comment author: william

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.

Thanks,
William

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

2 participants