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

order of -ccopt and -cclib wrt other arguments #5441

Closed
vicuna opened this issue Dec 23, 2011 · 11 comments
Closed

order of -ccopt and -cclib wrt other arguments #5441

vicuna opened this issue Dec 23, 2011 · 11 comments

Comments

@vicuna
Copy link

vicuna commented Dec 23, 2011

Original bug ID: 5441
Reporter: @ygrek
Status: closed (set by @xavierleroy on 2017-09-24T15:32:00Z)
Resolution: not a bug
Priority: high
Severity: minor
Version: 3.12.1
Category: ~DO NOT USE (was: OCaml general)
Tags: patch
Related to: #7150
Monitored by: mehdi dario @glondu Bardou @xclerc @hcarty gerd @damiendoligez

Bug description

In light of (not so) recent changes to binutils and ld defaults it becomes critically important to be able to pass linker options in predictable order.
ocamlbuild should guarantee that options from flags are inserted into command-line in the same order as they are encountered in the source (this is the case now afair), and ocamlopt should preserve the order of -cclib and -ccopt arguments wrt other entries on the command-line (this is NOT the case now).

Moreover the order in which ocamlopt inserts -ccopt had changed in 3.12 which caused build failures :

$ ocamlc.opt -custom -verbose -ccopt -lev lwtc.c lwtml.ml

  • gcc -o 'a.out' '-L/usr/lib/ocaml' '/tmp/camlprim50bdbc.c' 'lwtc.o' '-lcamlrun' -I'/usr/lib/ocaml' -lm -ldl -lcurses -lpthread -lev

$ /opt/ocaml-3.12.1/bin/ocamlc.opt -custom -verbose -ccopt -lev lwtc.c lwtml.ml

  • gcc -o 'a.out' '-L/opt/ocaml-3.12.1/lib/ocaml' -lev '/tmp/camlprimdac052.c' 'lwtc.o' '-lcamlrun' -I'/opt/ocaml-3.12.1/lib/ocaml' -lm -ldl -lcurses -lpthread

Additional information

Some real-world examples :

the order of -l arguments - http://stackoverflow.com/questions/8301367/order-of-linked-libraries-in-ocamlbuild

the order of linker options wrt linked libraries - https://savannah.nongnu.org/patch/?7579

File attachments

@vicuna
Copy link
Author

vicuna commented Dec 31, 2011

Comment author: gerd

So far I know, shared libraries behave now similar to static libraries wrt. the order of linking. What makes it a bit difficult to solve is that the order for ld is the reverse of the order for the ocaml compilers, i.e. "ld -l1 -l2" means that lib1 can use lib2, whereas in ocaml we do it the other way round.

So what about this: When ocamlc processes arguments it translates each arg separately into a list of cc options, yielding a list of lists, and finally the outer list is reversed, and the "standard trailer" is appended (-lm -ldl -lcurses -lpthread). This would be quite predictable, and would also work with cc options pulled from cma/cmxa files.

@vicuna
Copy link
Author

vicuna commented Feb 15, 2012

Comment author: meyer

Attached patch prepared some while ago is the simplest and ad-hoc way to fix the problem. However it was discussed that might be worth to preserve the location of the -ccopt and -cclib options within the stream of arguments. That would be the most semantically correct behaviour of these options, however that needs some major rework in the code responsible for the argument processing.

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: @damiendoligez

It's too late for a major rework before 4.00.0. Unless somebody has a strong objection, I will soon postpone this PR to after 4.00.0.

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: @xavierleroy

I think there is a misunderstanding here. As explained in the reference manual, -llib libraries should be given via the -cclib flag, not the -ccopt flag. -ccopt is for C compiler/linker options like -L/some/path or -g.

Then, ocamlc and ocamlopt call the C compiler with -ccopt flags first on the command line and -cclib libraries last. This does the job both with static libraries and new-style dynamic libraries (where order matters) and with old-style dynamic libraries (where order doesn't matter).

The change in 3.12 mentioned by ygrek fixes a mistake whereas -ccopt flags were not passed first, causing problems with -L/some/path options. This change is maybe not perfect (we need to check if the order of -ccopt options matter, and if so whether this order is preserved) but it goes in the right direction.

So, in summary: stick to the -cclib/-ccopt convention and things should work pretty well.

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: @ygrek

The order of -ccopt wrt -cclib does matter too. Consider an example:

-ccopt -Wl,-Bstatic -cclib -lsmth -ccopt -Wl,-Bdynamic

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: gerd

ygrek: This is an extreme example, but you are right, this may happen. FYI, I'm using a cc wrapper for controlling the cc arguments in this level of detail. (Which turns to be easier anyway, because you can be safe to catch all -lfoo args so that they can be statically linked, even those that are pulled in from a cma/cmxa.)

Btw, this example is also a good one, because the wish to link certain libraries statically is frequent, and there is no easy answer (-static links everything, but is broken on most OS). Maybe a separate feature wish?

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: @xavierleroy

ygrek and gerd: I agree the current heuristic isn't perfect, and some of us Caml developers dream about better solutions. Still, the situation is nowhere as bad as when -ccopt is used for all -llib parameters. And in the 15 years that the -ccopt/-cclib heuristic has been in use, this is the first time that I hear about someone actually needing -Bstatic and -Bdynamic in real life. So, do tell us about actual needs, but don't overlook what already works.

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: gerd

Xavier, a couple of weeks ago I was actually asked to link in static C libraries for a commercial project. This is very useful when you want to distribute binaries, especially on platforms like OSX where you cannot just ask the users to install the dynamic libraries with a package manager. So the ability to do this is a real requirement for creating commercial binaries.

IMHO, this is only loosely connected with -cclib/-ccopt, hence I think this should be discussed in a different bug report. Having -cclib separately could even be a simplification here. There is currently the workaround to write a cc wrapper that you activate with -cc at link time, so a solution is in no way urgent.

@vicuna
Copy link
Author

vicuna commented Jul 12, 2012

Comment author: @ygrek

The described linking could be useful for mldonkey to provide static binaries that do still link dynamically to glibc. OTOH I've already achieved that the other way (cause mldonkey doesn't have external deps and all C libs are known and can be gathered in single variable in one Makefile). The cc wrapper solution also sounds plausible. That clarifies ccopt/cclib issue.
The only question left is whether there are no other scenarios when cclib order wrt other parameters is important.

@vicuna
Copy link
Author

vicuna commented Feb 24, 2015

Comment author: @damiendoligez

As far as I can tell, you can just use -cclib instead of -ccopt to pass the -Wl,-Bstatic and -Wl,-Bdynamic arguments so ocamlc will not reorder them.

Do we still need to do something, or can we close this report?

@vicuna
Copy link
Author

vicuna commented Dec 6, 2015

Comment author: @xavierleroy

I confirm that
-cclib -Wl,-Bstatic -cclib -lfoo -cclib -Wl,-Bdynamic
does work.

In the absence of further information, I close this PR.

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