Project:Base/Alternatives

The packages in app-alternatives category symlink specific implementations of generic tools to their respective generic names. For example, installs  symlink. USE flags are used to select a specific implementation.

Migration
Migration to app-alternatives/* providers of common system packages like awk, bzip2, gzip will occur for stable users shortly.

It is important that users do not have FEATURES="collision-protect" enabled during this upgrade to allow the orphaned symlinks to transition to a new owner package (in fact, this setting is discouraged for users in general, and users should instead use FEATURES="protect-owned" which is the same but allows collisions in packages between orphaned files).

A similar recommendation was issued during the libxcrypt migration.

Note that for the reasons described on this page,  and   are both now obsolete.

All of these changes mean that e.g. the popular pigz & pbzip/lbzip2 symlink functionality returns, just with a new method.

Preferences
Users may change the provider of an app-alternatives package by setting the appropriate USE flags in, or roll with the defaults if they prefer.

Why?

 * 1) eselect interacts poorly when controlling software a package might depend on as there's no way for ebuilds to correctly express which implementation they need (think e.g. yacc), but also a broken system can result from edge-cases because of its reliance on orphaned files. See  for an example.
 * 2) Some packages which now use app-alternatives often previously relied on luck, like kbuild  where   caused confusing issues.
 * 3) Controlling a symlink via PATH precedence led to both unpredictable behavior and was often incompatible with Merge-usr.

Alternatives vs. eselect
Alternatives are preferred over eselect whenever writing outside is necessary. They guarantee that the installed symlinks are owned by the package manager, and managed using the same process as system upgrades, wiht all the reliability improvements that brings.

When is an alternative appropriate?
An alternative package is the appropriate solution if all candidates providing it are completely compatible and install the same binaries.

eselect is still a valid solution for some problems, but it's important to not rely on it in ebuilds at all. A user should never have to run in order to fix an  operation. is for users to customise the system in a way that is adjacent to ebuilds and their environment.

A virtual is more appropriate if the tool is not user-facing or the candidates do not install the same binaries (reverse dependencies might just detect and handle appropriately depending on which provider is installed). The key difference between an alternative is that virtuals simply ensure one of several packages are installed rather than managing a symlink in e.g..

split-usr support
Whenever the symlink is installed to, yet at least one of the implementations normally resides in , special care needs to be taken to handle both split /usr and merged /usr systems. For this purpose, split-usr flag can be used to alter the installed paths, e.g.:

Transition from unowned symlinks
Historically, symlinks such as were installed as part of the initial system and not owned by any package. For the transition period, it is a good idea to ensure that these symlinks remain even if the respective app-alternatives package is unmerged. This e.g. is accomplished in using the following snippet:

Moving symlinks from original implementations
Other files such as were originally installed by the default implementation. The original package needs to start installing the actual executable using a different name, and the symlink-to-be needs to be transitioned to the app-alternatives package.

Unfortunately, it is impossible to perform this transparently within the Gentoo packaging framework. The current solution is to add a pkg_postinst phase to the package installing the original implementation to temporarily restore the symlink being moved. This limits the time when the base executable is not provided to the period between merging the new version and running postinst.

For example, does: