ebuild shell blows me away

Since I initially raised the topic of using an ebuild to build from a custom source location (rather than unpacking from the tarball as it normally would), a few people have questioned me — is there really a way it can be done without modifying the ebuild at all?

Well, the answer is YES! I’ve just done it.

This is largely thanks to portage-cvs’ ebuild shell capabilities. This really is a fantastic piece of work.

Here’s a quick proof-of-concept example. Note that portage-cvs is required for this.

For many packages, you might say that I can easily point it to use my own set of sources instead of the tarball by simply hacking a value of ${S} to point at my own sources, and not running the ebuild’s src_unpack at all.

Well, what about the ebuilds that do useful things in src_unpack after unpacking the tarball? It would be nice if we didn’t have to also skip them.

Again, I’m using gamin as an example. gamin-0.0.26-r6.ebuild has a src_unpack function which looks like this:

src_unpack() {
	unpack ${A}
	cd ${S}

	# patch to work with inotify 0.21
	epatch ${FILESDIR}/${P}-inotify_use_fd.patch
}

So, this is a pretty standard scenario, a tarball unpack and a small patch fix being applied afterwards.

Now onto the real task. You need to install two files:

  1. Install the ebuild-env script somewhere in your PATH (e.g. /usr/local/bin) and make it executable.
  2. Install my ebuild.bashrc in the home directory of your non-root user.

Next up, we’ll obtain some gamin sources. The target scenario is where you have already got gamin sources lying around in your home directory and you’ve hacked on them somewhat, but for the sake of this demonstration, we’ll put them in place ourselves. Here’s a link to gamin 0.0.26 from the Gentoo mothermirror: gamin-0.0.26.tar.gz.

From your home-directory of your non-root user, extract the tarball as normal.

# tar xzf gamin-0.0.26.tar.gz
# cd gamin-0.0.26

Enter the pseudo-ebuild-environment shell:

# ebuild-env

At this point, you can run commands that you normally would inside ebuilds (inherit, unpack, epatch, use_enable, etc) – but don’t do this right now, some of them require some hackery to get going and we should keep the environment clean.

Now run use-ebuild to prepare the environment for working with gamin-0.0.26-r6.ebuild. use-ebuild is a function included in my ebuild.bashrc – it finds the ebuild you specify, sets up some environment variables such as ${P} and ${FILESDIR}, sources the ebuild, and sets ${S} to be the location where you called use-ebuild from (in this case, our locally unpacked gamin sources in our homedir).

# use-ebuild gamin 0.0.26-r6
QA Notice: ECLASS 'eutils' illegal conditional inherit in /gamin-0.0.26-r6
QA Notice: ECLASS 'multilib' illegal conditional inherit in /gamin-0.0.26-r6

Ignore the QA notices for now. You may notice a few other odd messages appearing in this demonstration. I’m ignoring the non-critical ones for now. The important part is that the ebuild has been sourced and the environment has been modified accordingly.

So now lets unpack the ebuild, like this:

# src_unpack
 * Would normally unpack:
 * Applying gamin-0.0.26-inotify_use_fd.patch ...  [ ok ]

Notice that the normal stage of unpacking the tarball from /usr/portage/distfiles was skipped, it just worked on the sources it found in the current directory. Notice also that the rest of src_unpack was executed as normal – i.e. the patch was applied.

Compilation through the normal portage processes is just as easy

# src_compile

Portage will now run econf and emake with all the other useful voodoo which comes with it.

And thats all there is to it. I haven’t tried src_install or merge onto live filesystem yet, but you can see I’m a good deal of the way there.

I’ve had to include some hackery in the ebuild.bashrc file to replicate the portage environment closely. At the moment, I’ve included the bare minimum to get the gamin example to work. Don’t be suprised if it fails with other packages right now, but you’ll probably find it easy to fix – it only took me 10 minutes to write the whole script.

Many thanks to ferringb for writing the ebuild-shell functionality. I’m very impressed with how simple it was for me to chain onto portage in this fashion. I’ll add this example to the development platform page soon.