Multilib/Concepts

This page aims to describe the concepts used in gx86 multilib project and the rationale for them.

Multilib ABIs
Multilib ABIs are binary format 'flavours' that can be used on the same architecture. A particular ABI determines executable format, available CPU features, standard type sizes, etc.

For example, the amd64 architecture supports three multilib ABIs:


 * the native amd64 ABI that is used by the kernel and all non-multilib-capable packages,
 * the 32-bit x86 ABI that is compatible with applications and libraries written for plain x86 CPUs,
 * the x32 ABI that mostly aims to mix the advantages of amd64 ABI with 32-bit pointers.

The native ABI is the ABI that is defined as default by a particular profile. It is used for all non-multilib packages, and also enabled by default for multilib packages. The remaining ABIs are considered non-native ABIs.

Package flavours
The multilib-capable packages can be collected in two important groups:


 * library packages — packages that install both the libraries used by native ABI applications and multilib ABI applications,


 * application packages — packages that do not install public-use libraries. Since non-multilib packages don't depend on those, distinction between native ABI and non-native ABIs is not important in those packages.

for library packages
Library packages are implemented using either or both of the two following methods:


 * emul-linux-x86 packages that contain pre-built 32-bit libraries for amd64,


 * multilib-build.eclass that adds support for building regular ebuilds for multiple ABIs.

The latter method is preferred, and we are in process of converting packages to use it. However, until all packages are ready and stable, both methods are supported in parallel.

Due to unevitable file collisions, we support systems either:


 * using only emul-linux-x86 packages,


 * using multilib-build.eclass packages with optional fallback to emul-linux-x86 for libraries that were not converted yet.

for application packages
Application packages can be implemented in variety of ways. The most common variants are:


 * ebuilds using ABI flags directly with upstream binary packages for closed-source applications,


 * ebuilds using package-specific build system quirks to support multilib (e.g. toolchain),


 * ebuilds using multilib-build.eclass to support building the application for multiple ABIs.

Multilib ABI USE flags
Multilib-capable packages are using USE flags with abi_ prefix in order to control the enabled ABIs. The following table lists all the currently supported flags:

Availability and visibility of flags depends on the profile in use:


 * 1) in multilib profiles, the relevant flag group is made visible and supported ABIs are unmasked. The native ABI is enabled by default and forced on on multilib library packages. For example, on amd64 you can notice ABI_X86 flags on a number of packages.
 * 2) in non-multilib profiles of architectures that support multilib, all the flags are hidden but the flag corresponding to the native ABI is enabled and forced to be always on. This allows packages to conveniently use the flags independently of whether multilib is enabled or not. For example, on x86 the flag abi_x86_32 is always enabled on the multilib packages.
 * 3) in profiles of architectures that do not support multilib, all multilib flags are hidden and disabled.

in multilib library packages
Whenever a multilib package requires a multilib library built for the same ABI, USE flag dependencies shall be used to enforce the match. The multilib-build.eclass provides a convenience ${MULTILIB_USEDEP} variable that provides a proper USE dependency string.

It should be noted that we do not support depending on emul-linux-x86 packages from modern multilib ebuilds. Therefore, all the necessary dependencies need to support multilib via multilib-build.eclass before an ebuild is committed.

in application packages
Depending on the exact implementation of multilib in package, the following dependency forms may be used:


 * ${MULTILIB_USEDEP} or a compatible dependency that enforces USE match between the packages,


 * direct USE flag dependency if the package supports only single ABI (e.g. 32-bit x86 binary packages).

The application packages should preferably support both new-style multilib dependencies and emul-linux-x86 dependencies. This can be achieved using any-of dependency strings.

libraries
Multilib packages should install the same set of public libraries for all multilib ABIs. Furthermore, all the ABIs should use the same set of features (USE flags).

This is mostly in order to avoid confusion and unnecessary complexity. It guarantees that same version ranges and USE flag dependencies can be used both for non-native and native ABI dependencies.

header files
By default, we assume that all ABIs use the same header files. Therefore, all headers are installed into /usr/include. The eclasses additionally check whether each ABI installed the same header files, and prevent the installation from proceeding if it founds mis-matched headers.

If necessary, the headers may be wrapped for a particular ABI. If the wrapping is in effect, the original headers are placed in /usr/include/${CHOST} sub-tree and a wrapper file is installed in /usr/include. The wrapper includes proper file for ABI used by the compiler, or errors out if an unsupported ABI was requested.

executables
By default, we assume that the executables are equivalent in different ABIs and therefore the native executables are to be installed.

If possible, it is preferred to prevent building executables for other ABIs and build them for the native ABI only. However, it is acceptable to build (and therefore discard) the other ABI tools if the following conditions are met:


 * 1) disabling the tools would require patching or heavy hacking of the build system,
 * 2) the tools are small and therefore do not take long to build,
 * 3) the tools do not introduce additional multilib dependencies.

If there is a need to keep separate copies of the same executable for different ABIs (e.g. a -config tool), the extra tools are to be prefixed with ${CHOST}-' (e.g. ${CHOST}-libgcrypt-config''). In place of the original name, a symlink to the native variant is to be placed.

This utilizes the GNU build system behavior of preferring build tools with ${CHOST}- prefix if available, and therefore makes it possible for multilib reverse dependencies to find the correct tools automatically. However, some build systems may require patching or hacking to use proper tools.