EAPI 4

Helpers
Removed dohard and dosed
All helpers die on failure
Controllable Compression
docompress helper
dodoc -r
doins and newins preserve symlinks
doman -i18n option takes precedence over filename language suffix
econf adds --disable-dependency-tracking
use_with and use_enable support empty third argument
Metadata
Dependencies
unset RDEPEND no longer triggers implicit setting
USE Dependency Defaults
REQUIRED_USE
Motivation
Specification
Phases
New pkg_pretend Phase Function
Default src_install no longer a no-op
S to WORKDIR fallback restricted
Variables
AA and KV variables are no longer exported
MERGE_TYPE
REPLACING_VERSIONS and REPLACED_BY_VERSION

Helpers

Removed dohard and dosed

The dohard and dosed helpers from previous EAPIs are no longer available.

All helpers die on failure

All helpers now die automatically whenever some sort of error occurs. Helper calls may be prefixed with the 'nonfatal' helper in order to prevent errors from being fatal.

Controllable Compression

In EAPI 4, the package manager may optionally compress a subset of the files under the D directory. To control which directories may or may not be compressed, the package manager shall maintain two lists:

  • An inclusion list, which initially contains /usr/share/doc, /usr/share/info and /usr/share/man.

  • An exclusion list, which initially contains /usr/share/doc/${PF}/html.

The optional compression shall be carried out after src_install has completed, and before the execution of any subsequent phase function. For each item in the inclusion list, pretend it has the value of the D variable prepended, then:

  • If it is a directory, act as if every file or directory immediately under this directory were in the inclusion list.

  • If the item is a file, it may be compressed unless it has been excluded as described below.

  • If the item does not exist, it is ignored.

Whether an item is to be excluded is determined as follows: For each item in the exclusion list, pretend it has the value of the D variable prepended, then:

  • If it is a directory, act as if every file or directory immediately under this directory were in the exclusion list.

  • If the item is a file, it shall not be compressed.

  • If the item does not exist, it is ignored.

The package manager shall take appropriate steps to ensure that its compression mechanisms behave sensibly even if an item is listed in the inclusion list multiple times, if an item is a symlink, or if a file is already compressed.

The following commands may be used in src_install to alter these lists. It is an error to call any of these functions from any other phase.

docompress helper

If the first argument is -x, add each of its subsequent arguments to the exclusion list. Otherwise, add each argument to the inclusion list.

dodoc -r

The dodoc helper now has a -r option which enables recursion.

doins and newins preserve symlinks

The doins and newins helpers now preserve symlinks. In earlier EAPIs symlinks are dereferenced rather than preserved.

doman -i18n option takes precedence over filename language suffix

When the doman helper is called with the -i18n option, this takes precedence over the filename language suffix.

econf adds --disable-dependency-tracking

The econf helper now adds --disable-dependency-tracking to the configure arguments if the string disable-dependency-tracking occurs in the output of configure --help.

use_with and use_enable support empty third argument

Beginning with EAPI 4, an empty third argument is recognized. In EAPI 3 and earlier, an empty third argument is treated as if it weren't provided.

Metadata

Dependencies
unset RDEPEND no longer triggers implicit setting

When the RDEPEND variable is unset within an ebuild, it will remain empty. In prior EAPIs, if RDEPEND was left unset then it was implicitly set to the value of DEPEND.

USE Dependency Defaults

In a 3-style use dependency, the flag name may immediately be followed by a default specified by either (+) or (-). The former indicates that, when applying the use dependency to a package that does not have the flag in question in IUSE_REFERENCEABLE, the package manager shall behave as if the flag were present and enabled; the latter, present and disabled.

Unless a 3-style default is specified, it is an error for a use dependency to be applied to an ebuild which does not have the flag in question in IUSE_REFERENCEABLE.

Note: By extension of the above, a default that could reference an ebuild using an EAPI not supporting profile IUSE injections cannot rely upon any particular behaviour for flags that would not have to be part of IUSE.

It is an error for an ebuild to use a conditional use dependency when that ebuild does not have the flag in IUSE_EFFECTIVE.

REQUIRED_USE

This new REQUIRED_USE metadata key is used to specify what USE flag combinations are disallowed for a specific pkg.

Motivation

It's a semi common occurrence that an ebuild may need to state that they disallow USE flags in specific combinations- either mysql or sqlite for example, but not both.

Existing solutions rely on checking the USE configuration in pkg_setup which is non-optimal due to pkg_setup being ran potentially hours after the initial emerge -p invocation.

