Using ABI_X86 in Gentoo

I must disclose that I have little experience using multilib-build.eclass-style multilib in Gentoo.

ABI_X86 is a USE_EXPAND variable; setting ABI_X86="32 64" or USE="abi_x86_32 abi_x86_64" are equivalent. The default setting of ABI_X86, as of this writing (2013-09-09), for the default/linux/amd64/13.0 profile seems to be just ABI_X86=64.

This variable controls explicit multilib support in ebuilds which use multilib-build.eclass which is a more Gentoo-like way of doing multilib than the original method.

The original method that 32-bit libraries would be installed in Gentoo is via the binary snapshots named app-emulation/emul-linux-*. Each of these emulation binary packages contains a whole set of 32-bit libraries compiled by some Gentoo dev for you. Because each one installs a bundle of libraries which must be coordinated together, tracking dependencies of 32-bit-only ebuilds is harder. E.g., if you need a 32-bit media-libs/alsa-lib on a 32-bit system, you just install media-libs/alsa-lib, but on a 64-bit multilib system, you have to discover that app-emulation/emul-linux-soundlibs installs, among other libraries, the 32-bit version of media-libs/alsa-lib. Also, the Gentoo dev building one such binary package must do the work of figuring out the multilib and buildsystem quirks of each of the included libraries in the snapshot package, making maintenance harder. And, most importantly, providing binary packages as the only option official option for using multilib in Gentoo goes against the the spirit of Gentoo. You should have the right to compile everything yourself!

The multilib-build.eclass moves away from this behavior by helping individual ebuilds install both 32-bit and 64-bit versions. This should allow, for example, wine to only need to specify dependencies directly against the packages it needs instead of needing to pull in app-emulation/emul-linux-* packages. As ssuominen mentions in the forum thread you referenced:

=app-emulation/emul-linux-x86-xlibs-20130224-r1 which is empty package that doesn't have files because the files come now directly from the x11-libs/

(Note that -r1 has since been renamed to -r2) Eventually, app-emulation/emul-linux-x86-xlibs itself should be able to be dropped as 32-bit-only packages appropriately depend directly on the correct packages in x11-libs that, with multilib-build.eclass’s help, provide the needed 32-bit libs. This is where ABI_X86 comes into play. Any multilib-build.eclass-enabled package gains at least the new USE-flags abi_x86_32 and abi_x86_64 and probably abi_x86_x32. Using EAPI=2-style USE dependencies, packages can depend on 32-bit versions of other packages. If x11-libs/libX11 is emerged while ABI_X86="32 64", then it shall be installed with USE-flags abi_x86_32 and abi_x86_64 USE-flags set. If a particular graphical package needs a 32-bit version of libX11, it can specify x11-libs/libX11[abi_x86_32] in its dependencies. This way, if you try to emerge this graphical package and libX11 has not installed 32-bit libs, portage will refuse. multilib-build.eclass is also universal and is compatible with 32-bit systems: installing this same graphical package on a 32-bit system will always work because it is impossible to install libX11 without its abi_x86_32 useflag being set. This solves the problem of needing to depend on app-emulation/emul-linux-x86-xlibs when on a multilib system and directly on x11-libs/libX11 on a 32-bit-only system. We are paving the way to a having cleaner and sensible inter-package dependencies on multilib systems. =app-emulation/emul-linux-x86-xlibs-20130224-r2 exists as an intermediary which enables any old packages which used to depend on app-emulation/emul-linux-x86-xlibs which don’t know how to depend directly on, for example, x11-libs/libX11[abi_x86_32], to still work. =app-emulation/emul-linux-x86-xlibs-20130224-r2 makes sure sure that the same 32-bit libraries exist in /usr/lib32 as if =app-emulation/emul-linux-x86-xlibs-20130224 had been installed, but does it the Gentoo way by building these 32-bit libraries through its dependencies rather than providing a binary package. It behaves much like packages in the virtual category this way: it doesn’t install anything, just "forwards" dependencies for existing ebuilds.

We have seen how multilib-build.eclass paves the way for cleaner dependencies on multilib systems. Any package which has ABI_X86 options (same thing as saying it has abi_x86_* useflags) has installed a 32-bit version of itself if you have specified USE=abi_x86_32/ABI_X86=32. How does this work (at a high conceptual level)? You can read the ebuild itself. Basically, the idea is the same as python or ruby ebuilds which have the option to install themselves for multiple versions of python and ruby simultaneously. When an ebuild inherits multilib-build.eclass, it loops over ABI_X86 and does each step of the unpacking, compilation, and installation process for each entry in ABI_X86. Since portage goes through all of the ebuild phases like src_unpack(), src_compile(), and src_install() (and others) in order and only once, the multilib-build.eclass (currently, with the help of the multibuild.eclass) uses creates a directory for each different value of ABI_X86. It will unpack a copy of the sources to each of these directories. From there, each of these directories starts to diverge as each targets a particular ABI. The directory for ABI_X86=32 will have ./configure --libdir=/usr/lib32 run with FLAGS targeting 32-bit (e.g., CFLAGS=-m32 comes from the multilib profile’s CFLAGS_x86 envvar (note: portage profiles mostly refer to ABI_X86=32 as ABI=x86 and ABI_X86=64 as ABI=amd64)). During the src_install() phase, all of the different compiled ABIs are installed over eachother so that when any files have both 32-bit and 64-bit versions, the native ABI wins (e.g., an ebuild installing both libraries and an executable in PATH would install only a 64-bit executable into PATH but include both 32-bit and 64-bit libraries). To sum: when you set ABI_X86="32 64" in make.conf, any package which supports multilib-build.eclass will take roughly twice the amount of work (I’m not saying time ;-)) to compile as it is being built once for each ABI and results in 32-bit libraries in /usr/lib32.

I do not know if there is official documentation for ABI_X86 yet or its detailed status. Ebuilds using multilib-build.eclass seem to be mostly unstable for now. You can follow the instructions at the blog you linked to to start experiencing and testing ABI_X86 if you understand the distinction between app-emulation/emul-linux-x86-xlibs-20130224 and the new-style multilib app-emulation/emul-linux-x86-xlibs-20130224-r2. But, if you are OK with the old-style binary package, I think that app-emulation/emul-linux-x86-xlibs-20130224 should remain functional. You would only need to move to -r2 if you use any package which directly depends on another package’s abi_x86_32 useflag (for example, app-emulation/emul-linux-x86-xlibs-20130224 and x1-libs/libX11[abi_x86_32] cannot coexist because they probably both install the same library to /usr/lib32, namely /usr/lib32/libX11.so.6). A quick look at wine-1.7.0.ebuild suggests to me that it doesn’t need -r2.


There is also abi_x86_x32(it is not the same as abi_x86_32) use flag. This one is experimental and intended to build semi-64bit applications. The only difference is they have 4byte pointers. This limits memory usage to 4GiB and reduces overhead in most cases, while allows to use all the 64bit instructions.