Gentoo Archives: gentoo-dev

From: Fabian Groffen <grobian@g.o>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] Gentoo Prefix: on EPREFIX, ED and EROOT inside ebuilds
Date: Sun, 18 Oct 2009 09:12:40
Recently, Prefix changes have been committed to the gentoo-x86 tree, it
was rather ambitious on my part, where I moved stuff that we are not
maintainer of ourself.  It should have been communicated better for
these ebuilds.  This is a formal apology for springing that onto you.
This will attempt to solve the confusion and answer questions that have
been raised.

Gentoo Prefix has mainly the following characteristics:
- allow for unprivileged installations,
- in an offset-prefix called "the prefix", often referred to as EPREFIX,
  in autoconf words: ./configure --prefix=${EPREFIX}/usr

In the Prefix Portage branch, that we have in use [1], we extended and
adapted regular Portage to support above two characteristics.  I will
ignore the details of unprivileged installations in this email.

The offset-prefix changes in Portage introduce three new variables that
are available in the ebuild environment:
- EPREFIX: the configured offset-prefix
- ED: shorthand for ${D%/}${EPREFIX}/

The offset-prefix changes require extensive changes to most eclasses,
and minor changes to many ebuilds.  This is mainly because "awareness"
of the offset-prefix has to be added to places where ebuilds manually
deal with file-system locations.  In particular:
- configure calls that specify some argument to find a component need to
  do so in the offset prefix, e.g.
- almost every place where ${D} is used, the offset-prefix ${EPREFIX}
  has to be added.  Because this is lengthy, Prefix Portage provides a
  variable ${ED} that is the shortcut for ${D} plus the offset-prefix.
- the same holds for occurrences of ${ROOT}, where ${EROOT} is available
  as shortcut

Why do we need both ${ED} and ${D}?  Technically we don't, because we
can use ${EPREFIX} all the time.  However, one cannot say that ${D}
includes ${EPREFIX} for Prefix Portage, because that means the following
src_install() function no longer works correctly:

  src_install() {
    emake DESTDIR="${D}" install || die
    mv "${D}"/usr/bin/{,exuberant-}ctags || die

While the "mv" does a great job if ${D} would include ${EPREFIX} here,
the make install will cause double offset to be written, since configure
recorded the ${EPREFIX} before in src_compile using the argument
--prefix="${EPREFIX}"/usr.  In a previous version of Prefix Portage, the
variable EDEST was available as workaround for this, so the example
would read like this:

  src_install() {
    emake DESTDIR="${EDEST}" install || die
    mv "${D}"/usr/bin/{,exuberant-}ctags || die

Apart from that this approach got very tricky and confusing in eclasses
and ebuilds that do special mungling in their src_install, it makes it
harder to reconstruct the variable in normal Portage and hence to make
existing ebuilds forward compatible.

The lengthy forward compatible version of the example src_install
function would look like this:

  src_install() {
    emake DESTDIR="${D}" install || die
    mv "${D%/}${EPREFIX}"/usr/bin/{,exuberant-}ctags || die

As mentioned before, this is pretty lengthy, and quickly becomes too
much work and unreadable when ${D} is used more.
To avoid the confusion that implicit ${EPREFIX} in ${D} in the ${EDEST}
approach brought, ED and EROOT were chosen because they are easy to
understand and easy to reconstruct outside Prefix Portage.  To help
with this, the Prefix profiles use.force the "prefix" USE-flag.
Non-Prefix profiles have this flag masked and unset in the base profile.
This USE-flag can be used to do conditional code for Prefix consumers.
In case of our ${ED} and ${EROOT} convenience variables, we can use it
to define ${ED} and ${EROOT} in case a normal Portage is used.  For our
example function:

  src_install() {
    use prefix || local ED=${D}
    emake DESTDIR="${D}" install || die
    mv "${ED}"/usr/bin/{,exuberant-}ctags || die

Here, Prefix Portage (using a Prefix profile) will not set ${ED}, but
still do as intended because ${ED} is set correctly by Prefix Portage.
Normal Portage will set the convenience variable such that it does not
cause a sandbox violation due to the missing image path.

We will consult the maintainers of packages we would like to make
compatible with Gentoo Portage before adding the changes.  In the
future, you will likely see more bug reports and more requests on IRC
from us.

At this point, we have reached a critical mass where we cannot maintain
the Prefix overlay much longer with its size and usage.  We either
continue to grow on, requiring less maintenance on tree synchronisation,
or we stop the project -- an option we really don't like.
Bringing back most, and ideally all, ebuilds to gentoo-x86 significantly
improves the workload caused by synchronisation, leaving more time for
the real issues.  Examples are fixing and porting packages and getting
the Prefix Portage branch merged with regular Portage some day.  At that
point, the variables EPREFIX, ED and EROOT can become available in a
next EAPI as well.


Fabian Groffen
Gentoo on a different level