Alternatives are a concept we use for two purposes: providing choice, and making slotting more manageable. They allow for switching out the package which provides files such as libraries, binaries, and manpages by replacing the “normal location” of the file (ex. /usr/i686-pc-linux-gnu/bin/python
) with a symlink to the “actual file”, (/etc/env.d/alternatives/python2/_current/usr/i686-pc-linux-gnu/bin/python2
) which alternatives.exlib
stores in /etc/env.d/alternatives
.
Alternatives are also a part of eclectic
, the tool we use for some aspects of system configuration. There’s an alternatives
module which is used by alternatives.exlib
for allowing for programmatic creation of new modules which can then be invoked as normal modules in eclectic
.
Related to and often used with Providers and virtuals.
gcc
: slotted into 4.9
and 5.1
, alternatives allows for changing the provider of /usr/host/bin/gcc. So, if something doesn’t compile with gcc:5.1
, but does with gcc:4.9
, you can temporarily switch it with eclectic gcc set 4.9
.pkg-config
: pkg-config
‘s binary can be provided by either dev-util/pkg-config
or dev-util/pkgconf
, so you can switch between the different implementations with eclectic pkg-config set
, or access a specific package’s implementation with /usr/host/bin/pkg-config.${PN}
.Examples are edited for brevity, don’t expect it to look exactly like this.
somasis/cicero:~/ % eclectic
Usage: eclectic <global options> <module name> <module options>
Alternatives modules:
awk Alternatives for awk
gcc Alternatives for gcc
gzip Alternatives for gzip
hostname Alternatives for hostname
init Alternatives for init
kmod-tools Alternatives for kmod-tools
ld Alternatives for ld
locate Alternatives for locate
lua Alternatives for lua
perl Alternatives for perl
pkg-config Alternatives for pkg-config
python Alternatives for python
python2 Alternatives for python2
python3 Alternatives for python3
ruby Alternatives for ruby
vala Alternatives for vala
wxwidgets Alternatives for wxwidgets
Extra modules:
alternatives Maintain Alternatives symlinks
Each package which uses alternatives has a name of what it provides, and that is what is used as the name of the module eclectic
shows you. Usually, the package’s main binary, or the name of whichever package came first is used as the module name; gcc
, awk
, wxwidgets
, etc.
somasis/cicero:~/ % eclectic awk list
Available providers for awk:
[1] mawk *
[2] gawk
As shown here, you can list the packages you have installed that can provide for the module you’re listing. sys-apps/mawk
and sys-apps/gawk
both provide an implementation of the AWK programming language, and both can function fine as /usr/host/bin/awk
. The asterisk indicates the provider currently set.
somasis/cicero:~/ % eclectic awk set gawk
somasis/cicero:~/ % awk
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.
Examples:
gawk '{ sum += $1 }; END { print sum }' file
gawk -F: '{ print $1 }' /etc/passwd
somasis/cicero:~/ % eclectic awk set mawk
somasis/cicero:~/ % awk
Usage: mawk [Options] [Program] [file ...]
Program:
The -f option value is the name of a file containing program text.
If no -f option is given, a "--" ends option processing; the following
parameters are the program text.
Magic.
alternatives_for
alternatives_for <module name> <provider name> <[provider importance]> <source> <target> [<source> <target>...]
alternatives_for
is the main function, which is what actually sets the module name, provider, provider importance value, and files which are provided by the package in question. It must only be used in src_install
.
If the source and target are a bit confusing, here’s an example:
/usr/$(exhost --target)/bin/gzip
.pigz
./usr/$(exhost --target)/bin/gzip
, it will run pigz
, which is located in the same directory. So, essentially, /usr/$(exhost --target)/bin/gzip
becomes the same as if you executed /usr/$(exhost --target)/bin/pigz
.In addition, if the the source’s basename exists, and the target doesn’t, alternatives_for
will move the source to the target.
alternatives_pkg_postinst
alternatives_pkg_postinst
is what creates the alternatives module for the package being installed, if it doesn’t already exist. If it does exist, it updates the alternatives modules to have a valid provider. On package upgrades, it also updates the currently selected provider, to maintain the integrity of the file list. alternatives_pkg_postrm
does the opposite, and cleans up alternatives modules that no longer have any providers.
DESCRIPTION
is what is displayed in the output of eclectic list-modules
, shown next to the name of the alternative.
The correct way to set it is like so:
ALTERNATIVES_cc_DESCRIPTION="System-wide C compiler"
ALTERNATIVES_cxx_DESCRIPTION="System-wide C++ compiler"
alternatives_for cc gcc 1000 /usr/bin/gcc /usr/share/man/man1/gcc.1
alternatives_for c++ g++ 1000 /usr/bin/g++ /usr/share/man/man1/g++.1
Resulting in:
somasis/cicero:~/ % eclectic print-modules
[...]
Alternatives modules:
cc Alternatives for cc
c++ Alternatives for c++
[...]
The alternative name is sanitized to work around some variable name restrictions in bash
, by replacing [+=-]
with x
. Therefore, to set c++
‘s description you would set ALTERNATIVES_cxx_DESCRIPTION
to the description that is desired.
It is important that all providers share the same description. If they don’t, it will result in the description changing every time a different provider is installed.
You should keep in mind that alternatives can affect package building. This means that you shouldn’t assume that the user has a certain provider selected for any of the alternative modules; you should instead find a way to make the package’s build system work, regardless of what the provider that the user has selected is.
Exheres are never allowed to change alternatives. You may not run eclectic <module> set
in an exheres. It is only for users.
Example: some packages may assume that the user’s default /usr/host/bin/python
is python2
; alternatives give the ability to choose, so you should fix the package’s build system to specifically use python2
if it needs python2
, rather than assume python
is python2
.
Importance should be a signed integer, and can contain decimals, but may not start with or end with a dot. The provider which has the highest importance value is the most important. No two providers are allowed to have the same importance; you must make a decision on how important one provider should be over another.
Importance controls the order of the providers used for the list that eclectic <module> list
outputs, and what provider eclectic <module> update
selects if the preferred one is uninstalled. Importance doesn’t matter in any other case though, since we make a best effort to abide by what the user’s choice on what they want as their provider when possible. A list of full rules that eclectic <module> update
uses can be found here.
For light alternatives, importance controls what is selected, since light alternatives are designed to not be changed by the user.
# Copyright 2012 Elias Pipping <pipping@exherbo.org>
# Copyright 2015 Kylie McClain <somasis@exherbo.org>
# Distributed under the terms of the GNU General Public License v2
require alternatives
SUMMARY="Parallel implementation of gzip"
HOMEPAGE="http://www.zlib.net/${PN}"
DOWNLOADS="${HOMEPAGE}/${PNV}.tar.gz"
LICENCES="ZLIB"
SLOT="0"
PLATFORMS="~amd64"
MYOPTIONS=""
src_prepare() {
edo sed \
-e "s/^CC=.*/CC=$(exhost --tool-prefix)cc/" \
-e "s/^CFLAGS=.*//" \
-i Makefile
}
src_install() {
edo mkdir -p "${IMAGE}/usr/$(exhost --target)/bin"
edo mv ${PN} "${IMAGE}/usr/$(exhost --target)/bin"
dosym "/usr/$(exhost --target)/bin/${PN}" "/usr/$(exhost --target)/bin/unpigz"
doman ${PN}.1
dodoc README ${PN}.pdf
alternatives_for "gzip" "${PN}" "50" \
"/usr/$(exhost --target)/bin/gzip" "${PN}" \
"/usr/$(exhost --target)/bin/gunzip" "unpigz" \
"/usr/share/man/man1/gzip.1" "${PN}.1"
}
Light alternatives are alternatives that aren’t intended to be messed with by the user. Their name is prefixed with an underscore, and they don’t show up in eclectic
‘s list of modules, and are usually only changed by packages being installed, during the pkg_postinst
phase. These are often used for slotted libraries so that the upgrade process is easier. An example of it’s usage is dev-libs/icu
, which has its libraries slotted so that during the upgrade, you don’t hit linking errors and can safely upgrade and remove the previous version once all packages depending on it are linked correctly with cave fix-linkage
.
Copyright 2015 Kylie McClain