1 |
A little message to get everyone up-to-date on what's been going on. |
2 |
|
3 |
A few weeks ago I upgraded gcc from 4.2.2 to 4.2.3 on my Solaris 10 |
4 |
machine, and I ended up with a completely broken system. The cause of |
5 |
this was that usr/lib/gcc/i386-pc-solaris2.10/4.2.2/libgcc_s.so.1 no |
6 |
longer existed, and (almost) every application in my Prefix happened to |
7 |
be linked against it. Obviously, libgcc_s.so.1 is just provided by |
8 |
4.2.3, but stored in another directory. |
9 |
|
10 |
Thinking about this, I also realised that each binpkg includes these |
11 |
same links, effectively requiring one to use the same compiler as the |
12 |
binpkg was built with. |
13 |
|
14 |
This is undesirable, so a solution was to be found. This is where the |
15 |
journey starts... |
16 |
|
17 |
gcc-config is the tool that switches the compilers our systems, and this |
18 |
tool is responsible for actually placing libgcc into /lib, because it is |
19 |
recognised that some systems always need this lib for almost any |
20 |
application. However, due to some nice screwup from the writer of this |
21 |
message this never functioned at all, so bug one found. |
22 |
But, does this solve everything? Not really, I think. There's more in |
23 |
gcc than just libgcc; think of libstdc++, libobjc, libgcj, libfortran, |
24 |
etc, etc. So, it seemed like a simple idea to just copy over those libs |
25 |
into /usr/lib (they don't belong in /lib, as the system should be able |
26 |
to do most without them) and be done with it. |
27 |
|
28 |
Ok, why do we need this actually, and mainstream not. Well, simply |
29 |
because they have ld.so.conf and it contains all the paths to the |
30 |
installed compiler(s!) lib directories. So, for instance this |
31 |
/usr/lib/gcc/i386-pc-solaris2.10/4.2.3. Obviously, in Prefix we can't |
32 |
do that as long as we're unprivileged, so we solved that problem by |
33 |
using rpath directions, which are stored during the compilation/linking |
34 |
process inside all objects, such that the runtime linker can find back |
35 |
those libraries. Joy is that enough, well, yes, to actually create the |
36 |
situation that I started this email with. While ld.so.conf is dynamic |
37 |
and can change at any moment, the rpath directions are static, embedded |
38 |
in the objects. They can be changed (using chrpath) but that is an |
39 |
operation that needs to be applied to each and every object. Because it |
40 |
is not dynamic, it will always point to the directory that was used |
41 |
during compilation. |
42 |
|
43 |
To solve this, I modified gcc-config as I pointed out before. Now the |
44 |
problem with that approach was that cleaning up the libs would get hard, |
45 |
as different gcc installations may have different libraries, so I |
46 |
quickly decided that we should dedicate a directory for these libs, so I |
47 |
would simply remove that directory and start with a clean sheet, once |
48 |
gcc-config runs. This location happens to be usr/<chost>/lib/gcc. The |
49 |
additional challenge is that when multiple gccs are installed, one might |
50 |
want to use the libstdc++ version belonging to gcc 3.4 for some apps, |
51 |
while most other apps are fine with gcc 4.2's libstdc++. This basically |
52 |
means that the versioned libs for those compilers should always be |
53 |
available, as they would be in the ld.so.conf case. For this reason |
54 |
gcc-config overlays all known compilers, making sure that the currently |
55 |
selected compiler installs the unversioned symlinks for the libraries, |
56 |
e.g. one defaults to using those libs. |
57 |
|
58 |
Now, with a static path, it is just trivial to have binutils-config, our |
59 |
ldwrapper that adds Prefix paths to the linker, add this static path to |
60 |
the search path and rpath as well, and all should be fine, right? |
61 |
|
62 |
Well, I have to test what Linux and Solaris do with this, but on Darwin |
63 |
this horribly failed. |
64 |
|
65 |
First GCC puts its libs itself somewhere. On Darwin all libs have |
66 |
install_names, absolute paths pointing to the library to use. Where GCC |
67 |
is said to install the libs, is also where the install_names point to. |
68 |
Now if all GCC's would install their libs into our static path, we would |
69 |
get collisions, so that's not what we do. In fact, we let GCC simply |
70 |
install its libs into the directory as at the start of this mail. While |
71 |
these can be easily copied to any place on an ELF system, on Darwin this |
72 |
results in applications linking against those libraries pointing to the |
73 |
original installed location. Luckily there is a utility to change this |
74 |
install_name, and so I did. Problem solved, I thought. Well, not |
75 |
really. GCC knows it needs its own lib on every object it creates, so |
76 |
passes on the path to its own lib to the linker to be sure it will find |
77 |
it. This unfortunately results in finding the original library and |
78 |
hence an object not pointing to the place where we carefully put our |
79 |
libs. |
80 |
|
81 |
Due to a Portage check, we can't mess with the install_names in the GCC |
82 |
installation, because when they don't match the installation is aborted. |
83 |
Also, if we mess, we should mess in such a way that GCC will inject the |
84 |
proper path (ideally none). The worst thing I've seen with GCC is that |
85 |
it even injects -L/usr/lib when doing g++ final linking. And then we're |
86 |
back on track with the multilib hell where the same thing happens. |
87 |
Should our ldwrapper intercept these flags? Linking is seriously messed |
88 |
up to say the least. |
89 |
|
90 |
By the way, I shot multilib in Prefix. Due to more variations of this |
91 |
search path problem, multilib will not work properly. Also I think it's |
92 |
quite useless in Prefix. If you want to do another bitwidth, then just |
93 |
bootstrap that one (such as with the Solaris 64-bits Prefixes). We |
94 |
don't need multilib for that. |
95 |
|
96 |
|
97 |
-- |
98 |
Fabian Groffen |
99 |
Gentoo on a different level |
100 |
-- |
101 |
gentoo-alt@l.g.o mailing list |