You are here
gcc cookbook for a distribution
Quick and condensed my thoughts about how a gcc should be compiled to plan forward for future upgrades and safety measure to not interfere with other gcc runtime libraries you might have.
A distribution does keep the door open for future changes without breaking old binaries if following the concept from below.
You can host more then one GCC Version at a time on one machine. You can have several incompatible GCC runtimes at a time. You do not interfere with other runtime versions _if_ you leave out runtime from /usr/lib. (edited 20121229:) Note: you may provide symlinks in /usr/lib to the most common version of gcc runtime on your system, as a fallback layer.
A distro may decide to compile core binaries with e.g. gcc 4.4 and other userland stuff with gcc 4.6 or even 4.7 at will.
Real-Use cases: In spec-files-extra (SFE) the gcc 4.6/4.7 compiler uses the concept described here and avoids that way using the OS provided gcc runtime files.
By default placing runtime libs or symlinks into /usr/lib is strongly discouraged (my opinion!)! Only under special consideration this should be done and never as default! Suggested is a tiny package just providing symlinks but not install that by default. Or if you run odd 3rd party software, then manage to isolate this issue and use e.g. LD_LIBRARY_PATH="/usr/gcc/4.6/lib" in the startscripts to find a matching runtime (still not perfect, no rants please, this is gcc runtime libs...)
A bit about the history how this information was researched is in the email archives of sfe-devel and on my other blog article. The GCC team is thinking for a while about what to do with the runtime libs, but I think they didn't get to a final solution up to now. Best for gcc in general is in my view to eliminate the need for the runtime libs at all. Best for a distro in my view is, to take the next step and deliver a gcc which move the runtime libs out of the way for safety.
Building a GCC which fits well:
what you need:
Why? Most times the distro does not carry the minimum needed versions of the above libraries if you want a leading edge GCC version.
How to solve? SFE does it that way: place SFEgmp, SFEmpfr, SFEgmpc into alternate prefix path /usr/gnu/ (instead /usr) and this can co-exist with whatever the core OS wants / has / can provide as the version of the names libraries.
As well relatively few other programs rely on the named libs in /usr/gnu, so resolving dependency with upgrades should be easy and not issue incompatibility problems in case of an upgrade.
Alternatives: Upgrade the distro to contain the needed fresh versions of the libs and place them into /usr/lib (Solaris has its own version, OpenIndia might want to stay in sync with Solaris).
What else you need:
* a gcc compiler, e.g. the one in version 3.4.x provided by old and new Solaris and OI distributions
Why? SunStudio might not work for bootstrapping (does it?)
How to solve? Install with pkg install developer/gcc-3
What you don't need:
You don't need a hardcoded non changeable runpath for searching libraries. The old gcc implementations in Solaris did cement the runpath so hard into the binaries, only a jack-hammer could remove that (that is elfedit).
Old gcc-3 and even the OpenSolaris gcc-4 versions had a very odd hardcoding of runtime libraries into *all* binaries you compiled by these compilers. It was probably thought as being so handy to not having to specify -R/usr/gnu/lib:/usr/sfw/lib -L/usr/gnu/lib:/usr/sfw/lib while compiling stuff.... well you get the idea that this can lead to all sorts of problems *if* you want/have to override that path (which is nearly impossible for a normal person/programmer). For instance this hardcoded runpath for searching libraries made it impossible that _you_ replace a library the system provides in the wrong version and search and find that library in a separate directory *before* the system provided lib is found in the -R and -L directories.
Summary: Don't import patches which hardcoded runpath. Beware, SFEgcc.spec uses a patch in that area but believe me, the hardcoding with -R and -L has been fully removed (beware: not all others may really know what they tell about that patch! They didn't look close enough unfortunatly were oversimplifying).
what you should do:
Use a soft hint in compiled binaries where to search first for runtime libraries. This is LINK_LIBGCC_SPEC.
A compiler needing a runtime library is generally a good and a bad idea at the same time.
Good: potential code sharing in memory and saving diskspace. Hey not worth much! Times of 16MB RAM and 100MB harddisks is really _gone_.
Bad: Dependencies. You often can't mix programs and runtime libs if they have been compiled with different options or provide different internal implementations of C++ binary code. Though there is a GCC promise to be upgrade compatible in the runtime libraries, but still in practise you run into nasty problems because it is not guaranteed to allow *mixing* the same name but differen version runtime libs in the same binary. For instance you might end up with e.g. two different C++ runtime libs loaded into the same program (vbox uses special settings and may run into this, probably other programs as well). This has been discussed elsewhere and found that a special setting for library binding is the real trigger for the vbox problem.
How to solve? Leave /usr/lib free from runtimes and place the libs into a private directory, one for each major.minor release of the compiler. A possible layout was introduced long ago, this is /usr/gcc/major.minor/lib - so for example /usr/gcc/4.6/lib/libgcc_s.so
Second, tell the compiler gcc to always place a "soft" hint (LINK_LIBGCC_SPEC) into each compiled binary where it has to search for the runtime libs, that is "where to search first", then search the remaining common direcories.
Such a binary searches first in /usr/gcc/4.6/lib/ and after that traverse all other commonly known directories like /usr/lib and /lib. That fallthrough makes a binary sill runnable on a system not having a copy of the runtime libs in /usr/gcc/4.6/lib/ and instead have a copy fresh engough in /usr/lib for instance.
Advantages: This soft hint (LINK_LIBGCC_SPEC) makes is possible to have *more then one* gcc compiler and runtime version on the system, with the binaries search first for theyr native runtime version the have been compiled for. But the biggest advantage is a different one:
You can have an incompatible runtime lib in /usr/lib and this one is *not* used then. Why have such a incompatible runtime lib? One example would be you want to run a 3rd party software and this one just need that incompatible runtime libs or you have a non-changeable distro which thinks you should be happy with a 4.4 version in /usr/lib but you want version 4.6 or 4.7 and can't change that.
SFE does it as described here, and avoids that way all the troubles if SFE uses e.g. gcc 4.7 and the distro something older or incompatible.
If you are packaging stuff.
Suggested layout is this:
Place all real files into: /usr/gcc/major.minor/ directory prefix
If you want, create a package with symlinks: /usr/gnu/bin/gcc -> /usr/gcc/major.minor/bin/gcc (and so on)
Create a not-by-default-install package pointing to the very latest _or_ other gcc version runtime you need: /usr/lib/libgcc_s.so ->/usr/gcc/major.minor/lib/libgcc_s.so
(duplicate libgcc_s.so to also have libstdc++.so.6, using mediated symlinks is a plus)
The SFE project runs for a long time theyr _own_ SFEgcc version implementing the above concept with isolated runtime libs and it runs seamlessly on Solaris 11 (TM) and OpenIndiana (TM). ( Beware I mean the unmodified SFEgcc.spec ... the OpenIndiana binary repo for sfe gcc does explicitly *not* implement the above idea LLINK_LIBGCC_SPEC for the runtime and does unfortunatly run into troubles with vbox - OI wanted /usr/lib/ for the runtime libs, a workaround is provided ...)
Please review the files below carefully and ask me if you have questions:
SFEgcc.spec (that compiles the SFE variant of the compiler)
Patch gcc-03-gnulib.diff (that adjusts common directories depending on %arch amd64, sparc, ... but *NO* hardcoded runpath!!!)
Patch gcc-05-LINK_LIBGCC_SPEC.diff (that one makes you happy as it instructs compiled binaries to search runtime libs in your place)
Patch gcc-10-spawn.diff (that fixes a spawn issue, will go away once integrated in the common source)
You can find those patches (read the comments in there as well!) on the pkgbuild.sourceforge.net -> SFE -> SVN repository spec-files-extra
Downsides: (Applies only if you set -R/lib:/usr/lib *AND* provide files or symlinks /usr/lib/libgcc_s.so and /usr/lib/libstdc++.so.6 !)
Only one is known. If you compile with "-R/lib:/usr/lib" then you need to inject you location to the runtime libs by modifying that to: "-R/usr/gcc/major.minor/lib:/lib:/usr/lib" . Pretty cool?
And please don't spread only half the truth about how to make future proof gcc implmentations.
This is my experiences and opinion and you are free to disagree with my experiences and view. Please discuss this concept in a friendly respecting manner. And be really *prepared* before speaking up please. We should do usefullthings and not waste our all time with explaining over and over again to people not having run a realisitg number of different settings in a well-though test bed.
Read here http://tom.blog.in-ulm.de/GNU_gcc_spec_file and the SFE Mailing lists for more history behind the story from above.