He's not dead, he's resting
New Gentoo EAPI Things: DEFINED_PHASES
This is the first post in a series about new Gentoo EAPI things.
DEFINED_PHASES is a new magic metadata variable that we’ve retroactively added to all existing EAPIs. As such, package managers can’t assume that it’s supported, but that’s not really a problem.
DEFINED_PHASES is purely for package manager use; it may or may not be exported in the environment to ebuilds, and ebuilds mustn’t touch it.
If a package manager supports it, at metadata generation time, the package manager will generate a list of phase names whose phase functions are defined by an ebuild (or an eclass inherited by that ebuild). The
DEFINED_PHASES metadata cache key contains this list, space separated and in no particular order. For example, the current value for app-editors/vim-7.2.021 would be (possibly not in this order):
DEFINED_PHASES="setup unpack compile install test postinst postrm"
In this case, all of these functions come from eclasses.
As a special rule, if an ebuild defines no phase functions (for Gentoo, this is mostly just metapackages and new style virtuals, since the default
src_install is useless), the value is a single hyphen rather than an empty string. This lets package managers tell the difference between “cache generated by an old package manager” and “no phases defined”.
Note that even the name
DEFINED_PHASES is largely meaningless. The current cache format is a flat list, rather than a key=value format, so
DEFINED_PHASES doesn’t show up somewhere. It has a name because at some point the switch to a key=value format cache might be made, and to avoid any future name collisions in ebuilds which might otherwise use
DEFINED_PHASES as a variable.
So what’s the point?
With current 0-based EAPIs,
DEFINED_PHASES has a few uses:
- It can be used to save a bit of time during the build process by ignoring phases that have an empty default implementation and no ebuild implementation, but this isn’t really a huge deal. Package managers could get this benefit anyway by regenerating metadata locally up-front.
- For interactive packages, it lets the package manager avoid having to go into ‘interactive’ mode for most phases.
- It lets the package manager parallelise
pkg_phases if there’s no implementation. Normally
pkg_phases have to be run exclusively because they can modify the live filesystem.
DEFINED_PHASES really comes into its own with various things that will probably be in future EAPIs (some of which are already in exheres-0):
- The proposed
pkg_pretendfunction, which will be run at pretend-install time, would require about 0.1s per package to be changed. When doing a large upgrade, this can result in the user having to sit there waiting for tens of seconds whilst the package manager runs lots of mostly useless ebuild phase functions.
src_fetch_extra(to handle fetching scm things, rather than using
src_unpack) shouldn’t be run except where necessary.
It might be possible to use this to get
pkg_nofetch information upfront at pretend-install time too. I’m still thinking about that.
Paludis has had
DEFINED_PHASES support since 0.32.2, although no cache line had been standardised so it was only used for self-generated caches. The next release (0.32.4 or 0.34.0) will use the agreed-upon line. Portage doesn’t yet support this, so Gentoo-generated caches won’t include a value yet anyway.