Basic guide to write Gentoo Ebuilds

Portage, the heart of Gentoo, uses ebuild scripts!
In order to be able to do package management you have to define what packages are and how they download, unpack, patch, compile, install and merge (copy it from a temporary directory to your live file system) sources and/or binaries, to make it more nice we also add some useful metadata as well as USE flags, patches and more to allow one to manipulate the process the way; this definition is mostly done in an ebuild, which are bash shell scripts.

Ebuilds, where do they live? How do I create one?
When you had set up Gentoo, you probably remember that you had to download and unpack a Portage tree snapshot. This snapshot (which you later update when you run emerge --sync) is full of ebuilds, it is the Portage tree and once unpacked is usually located at /usr/portage.

Now, you can't just create a file /usr/portage/hello-world.ebuild and be done with it; there are several reasons:


 * 1) It is your local copy of a remote Portage Tree: If you place an ebuild in there or update an ebuild, then you run emerge --sync, your changes will be gone. Therefore, you will want to work in /usr/local/portage, in a sub directory of your home directory or in an overlay instead.
 * 2) The ebuild file is not in the right directory: An ebuild has to be located in the "package name" subdirectory of "category" directory; so, for an ebuild to work you have to place it in a directory like /usr/local/portage/app-misc/hello-world/.
 * 3) The ebuild file name has no version listed: Packages have versions, they need to specified in the file name; therefore we would like to create a file like /usr/local/portage/app-misc/hello-world/hello-world-1.0.ebuild.

So, let's create us a minimal ebuild; to keep it simple I will assume you run under root privileges, you can always use sudo if you feel like.

We recursively create the directories and cd into it ($_ recalls the last argument), then we create an ebuild out of the ebuild header which is a necessity if you want it added to the Portage tree.

This won't run yet, it requires us to define a minimal amount of variables, so let's add the following code:

The minimum needed to create an ebuild.

Just one variable? Exactly, it is required that we explicitly state that we won't use SLOTs, which is what "0" means.

We can now install the package to our system by running:

This will manifest (create hashes, to avoid corruption), clean any present temporary work directories and (e)merge the ebuild.

Good, you have just made and tested your first ebuild, it doesn't really do much but it's a good start!

Adding more useful variables
If you take a look at */usr/portage/skel.ebuild* you see a skeleton with a lot of documentation, we will be adding some of these variables and functions to our ebuild as we proceed; so, it seems wise to read over this file as we go. Add the following code blocks to our hello-world-1.0.ebuild:

The council suggests to use the lastest ebuild API.

More information about the EAPI can be found here.

Short, one-line description of our package.

The homepage which the package was found on, for developer reference.

The source code which we will download, hosted by the developer who wrote this documentation.

This is a simple tarball that contains a hello-world shell script that echoes "Hello world!".

Next, we need to specify a license, I hereby tell you I am licensing it under the MIT license so let us specify that.

This package is licensed under the MIT license.

We already did the SLOT, so we can move on to KEYWORDS. The KEYWORDS variable tells you on which arches a package works and also tells you whether it is masked (not listed or explicitly listed with -), untested (~) or stable (listed, but with to character in front of it). Since we can't stabilize ourselves (bugs are to be filed for that), the best we can do for now is list all the arches as untested. All the arches, because they can all run shell scripts.

We hereby confirm that our package runs on all arches, but might not be stable yet.

The other variables define some more specific things (check them out in skel.ebuild) but we won't need them for now; you also see there are functions, but let us see what the ebuild already does by now.

The ebuild should look like this.

We see that it first tries to download our file from a mirror, but since it is not on the Gentoo mirrors it will download it from the SRC_URI we specified.

Then, when it has the file it can create a manifest, this contains a hash of our ebuild and that downloaded file to ensure integrity such that corruption will yield errors.

Then, the emerge process kicks in, the integrity is first checked. Then, we can see the archive we downloaded is automatically unpacked, this is really useful as we don't have to implement this anymore. We can change this behavior by overriding its function (src_unpack), setting some variables or using eclasses whom define such behavior; but we don't need to do that in this case.

As we read further, we see that it tries to prepares, configure, compile and install. In the prepare phase, patches will typically be applied. In the configure and compile phases, the typical build process is done, by default in runs econf (a wrapper for ./configure) and emake (a wrapper for make) when it finds files to handle; but since we use a shell script, we won't need to adjust these phases.

Now, the last step doesn't look quite right; it doesn't install our file yet...

Telling our ebuild where to install our shell script.
In our development manual we can find a page about the phase functions, src_install seems useful for what we want to do. If you click on the src_install link you will see what it does by default for each EAPI as well as some examples. As the default doesn't look good, we'll define our own src_install function. In our function we will be calling other functions to do installation work for us, an overview for them is install functions.

So, we can proceed by adding the following function to our ebuild:

Let's place our shell script in /usr/bin and make it executable

That dobin call will copy hello-world to a temporary build directory (${D}/usr/bin/), make it executable; later on it will be checked by Portage and copied to the live file systems.

Let us try again...

Ah, we see ">>> /usr/bin/hello-world", that looks good!

Let us try...

And there we have it, we just installed a package that echoes "Hello world!".

To be continued!
New sections will get added as new examples get produced...

Here are some ideas for more examples if anyone wants to help writing this article:


 * Expand on the hello world ebuild by adding a src_prepare function where we will patch the package such that the shell script asks for the user's name and uses it instead of world.
 * Usage of variables like $P, $PN, $PV, $PF to ease the maintanance (let's assume a new version was released).
 * Installation of optional documentation (via IUSE="doc").
 * Usage of autotools, cmake and other useful eclasses; in easy to use examples.
 * How to ensure QA, deal with QA warnings and errors and set up FEATURES for more realible ebuild writing.
 * Explain or refer to Sunrise, how to contribute and how to become a developer.

Useful resources

 * Gentoo Development Guide


 * man 5 ebuild


 * repoman metadata && repoman full to check for QA errors, QA keywords are explained in the last part of man repoman.


 * Ebuild Policy