Current versions of EAPI4 support a phase hook pkg_pretend that is intended to move pre-build checks to just after resolution. It has been proposed that pkg_pretend should continue the tradition of adhoc shell code validating the USE state- this too is non optimal for the following reasons-

  1. The only way to find out if the USE state is disallowed is to run the code

  2. The common implementation of this can result in an iterative process where the user hits a USE constraint, fixes it, reruns the emerge invocation only to find that there is another constraint still violated for the ebuild, thus requiring them to fix it, rerun emerge, etc.

  3. For a package manager to classify the error, the only option it has is to try and parse adhoc output written by an ebuild dev. This effectively disallows package manager options for providing a more informative error message. A simple example would be if the package manager wanted to integrate in the flag descriptions from use.desc/use.local.desc; this would be effectively impossible.

  4. Fundamentally these constraints are data, yet they're being encoded as executable code- this effectively blocks the possibility of doing a wide variety of QA/tree scans. For example it blocks the possibility of sanely scanning for USE flag induced hard dependency cycles, because the tools in question cannot get that info out of adhoc shell code. More importantly if the manager cannot know what the allowed USE states are for the ebuild in question, this eliminates the possibility of ever sanely breaking dependency cycles caused by USE flags.

Just as .sh scripts are considered a poor archival form due to their opaqueness, pkg_setup and pkg_pretend aren't a proper solution for this. pkg_pretend in particular makes the situation slightly worse due to ebuild devs being expected to convert their ebuilds to the pkg_pretend form when using EAPI4. In doing so they'll have to do work w/out the gains REQUIRED_USE provides and have to repeat the same conversion work when REQUIRED_USE lands in a later EAPI.

Specification

Essentially REQUIRED_USE is proposed to be an analog of DEPENDS style syntax- a list of assertions that must be met for this USE configuration to be valid for this ebuild. For example, to state "if build is set, python must be unset":

REQUIRED_USE="build? ( !python )"

To state "either mysql or sqlite must be set, but not both":

REQUIRED_USE="mysql? ( !sqlite ) !mysql? ( sqlite )"

Note that the mysql/sqlite relationship is that of an Exclusive OR (XOR). While an XOR can be formed from existing syntax, it's suggested that a specific operator be added for this case using ^^. Reformatting the "mysql or sqlite, but not both" with XOR results in:

REQUIRED_USE="^^ ( mysql sqlite )"

Like any block operator, this can be combined with other constraints. For example if the user has flipped on the client flag, one gui must be choosen:

REQUIRED_USE="client? ( ^^ ( gtk qt motif ) )"

If the pkg is implemented sanely and requires at least one gui, but can support multiple it would be:

REQUIRED_USE="client? ( || ( gtk qt motif ) )"

Because ARCH is integrated into the USE space, this also allows for specifying corner cases like "at least one gui must be specified, but on mips only one gui can be specified":

REQUIRED_USE="client? ( !mips? ( || ( gtk qt motif ) ) mips? ( ^^ ( gtk qt motif ) ) )"

Please note that the AND operator is of course supported- if to enable client you must choose at least one gui and enable the python bindings the syntax would be:

REQUIRED_USE="client? ( python || ( gtk qt motif x11 ) )"

Finally, please note that this new metadata key can be set by eclasses, and the inherit implementation should protect the eclass set value just the same as how eclass defined DEPEND is protected.

Phases

New pkg_pretend Phase Function

The pkg_pretend function may be used to carry out sanity checks early on in the install process. For example, if an ebuild requires a particular kernel configuration, it may perform that check in pkg_pretend and call eerror and then die with appropriate messages if the requirement is not met.

pkg_pretend is run separately from the main phase function sequence, and does not participate in any kind of environment saving. There is no guarantee that any of an ebuild's dependencies will be met at this stage, and no guarantee that the system state will not have changed substantially before the next phase is executed.

pkg_pretend must not write to the filesystem.

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

	if ! declare -p DOCS &>/dev/null ; then
		local d
		for d in README* ChangeLog AUTHORS NEWS TODO CHANGES \
				THANKS BUGS FAQ CREDITS CHANGELOG ; do
			[[ -s "${d}" ]] && dodoc "${d}"
		done
	elif [[ $(declare -p DOCS) == "declare -a "* ]] ; then
		dodoc "${DOCS[@]}"
	else
		dodoc ${DOCS}
	fi
}
			
S to WORKDIR fallback restricted

For any of the src_* phases that executes after src_unpack, it is invalid for the S variable to refer to a non-existent directory. However, these src_* phases are exempt from this requirement if none of the prior src_* phases are defined by the ebuild. When a src_* phase is exempt from this requirement, if the S variable does not refer to an existing directory, the WORKDIR directory will be used instead of S as the initial working directory.

Variables

AA and KV variables are no longer exported

The AA and KV variables are no longer exported to the ebuild environment.

MERGE_TYPE

The type of package that is being merged. Possible values are: "source" if building and installing a package from source, "binary" if installing a binary package, and "buildonly" if building a binary package without installing it.

REPLACING_VERSIONS and REPLACED_BY_VERSION

The REPLACING_VERSIONS variable shall be defined in pkg_preinst and pkg_postinst. In addition, it may be defined in pkg_pretend and pkg_setup, although ebuild authors should take care to handle binary package creation and installation correctly when using it in these phases.

REPLACING_VERSIONS is a list, not a single optional value, to handle pathological cases such as installing foo-2:2 to replace foo-2:1 and foo-3:2.

The REPLACED_BY variable shall be defined in pkg_prerm and pkg_postrm. It shall contain at most one value.