gentoo prefix

February 5, 2011

Once upon a time I’ve got a bunch of emails from gentoo’s bugzilla about haskell prefix support:

The idea of prefix is quite fun. In one sentence it can be described as:

run gentoo in your $HOME/gentoo/ on any host operating system: MacOS, Linux, Solaris, etc.

I tried to read the notes about porting ebuilds to support it and was seriously confused by $D vs $ED, $ROOT vs $EROOT and $EPREFIX variable meanings.

So I gave up on it for extended time and returned back to prefix this week.

I’ve decided to solve my $ROOT vs. $EROOT confusion and to try to merge haskell related changes for prefix. They are very useful after all: you could hold various ghc versions without need to keep full-fledged chroot. Say, prefix-ghc612 user could hold ghc-6.12.3 in his $HOME/gentoo/ and prefix-ghc700 user could hold currently unstable ghc-7.0.1. so you just issue:

sudo su - prefix-ghc612 # or prefix-ghc700

and get needed ghc and it’s environment.

So far I’ve decided to actually install prefix. It was quite simple. With great help of grobian and solaris HOWTO I’ve bootstrapper prefix. There were some deviations from the guide: I had to install coreutils6 instead of coreutils and tar22 instead of tar. The rest of stuff was smooth.

Then I once again started to look the “porting to prefix” so called techdoc. The thing, which annoyed me is a lost meaning of commonly used $ROOT and $D variables in ebuilds. Prefix team seds them out to $EROOT and to $ED almost in every place of every ebuild! (exceptional cases are to be described below)

So, what are those E* variables? Basically the sole difference from usual gentoo installation is slightly changed absolute path for all the packages. The prefixed gentoo root has EPREFIX variable name.

An example:

Having EPREFIX=$HOME/gentoo/ you will have (say) gcc installed in $EPREFIX/usr/bin/gcc (aka $HOME/gentoo/usr/bin/gcc).

In order to achieve it portage should call not ./configure --prefix=/usr but ./configure --prefix=$EPREFIX/usr. And that’s all!

Except you need to adjust all the ebuilds, which use absolute paths to use $EPREFIX. An example:

# somewhere in pkg_setup() on gentoo-x86 tree
[[ -e /usr/bin/python2 ]] && einfo "Whoa, you have python"

# on prefix tree should be changed to
[[ -e $EPREFIX/usr/bin/python2 ]] && einfo "Whoa, you have python"

Everything else should use relative path and do not suffer from change at all!

But! there is one serious culprit. Under prefix $ROOT is meaningless variable! There is EROOT=$ROOT/$EPREFIX to mean gentoo root.

Let’s see at the following merge session:

>>> Completed installing less-440 into /home/prefix/gentoo/var/tmp/portage/sys-apps/less-440/image/home/prefix/gentoo/

strip: i686-pc-linux-gnu-strip --strip-unneeded -R .comment
   usr/bin/lessecho
   usr/bin/lesskey
   usr/bin/less

The $D variable is /home/prefix/gentoo/var/tmp/portage/sys-apps/less-440/image/, and if you plan to use any modifications in the image you should use ${D}{$EPREFIX} as an absolute path. Like the following:

make DESTDIR="${D}" install
strip ${D}${EPRFIX}/usr/bin/less

For simplicity there is $ED variable ED=${D}${EPREFIX} (I would call it $DE, which would have shortening of: D + E(prefix)). So you can use the following to access to the staging area:

make DESTDIR="${D}" install
strip ${ED}/usr/bin/less

Ok, once again: $D points to the sandbox root for a staging install (as it always was). My apologies to darkside and grobian for not getting right it from the very start.

And $EROOT is for prefixed root to access things like:

What about the $ROOT then? And here we have a problem. Under prefix $ROOT is not our prefixed gentoo’s root, but host’s root (aka “/”)! Gah! Why would we need to know about it at all? And there is rare cases when we need it:

The short guideline for prefix porter: