Project:Prefix/Technical Documentation

From Gentoo Wiki
Jump to: navigation, search

Technical documentation on Gentoo Prefix

Changes to Portage


What does Gentoo Prefix do more? For short, it allows to install packages into an offset, without root privileges. The longer answer includes how this is done, and why. To start with the latter one, let's see how the land of the package manager (Portage) looks like.

A package manager can be primary, or secondary. In the first case, the package manager is responsible for building the (core) system, while in the latter case, the package manager builds on top of an existing system to enhance it. Please note that this is by no means meant as a formal definition of the general concept "package manager". Within this document it is used as entity that is natively responsible for managing software packages on the OS it works on. Effectively, this means that Gentoo Portage is not the primary package manager on Apple Mac OS X, Sun Solaris, Debian, Ubuntu, etc. Gentoo Portage is the primary package manager on its Gentoo GNU/Linux distribution, and as such, the Gentoo repository matches this goal.

The Portage version we use in Gentoo Prefix is meant to be a secondary package manager. Therefore it doesn't require root privileges, and has to install into another place than /, because there the primary package manager is already in charge.

This Portage version started as a set of patches by Michael Haubenwallner, that were finally applied to a new branch of portage development: Prefix. In this branch, initially managed by Brian Harring, then later by Kito Dietrich, lots of development made Prefix portage into what it is currently. Fabian Groffen did lots of work on getting the Portage sources usable for everyday Prefix use. Currently, the Prefix branch of the Gentoo repository benefits a lot from the efforts of Zac Medico to make Prefix a first class feature of Portage.

Technical state

The Portage version used in Gentoo Prefix resides in the prefix branch of the main Portage Subversion repository. Its sources can be inspected at, the Portage in this branch code is very close to the master branch in git. Patches made in master usually apply cleanly to the prefix branch. Hence, it is easy to keep the two synchronised using frequent merge operations.

Repository state

Since the Gentoo Linux repository is not always compatible with Gentoo Prefix, an overlay has been created, which is currently hosted on This overlay is really overlaid on the main Gentoo repository, and provided as such to Prefix users from the Prefix rsync mirror.

Keeping the copied packages in the overlay synchronised with the main repository is facilitated by a script that is capable of applying the diffs with some intelligence between revisions. Also "cross-diffs", diffs between versions to create a new ebuild version, retaining as much changes as added in the previous version are implemented, keeping the maintenance overhead rather low.

Ebuild modifications

EPREFIX variable

Since Portage will install in an offset, called a "prefix", in some cases it might be necessary to directly handle with this offset. Some configure scripts for example require paths to be given next to --prefix, --libdir, etc. (all what econf covers), or some packages can't use econf at all. For those occasions the EPREFIX variable is available in ebuilds and eclasses, pointing to the root of the offset. For an offset /home/user/gentoo for example, the EPREFIX variable would contain /home/user/gentoo. This allows to easily use it for example like econf --with-some-app="${EPREFIX}"/usr/bin/some-app.

The variables ED and EROOT

In normal ebuilds, ${D} refers to the destination directory in a temporary location before all files are actually merged into the live filesystem. Since in Gentoo Prefix configure is run with --prefix=${EPREFIX}/usr in principle no changes are required. However, for all modifications to the build image, as is common practise in many ebuilds, ${D%/}${EPREFIX} should be used. While this is a clean and logical result of using an offset, it increases the burden of "porting" ebuilds. For this purpose the variable ${ED} was introduced. It contains the value of ${D%/}${EPREFIX}/ and functions as handy shortcut, which is easy to change. Usually, all but one occurrences of ${D} in an ebuild (or eclass) have to be replaced by ${ED} to work properly in the prefix. Remember that when using make DESTDIR="${D}" install the ${D} should in general not be changed, as configure was called with --prefix="${EPREFIX}"/usr.

The variable ${ROOT} has for the same purpose a corresponding ${EROOT} which contains ${ROOT%/}${EPREFIX}/. Often when ${ROOT} is being used, this can be replaced by ${EROOT} to add Gentoo Prefix support.


Given that ${EROOT} is ${ROOT}${EPREFIX}, using ${EROOT} or ${EPREFIX} is defined by the following rule. The rule is simple and automatable, whether or not it is "correct", for Gentoo Prefix this rule always holds:

If the main tree ebuild uses ${ROOT} , we respect ${ROOT} and usually use ${EROOT} , however if the main tree does not use ${ROOT} , we only add the offset, ${EPREFIX} .

This rule basically means that you never add ${EROOT} yourself, if there isn't a ${ROOT} in the main tree ebuild. Repeating: whether or not that is "correct", for Gentoo Prefix this rule always holds. Rationale is simple: if it is a bug, it is a bug that should be fixed "upstream" (in the main repository), and that fix propagated to Gentoo Prefix. We don't want any extra differences between main repository and Gentoo Prefix, to keep maintenance and the amount of unrelated changes low.


In some cases, the offset prefix needs to be hardcoded into files. Examples are shebangs with arguments or references to config files. The prefix.eclass provides the function eprefixify, which replaces each occurrence of @GENTOO_PORTAGE_EPREFIX@ with the offset prefix as known by Portage. To use the eprefixify function on files (e.g. after patching), one needs to inherit the prefix eclass.

