EAPI usage and description – Gentoo Development Guide
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
Important:
An overview about the important features of each EAPI is provided in the
appendix of the Package Manager Specification. The two-page leaflet
can be printed out, consulted for reference and is available
as
app-doc/pms
in the main tree.
You must set the EAPI variable by specifying it at the top of the ebuild:
1999-2021
Gentoo
Authors
Distributed
under
the
of
the
GNU
General
Public
License
v2
EAPI
Note:
Most developers prefer to set the EAPI version without quotes. However,
enclosing it in single or double quotes is also allowed.
Important:
EAPI must only be defined in ebuild files, not eclasses. (eclasses may have
EAPI-conditional code)
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
Todo:
EAPI 5 is deprecated and should no longer appear here. The information needs to
be split up and moved to other sections.
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.
Note:
use
:slot/subslot
without a
to depend on a specific
slot and sub-slot pair; it's a syntax error to use
:slot/subslot=
in an ebuild.
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
# 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
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
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 desktop
database 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
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
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.
EAPI 9
Note:
This section is based on the
EAPI Cheat Sheet
EAPI 9 profiles
Default EAPI for profiles
Profile directories that don't contain an own
eapi
file no longer
default to EAPI 0, but to the EAPI specified in the top-level
profiles
directory.
use.stable
and
package.use.stable
Profile dirs may contain two new files
use.stable
and
package.use.stable
. They can be used to override the USE flags
specified by
make.defaults
, but act only on packages that would be
merged due to a stable keyword.
The format of the
use.stable
file is simple: Each line contains a
USE flag to enable; a minus sign before the flag indicates that the flag
should be disabled instead.
The
package.use.stable
file has the same format as
package.use
(see
make.conf(5)
).
USE_EXPAND
values may be enabled or disabled by using
expand_name_value
Flags listed in
package.use.stable
take precedence over these listed
in
package.use
, which in turn take precedence over
use.stable
EAPI 9 ebuild format
Bash version is now 5.3
Ebuilds can use Bash version 5.3 (was 5.0 before).
Some notable new features are:
declare
and
local
now have a
-I
option that
inherits the attributes and value from of any existing variable with
the same name at a surrounding scope. For example, an ebuild could do
local
-Ix ROOT
to export the
ROOT
variable to the environment, from where an
external could get its value.
There is a new form of command substitution:
${ command; }
or
${|command;}
to capture the output of
command
without
forking a child process and using pipes.
${ command; }
executes
command
in the current execution
environment and captures its output. Any side effects of
command
take effect immediately in the current execution environment and
persist after the command completes. This type of command substitution
superficially resembles executing an unnamed shell function: local
variables are created as when a shell function is executing, and the
return
builtin forces
command
to complete; however, the
rest of the execution environment is shared with the caller.
The
${|command;}
construct expands to the value of the
REPLY
shell variable after
command
executes, without
removing any trailing newlines, and the standard output of
command
remains the same as in the calling shell. Bash creates
REPLY
as an initially-unset local variable when
command
executes, and restores
REPLY
to its old value after
command
completes, as with any local variable.
For example, this construct expands to
12345
, and leaves the
shell variable
unchanged in the current execution environment:
${
local
12345;
echo
$X;
while the following construct does not require any output to expand to
12345
and restores
REPLY
to the value it had before the
command substitution:
${|
REPLY
12345;
Pattern substitution now duplicates a common
sed
idiom:
If the
patsub_replacement
shell option is enabled (which it is
by default), any unquoted
in the replacement string is
replaced with the portion of the string that matched the pattern.
For instance:
var
foobar
echo
${var/foo/&123}
will print
foo123bar
, i.e. the
in the replacement
string is replaced with the string
foo
that matched the pattern.
A backslash can be used to escape the
and insert a literal
in the replacement string.
EAPI 9 variables
Variables are no longer exported
The package manager no longer exports its defined shell variables to the
environment but keeps them as unexported shell variables, namely:
CATEGORY
PF
PN
PV
PR
PVR
FILESDIR
DISTDIR
WORKDIR
ROOT
EROOT
SYSROOT
ESYSROOT
BROOT
EPREFIX
ED
USE
EBUILD_PHASE
EBUILD_PHASE_FUNC
MERGE_TYPE
REPLACING_VERSIONS
REPLACED_BY_VERSION
ECLASS
INHERITED
DEFINED_PHASES
Important:
Exceptions are
TMPDIR
and
which are always exported.
The same applies to variables set in
make.defaults
that have
specific meanings or special handling. These are no longer exported to the
environment of an EAPI 9 ebuild:
ARCH
CONFIG_PROTECT
CONFIG_PROTECT_MASK
USE
USE_EXPAND
USE_EXPAND_UNPREFIXED
USE_EXPAND_HIDDEN
USE_EXPAND_IMPLICIT
IUSE_IMPLICIT
ENV_UNSET
All variables named in
USE_EXPAND
and
USE_EXPAND_UNPREFIXED
All
USE_EXPAND_VALUES_${v}
variables, where
${v}
is a
value in
USE_EXPAND_IMPLICIT
All other variables set in
make.defaults
will still be exported to
the environment.
As a consequence, external commands can no longer rely on the value of the
ROOT
variable in the environment. For example,
eselect
must
be called with the
--root
option in EAPI 9:
pkg_postinst()
eselect
--root
${ROOT}
emacs update ifunset
EAPI 9 commands
assert
has been banned
Our definition of
assert
deviated from the semantics of the command
in mainstream programming languages and was a source of confusion.
Therefore, use of the
assert
command in ebuilds is no longer
allowed.
pipestatus
(see below) should be used as replacement.
domo
has been banned
The operation of the
domo
command was unintuitive. It also hardcoded
${PN}
as the gettext domain, which is often not what is wanted.
Therefore, the
domo
command has been banned.
insinto
plus
newins
should be used as replacement.
pipestatus
Checks if all commands in the last executed pipeline have returned an exit
status of zero. When the
-v
option is specified, also prints the
shell's pipe status array.
foo
bar
baz
pipestatus
||
die
ver_replacing
op v2
Checks if the relation
v1 op v2
is true for at least one element
v1
of
REPLACING_VERSIONS
op
can be any operator that
is accepted by
ver_test
. Returns shell true (0) if the specified
relation holds for at least one element, shell false (1) otherwise.
In particular, shell false is returned when
REPLACING_VERSIONS
is empty.
Obviously,
ver_replacing
is only meaningful in phases where
REPLACING_VERSIONS
is defined, i.e. in
pkg_preinst
and
pkg_postinst
pkg_postinst()
if
ver_replacing
-lt
3;
then
elog
This is a major upgrade and may break your existing setup!
fi
edo
Outputs its entire argument list as an informational message, then executes
it as a simple shell command, with standard failure behaviour.
EAPI 9 merging and unmerging
Merging of symlinks
When merging
to
ROOT
, absolute symlinks are now merged
as-is. The package manager will no longer strip a leading
from
their link targets.
In previous EAPIs, any absolute symlink whose link target started with
${D}
was rewritten with the leading
${D}
removed.
That behaviour was ill-defined because
is not guaranteed to have
the same value that it had in the
src_*
phases. For example, when
a binary package was merged on a target host with
PORTAGE_TMPDIR
different from the build host's
PORTAGE_TMPDIR
, symlink rewriting
would have failed.