EAPI usage and description

The Package Manager Specification is a standardization effort to ensure that the ebuild file format, the ebuild repository format (of which the Gentoo repository is Gentoo's main incarnation) as well as behaviour of the package managers interacting with these ebuilds is properly written down and agreed upon.

EAPI is a version defined in ebuilds and other package manager related files which informs the package manager about the file syntax and content. It is, in effect, the version of the Package Manager Specification that the file adheres to.

This section provides usage and descriptions of the different EAPIs.

Usage of EAPIs

You must set the EAPI variable by specifying it at the top of the ebuild:

# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=7

When writing new ebuilds developers can choose whatever EAPI they think is the best. Using the features of the latest EAPI is encouraged.

Upgrade path

Gentoo policy is to support upgrades for installations at least a year old with no/little intervention and up to two years old with minor intervention. To achieve this, developers must avoid using the latest EAPI in ebuilds within the @system set (see Implicit system dependency) or its dependencies.

The Base System project has rules governing their use of newer EAPIs, as does the Python project.

It is also convention that blockers within ebuilds are retained for at least 2 years after the last ebuild matching the block is removed from the tree to avoid file collisions for users upgrading older systems. pkgcheck has a warning for this called OutdatedBlocker (or even NonexistentBlocker for when the match is from pre-git times if using a non-grafted repository).

EAPIs 0 to 4

EAPIs 0 to 4 are obsolete and must no longer be used. Refer to the Package Manager Specification for details about them.

EAPI 5

EAPI 5 metadata

REQUIRED_USE supports new at-most-one-of operator
The new at-most-one-of operator consists of the string ??, and is satisfied if zero or one (but no more) of its child elements is matched.
SLOT supports optional "sub-slot" part
The SLOT variable may contain an optional sub-slot part that follows the regular slot and is delimited by a / character. The sub-slot must be a valid slot name. The sub-slot is used to represent cases in which an upgrade to a new version of a package with a different sub-slot may require dependent packages to be rebuilt. When the sub-slot part is omitted from the SLOT definition, the package is considered to have an implicit sub-slot which is equal to the regular slot.
Slot operators and sub-slots in dependencies

A slot dependency may contain an optional sub-slot part that follows the regular slot and is delimited by a / character. This can be useful for packages installing pre-built binaries that require a library with a specific soname version which corresponds to the sub-slot. For example:

RDEPEND="dev-libs/foo:0/3"

Package dependency specifications can use slot operators to clarify what should happen if the slot and/or sub-slot of a runtime dependency changes:

  • :* Indicates that any slot value is acceptable. In addition, for runtime dependencies, indicates that the package specifying the dependency will not break if the package matching the dependency is replaced by a different matching package with a different slot and/or sub-slot.
  • := Indicates that any slot value is acceptable. In addition, for runtime dependencies, indicates that the package specifying the dependency will break unless there is available a package matching the dependency and whose slot and sub-slot are equal to the slot and sub-slot of the best installed version that had matched this dependency at the time when the package specifying this dependency had been installed.
  • :slot= Indicates that only a specific slot value is acceptable, and otherwise behaves identically to the := operator.

The :slot dependency syntax continues to behave like in EAPI=4 or earlier, i.e. it indicates that only the specific slot value is acceptable, but the package will not break when the version matching the runtime dependency is replaced by a version with a different sub-slot.

For example:

RDEPEND="dev-libs/foo:2=
    >=dev-libs/bar-0.9:=
    media-gfx/baz:*
    x11-misc/wombat:0"

means that the package should be rebuilt when foo:2 or >=bar-0.9 are upgraded to versions with different subslots, but that changes in subslots of baz or wombat:0 should be ignored.

EAPI 5 profiles

Profile stable USE forcing and masking
In profile directories with an EAPI supporting stable masking, new USE configuration files are supported: use.stable.mask, use.stable.force, package.use.stable.mask and package.use.stable.force. These files behave similarly to previously supported USE configuration files, except that they only influence packages that are merged due to a stable keyword.

EAPI 5 helpers

econf adds --disable-silent-rules
This option will automatically be passed if --disable-silent-rules occurs in the output of configure --help.
new* commands can read from standard input
Standard input is read when the first parameter is - (a hyphen).
New option --host-root for {has,best}_version
This option --host-root will cause the query to apply to the host root instead of ROOT.
New doheader helper function
Installs the given header files into /usr/include/. If option -r is specified, descends recursively into any directories given.
New usex helper function
USAGE: usex <USE flag> [true output] [false output] [true suffix] [false suffix]
DESCRIPTION:
If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
 otherwise echo [false output][false suffix] (defaults to "no").

EAPI 5 phases

src_test supports parallel tests
Unlike older EAPIs, the default src_test implementation will not pass the -j1 option to emake.

EAPI 5 variables

EBUILD_PHASE_FUNC
During execution of an ebuild phase function (such as pkg_setup or src_unpack), the EBUILD_PHASE_FUNC variable will contain the name of the phase function that is currently executing.

EAPI 6

EAPI 6 Bash version

Bash version
Ebuilds can use features of Bash version 4.2 (was 3.2 before).

EAPI 6 ebuild environment

Locale settings
Behaviour of case modification and collation order (LC_CTYPE and LC_COLLATE) are guaranteed to be the same as in the C locale, as far as characters in the ASCII range are concerned.
failglob enabled
For EAPI=6, the failglob option of bash is set in the global scope of ebuilds. If set, failed pattern matches during filename expansion result in an error when the ebuild is being sourced.

EAPI 6 phases

Update default implementation of src_prepare

This phase is no longer a no-op, it supports applying patches via the PATCHES variable and applying user patches via eapply_user. The default src_prepare looks like this:

src_prepare() {
    if [[ $(declare -p PATCHES 2>/dev/null) == "declare -a"* ]]; then
        [[ -n ${PATCHES[@]} ]] && eapply "${PATCHES[@]}"
    else
        [[ -n ${PATCHES} ]] && eapply ${PATCHES}
    fi
    eapply_user
}
New src_install Phase Function

This phase uses the new einstalldocs function for installation of documentation. The default src_install looks like this:

src_install() {
    if [[ -f Makefile ]] || [[ -f GNUmakefile ]] || [[ -f makefile ]]; then
        emake DESTDIR="${D}" install
    fi
    einstalldocs
}

EAPI 6 helpers

einstall banned
The einstall helper has been banned with EAPI=6.
dohtml deprecated
The dohtml helper has been deprecated with EAPI=6.
nonfatal die
When die or assert are called under the nonfatal command and with the -n option, they will not abort the build process but return with an error.
eapply support
The eapply command is a simplified substitute for epatch (from eutils.eclass), implemented in the package manager. The patches from its file or directory arguments are applied using patch -p1, but it accepts patch(1) options from GNU patch to override default behavior.
eapply_user support

The eapply_user command permits the package manager to apply user-provided patches. It must be called from every src_prepare function.

econf adds --docdir and --htmldir
Options --docdir and --htmldir are passed to configure, in addition to the existing options.
in_iuse support
The in_iuse function returns true if the given parameter is available in the ebuilds USE.
unpack changes
  • unpack supports relative paths without leading ./ (unpack foo/bar.tar.gz is valid as relative path).
  • unpack supports .txz (xz compressed tarball).
  • unpack matches filename extensions case-insensitively.
einstalldocs support
The einstalldocs function will install the files specified by the DOCS variable (or a default set of files if DOCS is unset) and by the HTML_DOCS variable.
get_libdir support
The get_libdir command outputs the lib* directory basename suitable for the current ABI.

EAPI 7

EAPI 7 terminology

Documents may use the following terms to better describe dependency and installation targets.

CHOST
The system that will be running the installed package.
CBUILD
The system used to build packages. When not cross-compiling, CBUILD == CHOST.
CTARGET
Used in certain cross-compilations, often empty value.

EAPI 7 variables

PORTDIR and ECLASSDIR are removed
PORTDIR and ECLASSDIR are no longer defined and cannot be used in ebuilds to access these directories.
DESTTREE and INSDESTTREE are removed
The unintended exported variables PORTDIR and ECLASSDIR cannot be used in ebuilds to manipulate installation paths. Use into or insinto, respectively, instead.
D, ED, ROOT, and EROOT modified
These variables no longer contain a trailing slash with EAPI=7.
BDEPEND added
Previously, all build-time tools and libraries went into the DEPEND. Now, built-time dependencies are split into DEPEND and BDEPEND. The difference is simply that BDEPEND are dependencies to be executed on the CBUILD. DEPEND remains for other dependencies, such as libraries, for the CHOST. This improves the cross-compilation support.
BROOT added
BROOT is the absolute path to the root directory, including any prefix, containing build dependencies satisfied by BDEPEND, typically executable build tools.
SYSROOT and ESYSROOT added
SYSROOT is the location of where dependencies in DEPEND are installed. ESYSROOT is SYSROOT with EPREFIX appended.
ENV_UNSET added
A whitespace delimited list of variables to be removed from the build environment.

EAPI 7 metadata

Empty groupings are banned
Groupings which are empty, such as DEPEND="|| ( ${empty_var} )" will now generate an error. Furthermore, conditions within groupings are more strictly enforced. For example, REQUIRED_USE="|| ( foo? ( bar ) baz? ( zoinks )" would previously work with USE="-foo -baz" now requires either USE="foo bar" or USE="baz zoinks".

EAPI 7 profiles

package.provided banned
Profiles may no longer contain a package.provided file with EAPI=7.

EAPI 7 helpers

dohtml banned
The dohtml helper has been banned with EAPI=7.
dolib and libopts banned
The dolib helper and the associated libopts have been banned with EAPI=7.
has_version and best_version changes

has_version and best_version now support an optional switch to determine which type of dependencies to check.

  • -r (the default) will check runtime dependencies (RDEPEND)
  • -d will check CHOST build-time dependencies (DEPEND)
  • -b will check CBUILD build-time dependencies (BDEPEND)
Version manipulation and comparison commands

EAPI=7 introduced three commands for common version number operations.

  • ver_cut obtains substrings of a version string
  • ver_rs replaces separators in a version string
  • ver_test compares two versions

See Version and name formatting issues for examples of common uses or an in-depth look

New function eqawarn
The eqawarn helper has been added with EAPI=7. This function is to alert developers to a deprecated feature. Previously, this was contained in eutils eclass which is no longer necessary.
New function dostrip
The dostrip helper has been added with EAPI=7. This function controls whether or not to strip a binary. dostrip -x [file] will exclude a binary from being stripped. Conversely, when combined with RESTRICT=strip, dostrip [file] selects a binary file to be stripped.
die and assert changes
These commands are now safe to use in a subshell and act as if they were called in the main process.
nonfatal changes
The nonfatal command now works for shell functions and subprocesses.
domo behaviour changed
domo (for localizations) now ignores the into directives. This follows similar commands like doinfo and doman.
econf changes
The cross-compilation options --build and --target options to specify CBUILD and CTARGET respectively have been added and are retro-active to all EAPIs. In addition, if the build supports --with-sysroot, the correct value will be passed such that normal and cross-compilations succeed.

EAPI 8

EAPI 8 tree layout

Less strict naming rules for updates directory

Up to EAPI 7, the files in the profiles/updates directory had to follow strict naming by quarters like 2Q-2021, indicating the quarter and the year when they were added. Such a choice of name had the side effect that lexical sorting of filenames was unsuitable.

In EAPI 8, the naming requirement is removed. Eventually, this will allow switching to a more convenient scheme sorted by year. Different lengths of time periods will also be possible.

Note that this change actually requires changing the repository EAPI (found in profiles/eapi), so it will not affect Gentoo for at least the next two years.

EAPI 8 ebuild format

Bash version is now 5.0

The Bash version used for ebuilds is changed from 4.2 to 5.0. This means not only that ebuilds are now permitted to use features provided by the new Bash version but also the BASH_COMPAT value used for the ebuild environment is updated, switching the shell behaviour.

The only really relevant difference in behaviour is:

  • Quotes are now removed from the RHS argument of a "${var/.../"..."}" substitution:

    var=foo
    echo "${var/foo/"bar"}"
    

    The above snippet yields "bar" in Bash 4.2 but just bar in 4.3+.

Potentially interesting new features include:

  • Negative subscripts can now be used to set and unset array elements (Bash 4.3+):

    $ foo=( 1 2 3 )
    $ foo[-1]=4
    $ unset 'foo[-2]'
    $ declare -p foo
    declare -a foo=([0]="1" [2]="4")
    
  • Nameref variables are introduced that work as references to other variables (4.3+):

    $ foo=( 1 2 3 )
    $ declare -n bar=foo
    $ echo "${bar[@]}"
    1 2 3
    $ bar[0]=4
    $ echo "${foo[@]}"
    4 2 3
    $ declare -n baz=foo[1]
    $ echo "${baz}"
    2
    $ baz=100
    $ echo "${bar[@]}"
    4 100 3
    
  • The [[ -v ... ]] test operator can be used with array indices to test for array elements being set (4.3+). The two following lines are now equivalent:

    [[ -n ${foo[3]+1} ]]
    [[ -v foo[3] ]]
    
  • mapfile (AKA readarray) now accepts a delimiter via -d, with a -t option to strip it from read data (Bash 4.4+). The two following solutions to grab output from find(1) are now equivalent:

    # old solution
    local x files=()
    while read -d '' -r x; do
    	files+=( "${x}" )
    done < <(find -print0)
    
    # new solution
    local files=()
    mapfile -d '' -t files < <(find -print0)
    
  • A new set of transformations is available via ${foo@...} parameter expansion (4.4+), e.g. to print a value with necessary quoting:

    $ var="foo 'bar' baz"
    $ echo "${var@Q}"
    'foo '\''bar'\'' baz'
    

    For more details, see: info bash or the Bash reference manual.

  • local - can be used to limit single-letter (mangled via set) shell option changes to the scope of the function, and restore them upon returning from it (4.4+). The following two functions are now equivalent:

    # old solution
    func() {
    	local prev_shopt=$(shopt -p -o noglob)
    	set -o noglob
    	${prev_shopt}
    }
    
    # new solution
    func() {
    	local -
    	set -o noglob
    }
    

    The complete information on all changes and new features can be found in the Bash 5.0 (and earlier) release notes.

EAPI 8 variables

Selective fetch/mirror restriction

Before EAPI 8, fetch and mirror restrictions applied globally. That is, if you needed to apply the respective restriction to at least one distfile, you had to apply it to them all. However, sometimes packages used a combination of proprietary and free distfiles, the latter including e.g. third party patches, artwork. Until now, they had to be mirror-restricted completely.

EAPI 8 allows undoing fetch and mirror restriction for individual files. To use this, set RESTRICT as before, then use the special fetch+ prefix to specify URLs that can be fetched from, or the mirror+ prefix to reenable mirroring of individual files.

Similarly to how the fetch restriction implies a mirror restriction, the mirror override implies a fetch override.

EAPI=8

SRC_URI="
	${P}.tgz
	fetch+https://example.com/${P}-patch-1.tgz
	mirror+https://example.com/${P}-fanstuff.tgz"

RESTRICT="fetch"

The following table summarises the new behaviour:

RESTRICT URI prefix Fetching Mirroring
(none) (any) allowed allowed
mirror (none) / fetch+ allowed prohibited
mirror+ allowed allowed
fetch (none) prohibited prohibited
fetch+ allowed prohibited
mirror+ allowed allowed
Install-time dependencies (IDEPEND)

The primary use for install-time dependencies is to specify dependencies that are needed during the pkg_postinst phase and that can be unmerged afterwards. That's pretty much the same as RDEPEND, except for the unmerging part — and uninstalling a few tools did not seem a goal justifying another dependency type.

With cross-compilation support in EAPI 7, a new dependency type focused on the build host (CBUILD) tools was added — BDEPEND. Unfortunately, this had missed the important use case of running executables installed to the target system when cross-compiling. RDEPEND was no longer a suitable method of pulling in tools for pkg_postinst; and since BDEPEND is not used when installing from a binary package, something new was needed.

This is where IDEPEND comes in. It is roughly to RDEPEND what BDEPEND is to DEPEND. Similarly to BDEPEND, it specifies packages that must be built for the CBUILD triplet and installed into BROOT (and therefore queried using has_version -b). However, similarly to RDEPEND, it is used when the package is being merged rather than built from source. It is guaranteed to be satisfied throughout pkg_preinst and pkg_postinst, and it can be uninstalled afterwards.

EAPI=8

inherit xdg-utils

IDEPEND="dev-util/desktop-file-utils"

pkg_postinst() {
	xdg_desktop_database_update
}

pkg_postrm() {
	xdg_desktop_database_update
}

In the example provided above, the ebuild needs to update the icon cache upon being installed or uninstalled. By placing the respective tool in IDEPEND, the ebuild requests it to be available at the time of pkg_postinst. When cross-compiling, the tool will be built for CBUILD and therefore directly executable by the ebuild.

The dependency types table for EAPI 8 is presented below.

Dependency type BDEPEND IDEPEND DEPEND RDEPEND PDEPEND
Present at build install build install n/a
Binary compatible with CBUILD CHOST
Base unprefixed path / SYSROOT ROOT
Relevant offset-prefix BROOT EPREFIX (unless SYSROOT != ROOT) EPREFIX
Path combined with prefix BROOT ESYSROOT EROOT
PM query command option -b -d -r
PROPERTIES and RESTRICT are now accumulated across eclasses

Up to EAPI 7, PROPERTIES and RESTRICT were treated like regular Bash variables when sourcing eclasses. This meant that if an eclass or an ebuild wanted to modify them, they had to explicitly append to them, e.g. via +=. This was inconsistent with how some other variables (but not all) were handled, and confusing to developers. For example, consider the following snippet:

EAPI=7

inherit git-r3

PROPERTIES+=" live"

Note how you needed to append to PROPERTIES set by git-r3 eclass, otherwise the ebuild would have overwritten it. In EAPI 8, you can finally do the following instead:

EAPI=8

inherit git-r3

PROPERTIES="live"

Now the complete list of metadata variables accumulated across eclasses and ebuilds includes: IUSE, REQUIRED_USE, *DEPEND, PROPERTIES, RESTRICT. Variables that are not treated this way are: EAPI, HOMEPAGE, SRC_URI, LICENSE, KEYWORDS. EAPI and KEYWORDS are not supposed to be set in eclasses; as for the others, there appears to be a valid use case for eclasses providing default values and the ebuilds being able to override them.

EAPI 8 phase functions

pkg_* phases now run in a dedicated empty directory

Before EAPI 8, the initial working directory was specified for src_* phases only. For other phases (i.e. pkg_* phases), ebuilds were not supposed to assume any particular directory. In EAPI 8, these phases are guaranteed to be started in a dedicated empty directory.

The idea of using an empty directory is pretty simple — if there are no files in it, the risk of unexpected and hard to predict interactions of tools with their current working directory is minimized.

PATCHES no longer permits options

The eapply invocation in the default src_prepare implementation has been changed to:

eapply -- "${PATCHES[@]}"

This ensures that all items in the PATCHES variable are treated as path names. As a side effect, it is no longer possible to specify patch options via the PATCHES variable. Such hacks were never used in the Gentoo repository but they have been spotted in user-contributed ebuilds. The following will no longer work:

PATCHES=( -p0 "${FILESDIR}"/${P}-foo.patch )

Instead, you will need to invoke eapply explicitly, see the example below. Alternatively, rebase the patch level.

src_prepare() {
	eapply -p0 "${FILESDIR}"/${P}-foo.patch
	eapply_user
}

EAPI 8 commands

New econf-passed options

The econf helper has been modified to pass two more options to the configure script if the --help text indicates that they are supported. These are:

  • --datarootdir="${EPREFIX}"/usr/share
  • --disable-static

The former option defines the base directory that is used to determine locations for system/desktop-specific data files, e.g. .desktop files and various kinds of documentation. This is necessary for ebuilds that override --prefix, as the default path is relative to it.

The latter option disables building static libraries by default. This is part of the ongoing effort to disable unconditional install of static libraries ( Gentoo Policy Guide, Installation of static libraries).

dosym -r to create relative symlinks

Relative symlink targets tend to be more reliable. Consider the two following examples:

dosym "${EPREFIX}"/usr/lib/frobnicate/frobnicate /usr/bin/frobnicate
dosym ../lib/frobnicate/frobnicate /usr/bin/frobnicate

The first line creates a symlink using an absolute path. The problem with that is if you mount your Gentoo system in a subdirectory of your root filesystem (e.g. for recovery), the symlink will point at the wrong location. Using relative symlinks (as demonstrated on the second line) guarantees that the symlink will work independently of where the filesystem is mounted.

There is also fact that you need to explicitly prepend ${EPREFIX} to the absolute paths passed as the first argument of dosym. Using a relative target avoids the problem altogether and makes it less likely to forget about the prefix.

However, in some instances, determining the relative path could be hard or inconvenient. This is especially the case if one (or both) of the paths comes from an external tool. To make it easier, EAPI 8 adds a new -r option that makes dosym create a relative symlink to the specified path (similarly to ln -r):

dosym -r /usr/lib/frobnicate/frobnicate /usr/bin/frobnicate

Note that in this case, you do not pass ${EPREFIX}. The helper determines the logical relative path to the first argument and creates the appropriate relative symlink. It is very important here to understand that this function does not handle physical paths, i.e. it will work only if there are no directory symlinks along the way that would result in .. resolving to a different path. For example, the following will not work:

dosym bar/foo /usr/lib/foo
dosym -r /usr/lib/zomg /usr/lib/foo/zomg

The logical path from /usr/lib/foo/zomg to /usr/lib/zomg is ../zomg. However, since /usr/lib/foo is actually a symlink to /usr/lib/bar/foo, /usr/lib/foo/.. resolves to /usr/lib/bar. If you need to account for such directory symlinks, you need to specify the correct path explicitly:

dosym bar/foo /usr/lib/foo
dosym ../../zomg /usr/lib/foo/zomg
insopts and exeopts now apply to doins and doexe only

In previous EAPIs, there was an inconsistency in how insopts and exeopts applied to various helpers. In particular, the majority of helpers (e.g. dobin, dodoc and so on) ignored the options specified via these helpers but a few did not.

EAPI 8 changes the behaviour of the following helpers that used to respect insopts or exeopts:

  • doconfd
  • doenvd
  • doheader
  • doinitd

In EAPI 8, they always use the default options. As a result, insopts now only affects doins/newins, and exeopts only affects doexe/newexe. Furthermore, diropts does not affect the directories implicitly created by these helpers.

usev now accepts a second argument

The usev helper was introduced to provide the historical Portage behaviour of outputting the USE flag name on match. In EAPI 8, it has been extended, in order to provide an alternative to three-argument usex with an empty third argument (the two-argument usex variant uses a default of no for the false branch).

In other words, the following two calls are now equivalent:

$(usex foo --enable-foo '')
$(usev foo --enable-foo)

This is particularly useful with custom build systems that accept individual --enable or --disable options but not their counterparts.

As a result, usev and usex can now be used to achieve all the common (and less common) output needs as summarized in the following table.

Variant True False
usev flag flag
usev flag true true
usex flag yes no
usex flag true true no
usex flag true false true false
hasq, hasv and useq functions have been banned

In its early days, the use helper would print the USE flag name if it matched, in addition to its boolean exit status. Later, a quiet useq and a verbose usev helper were added, and use was made quiet by default. The same changes were applied to has.

Fast forward to EAPI 7, there are still three variants of use and three variants of has. The base variant that is quiet, the useq/hasq variant that is equivalent to the base variant, and the verbose usev/hasv variant.

Obviously, adding a second argument to hasv was not possible, so its behaviour would have become inconsistent with usev in EAPI 8. Since hasv was not used in the Gentoo repository, it has been removed, along with hasq and useq which were considered deprecated since 2011.

unpack removes support for 7-Zip, LHA and RAR formats

Support for the least commonly used archive formats from unpack has been removed:

  • 7-Zip (.7z)
  • LHA (.lha, .lzh)
  • RAR (.rar)

Packages using these format for distfiles must now unpack them manually. Using unpacker.eclass is recommended for this.