Ok, so we've gotten a good start on multilib in portage over the past few months. amd64's 2005.0 has been great in some areas and terribly lacking in other areas. We've started seeing more design flaws, and I'm thinking of doing some revisions to the toolchain/profile logic which will allow for much better crossdev toolchain integration as well as phasing out the ABI variable.
ABI was introduced because CHOST was insufficient to ALWAYS determine the ABI being used... The main example for this is mips64-u-l-g. We have no way to distinguish between n32 or n64 with this ABI. Most other examples are a bit more obscure. For instance, we MAY want to make a.out binaries for i386-*.
I'm starting to think that CHOST is the way to go, and we can try to figure out something else for mips64 (maybe mipsn32-*, mipsn64-*, mipso64-*, and mips-*).
On the toolchain side, we just need a way of always executing CHOST-application and making sure that that application really has the proper CTARGET. On crossdev toolchains, that's not a problem. On multilib systems, it's a tad tricky.
Currently, we use CFLAGS_$ABI to set things like '-m32', so when running x86_64_pc-linux-gnu-gcc with ABI="x86" and CFLAGS_x86="-m32", the compiler will generate 32bit code. This has the effect (bad design) of hiding some things from the log output. People are understandably confused when they see x86_64-*-gcc generating 32bit code with no visible '-m32'.
gcc-config-1.4.0 starts down the path of creating CHOST-gcc executables on multilib systems for ALL the targets, but it's still hackishly relying on ABI to do its dirty work. I intend to rewrite the wrapper to use the current ABI logic if ABI is set (for backwards compatibility), but if it isn't set, it should intelligently execute gcc based on how it was called:
1) If it's called as 'CHOST-gcc', run the gcc for that profile.
2) If it's called as 'gcc' and $CHOST is set, run gcc for that CHOST.
3) If it's called as 'gcc' and $CHOST is NOT set, check 'config-default' for the
default CHOST.
The multilib profiles (like i686-* when we have x86_64-* installed) will contain the "parent" CHOST as well as the necessary CFLAGS to _PREPEND_
Additionally, we should stop adding the gcc versioned directories into PATH and just searching through the PATH to find the gcc we want. This information is IN the config files and should be sufficient for our needs.
And finally, the lib handing in gcc is flawed. I sent this email to toolchain@gentoo.org about a month ago, but haven't yet acted on it:
Firstly, the problem I'm having...
Please see comment #34 in bug #75420. Basically, libtool is finding the 64bit lib<stdc++ or whatever>.la instead of the 32bit one even when we use -m32. The workaround I'm using now (personally, not in portage) is to just delete the gcc .las...
So as I see it we have a couple options...
Firstly, we can continue keeping the libs in gcc but break them out of the root multi-dir. We could then do something like opengl-update to symlink to the binary libs and copy over the .la with some sed to correct the libdir. This would have the added benefit of being able to avoid the ugly lafix that is run every gcc emerge currently as they would all correctly point to /usr/lib/libstdc++.la (or libobjc.la, etc).
Another option would be to have gcc just install the compiler itself and PDEPEND on ebuilds for the support libraries (libstdc++, libobjc, etc). I believe this was the direction headed with the gcc-library ETYPE... who was working on that?
The first option is the most doable, so it's where I'm aimed. I'm going to place the libs in <libdir>/libs/lib{,32,64} then do magic like opengl-update to symlink the .a and .sos into /usr/lib{,32,64} and copy the .la using sed to fix the libdir. This works very well for opengl-update, and it can finally kill off the stupid fix_libtool_archives BS as the .las should always point to /usr/lib/libblah.la.
binutils needs to get a wrapper script like gcc's which can handle adding things like '-b elf32-sparc' when sparc64's ld is executed as sparc-*-ld
--
Portage needs a bit of a facelift as well. The main issue I can see is multislot or atleast a hack at it. We need a way of having two packages installed on a system with different CHOSTs. My "simple" solution is to change the database directory to be /var/db/pkg/$CHOTS instead of /var/db/pkg. This causes problems, however, such as when someone changes CHOST between i386-* and i686-* for instance, but I think it is a start.
Additionally, we need a way of distinguishing between executable dependencies and library dependencies. For instance, if a program RDEPENDs on media-sound/mpg123, that means it needs mpg123 installed in order to function properly, but mpg123 is an executable, not a library. The package depending on it doesn't care if it's a 32bit application or a 64bit application. If a program DEPENDs on virtual/opengl, however, it needs to link against (or if RDEPEND, dlopen()) libGL.so. This means it needs a libGL.so which matches the abi being compiled for.
Thus, I believe RDEPEND/DEPEND should continue as library dependencies (since it's stricter), but we should introduce REDEPND and EDEPEND for executable dependencies.
--
The multilib.eclass should also be updated to handle the multilib-headers as a postinst so they don't all need to be installed at the same time. This will require having a database of files handled by this process so we can uninstall them with an unmerge. Right now, that's not extremely critical as only glibc and linux-headers make use of this, and those will always be on the system.
Post new comment