Ebuild inter-revisions

This subsection only applies to the Prefix Overlay, not the main Gentoo Linux repository, and the use of inter-revisions is highly discouraged!

Gentoo Prefix ebuilds are currently merged from the main tree, and kept in sync. This process is half automated using scripts and in short takes differences from the main tree to apply them on the Prefix tree. This process insures that changes made to the Prefix tree are not lost, where it still is possible to merge most changes. For this to work, the ebuilds need to keep the same filename as in the main tree though. This way an ebuild in the Prefix tree can be compared to the same ebuild in the main tree. Since in Prefix also fixes need to be pushed to users, a revision of an ebuild cannot be simply bumped, since this would break synchronisation and result in collisions when the main tree does a revision bump too. For this purpose, inter-revisions have been implemented in Gentoo Prefix. They allow to specify a higher version to an ebuild, while maintaining the connection with the main tree. Inter-revisions are simple sub-revisions of main revisions, meaning that for every revision, a numbered sub-revision (inter-revision) version can exist. To make Portage distinguish normal and inter-revisions, the latter ones start with a 0 followed by the normal revision number. The inter-revision is added as dot and the number. An example inter-revision 2 of revision 3 would be -r03.2. Note that the inter-revision of a revision less ebuild is the inter-revision of revision 0. For example: -r00.1.

The effect of inter-revisions on Portage is that the sub-revision part is taken into account when comparing the versions. A normal revision has a sub-revision of 0, hence -r01.1 is greater than -r1. This allows to bump a package in Prefix only. For the update scripts, however, the inter-revision is not taken into account. Hence, when an inter-revision ebuild is compared with the main tree, it is compared to the revision part only, thereby not breaking the connection between the Prefix tree and the main tree.

Gentoo Prefix tree developer policies

Main tree migrations

In principle, all ebuilds in the Gentoo Prefix tree are modified copies from their versions in the main tree, as used by Gentoo Linux. This means that each ebuild is copied and hence needs to be kept in sync with the main tree version. Since ebuilds in the Prefix tree all have manual modifications (those not automatically scriptable), the process of keeping the Prefix tree in sync with the main tree is not as straight forward as simply running a script. Instead, a complex script, eupdate is used to apply the differences made to an ebuild in the main tree, to the version in the Prefix tree. Also when new versions of ebuilds are added to the main tree, the eupdate script derives a new version in the Prefix tree, based on the differences between the latest two versions of the ebuilds in the main tree. This process is called a cross-diff . Both updating strategies may fail depending on modifications made to the ebuild in the Prefix tree. In 90% of the cases, both update strategies apply without problems, and semi-automatic propagation relies on that to currently merge changes from the main tree on a daily basis, with a limited investment of time on (manually) resolving the conflicts.

Mainly because manually resolving conflicts is a tedious job, the main policy in the Prefix tree with regard to modifications made to the main tree version is sound and simple: avoid any change that is not strictly necessary!. This boils down to the following concrete rules that need to be taken into account. Quoting of variables is a often confusing job. Underquoting results in problems when spaces are being used, overquoting is just unnecessary work. In many cases, the quoting of variables is done wrong in the main tree ebuilds, hence the problem is also carried over onto the Prefix tree. Fixing these quoting problems should not be done, unless this is necessary to solve a Prefix specific problem, which happens only in rare cases. Along the same line, adding or removing white space, indenting, rewriting to make more optimal in execution and similar changes which are not essentially necessary, should be avoided. To avoid differences in the Changelog file, you should not use echangelog when committing changes to ebuilds that are available in the main tree, and hence subject to semi-automatic updating. In fact each Changelog entry added using echangelog makes a conflict during updating, making the problem even worse. Don't update the ChangeLog.

When changes need to be made, such as adding an epatch line, or adding a platform specific statement, such as an configure option, care needs to be taken to try to reduce the size of the differences introduced. The smaller the difference, the bigger the chance that semi-automatic updating succeeds without problems.

For files that have no CVS header, and hence cannot be kept in sync, such as e.g. metadata.xml and many patches in the files/ directory the eupdate command just makes sure it is equal to the version in the main tree. For this reason, keep in mind that changes to those files get lost upon the next run of eupdate. Since this is done almost daily, the modifications disappear soon enough. Only files with a CVS $ Header :(such as ebuilds) can be changed in such a way that the modifications are not lost.

The good news is that Gentoo Prefix lives for a great deal in gx86, these days. Thus, the prefix overlay is being emptied, by migrating its packages to gx86. This requires contacting the gx86 maintainers and getting them to accept the changes necessary. Often, ebuilds in the prefix overlay need cleaning up, and reevaluation if hacks, patches and other changes are still necessary. Remember that many ebuilds have grown over years in the prefix overlay, and hence not necessarily are the cleanest solution. We aim not to add anything to our overlay any more, and move more and more towards acceptance in gx86.

This article is based on a document formerly found on our main website
The following people contributed to the original document: Fabian Groffen (grobian)
They are listed here as the Wiki history does not allow for any external attribution. If you edit the Wiki article, please do not add yourself here; your contributions are recorded on the history page.