[ << ]
[ < ]
[ Home ]
[ > ]
[ >> ]
2. Eclass HOWTO
Content:
2.a. Introduction to eclasses
The idea behind eclasses
eclasses are modules of shared code. They are written in
bash and have the same syntax as ordinary ebuilds, and are
sourced ('inherited') by ebuilds and other eclasses, to
provide default settings and functionality across many similar
ebuilds.
This is used to ensure maximum code reuse among similar
ebuilds.
This first chapter shows briefly how to write an eclass
incorporating the standard tricks and techniques used in
existing eclasses.
An example of a simple eclass
Here is a fictive sourceforge.eclass, designed to provide
homepage and download locations to sourceforge.net-hosted
projects:
Code Listing 1.1: Example: sourceforge.eclass |
# Copyright 2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License, v2 or later
# Author Dan Armak <danarmak@gentoo.org>
# $Header: $
# This eclass sets ${HOMEPAGE} and ${SRC_URI} to the standard values for
# sourceforge.net - hosted projects.
HOMEPAGE="http://${PN}.sourceforge.net/"
SRC_URI="http://download.sourceforge.net/${PN}/${P}.tar.gz" |
The first four lines are headers, just like those in any
ebuild. The next two lines are a short description of the
eclass. The rest of the code does the actual work - setting
SRC_URI and HOMEPAGE.
Most eclasses go beyond setting variables and providing
helper functions; they contain default versions of the special
ebuild functions (src_unpack, src_compile and so on). Before
writing a default function in an eclass, you should be aware
of the default functions already contained in ebuild.sh. They
are what gets executed if you don't put some function in your
ebuild (not even via an eclass); the default src_unpack() is
often used. If you haven't yet, go and look at the default
implementations in ebuild.sh.
This is all you need to know to actually write
eclasses. Put your new eclass
in ${PORTDIR}/eclass/, and put this line at the
beginning of your ebuild:
Code Listing 1.2: How to inherit eclasses |
inherit sourceforge |
The contents of the eclass will be sourced at this
point. Remember that any variables or functions defined in the
eclass can be overridden in the ebuild, whose code executes
after any eclasses. Therefore, you should try to put as much
default settings and common code in your eclass as
possible. Any nonstandard settings and modifications can then
be put into the ebuild.
Oh, and you can inherit several eclasses at the same time
by saying:
Code Listing 1.3: Inheriting multiple eclasses |
inherit eclass1 eclass2 [...] |
...but watch their order! Remember, eclasses can inherit
one another and override each other's settings, so you should
be careful when dealing with multiple eclasses that might
influence one another.
We will now go over all the tricks of eclass writing,
before moving on to the actual eclasses in portage.
inherit()
This function lives in ebuild.sh and handles inheriting
(sourcing) of eclasses. It is called with a list of eclass
names to inherit: inherit <eclass1> [eclass2
eclass3...].
Besides actually sourcing the eclass files, it sets the
ECLASS and INHERITED variables which are used by portage for
caching eclass modification timestamps. The INHERITED variable
might be of use in writing eclasses: it contains a list of all
eclasses inherited (sourced) up to this point, in order. Thus
an eclass can use it to determine whether or not it was called
from some other eclass.
EXPORT_FUNCTIONS
A good eclass's predefined functions can often be used
as-is; the ebuild will then contain very little code (which is
good). Sometimes, though, the eclass functions won't do
exactly what you need. You could write a new function in your
ebuild, overriding the function definition from the
eclass. However, this would minimize the benefit of code
reuse. So we try to 'extend' the eclass functions instead.
Suppose you want to extend src_compile(). You can write an
src_compile() definition in your ebuild, which would only
include the parts missing from the eclass src_compile(). You
would then call the eclass src_compile() from within the code
of your custom function.
However, if you create a new function called src_compile(),
bash will forget about the old one and you won't be able to
call it! That's where the EXPORT_FUNCTIONS macro comes into
play.
Let's look at another problem for a moment. Suppose that
foo.eclass and bar.eclass both define src_compile(). If you
inherit both foo and bar you'll get a different src_compile()
depending on the order in which you inherit them. That's ok;
you're supposed to keep track of your inheritance order. But
you may want to call either of the two src_compile()s
explicitly.
So, every eclass adds to the functions that it defines a
prefix. For example, foo.eclass will define a function called
foo_src_compile(), and bar.eclass will define a
bar_src_compile(). That way, the ebuild can call either
function and know what it'll get.
However, we also want to have some default function called
just src_compile(), or the ebuild will have to define one. The
EXPORT_FUCTIONS macro solves both this problem and the one
presented earlier.
Code Listing 1.4: EXPORT_FUNCTIONS() (from ebuild.sh) |
EXPORT_FUNCTIONS() {
while [ "$1" ]; do
eval "$1() { ${ECLASS}_$1 ; }" > /dev/null
shift
done
} |
The inherit() function sets ${ECLASS} to the eclass's name
before sourcing it. The eclass, at its end, calls
EXPORT_FUNCTIONS(), passing as parameters the list of default
functions it provides. For example, if you call
Code Listing 1.5: EXPORT_FUNCTIONS call example |
EXPORT_FUNCTIONS src_compile src_install |
then EXPORT_FUNCTIONS will call eval() on the following string:
Code Listing 1.6: EXPORT_FUNCTIONS result |
src_compile() { foo_src_compile ; }
src_install() { foo_src_install ; } |
Now, whichever eclass is inherited last will define the
default src_compile() function, but both functions can be
directly called by the ebuild if needed.
You can also extend the default src_compile() function by
calling the eclass's function from within your own
function. You then have to use the default function's full
name of foo_src_compile. An example:
Code Listing 1.7: Extending eclass-provided default functions in your ebuild |
#in foo.eclass:
foo_src_compile() {
[default code here]
}
EXPORT_FUNCTIONS src_compile
#end eclass code
#in an ebuild:
inherit foo
src_compile() {
[custom code here]
foo_src_compile
[more custom code]
} |
Function sections
Sometimes, extending default functions by having code
execute before and after isn't flexible enough. When dealing
with long, complex functions, you often want to have your
custom code run in the middle of those functions.
Function sections provide for greater flexibility required
here. They break the functions down into sections and allow
you to execute code between any two sections.
The implementation is simple. Let's take as an example the
src_compile() function from base.eclass. (Note: it no longer
exists, but it's a good example :-) It looks like this:
Code Listing 1.8: Example from original base.eclass |
base_src_compile() {
econf || die
emake || die
} |
Here is the same function, divided into sections:
Code Listing 1.9: The same function divided into sections. |
base_src_compile() {
[ -z "$1" ] && base_src_compile all
while [ "$1" ]; do
case $1 in
configure)
./configure || die;;
make)
emake || die;;
all)
base_src_compile configure make;;
esac
shift
done
} |
The code has been divided into two
sections: configure and make. In our simple
example, they correspond to the two commands in the original
function.
In the center of the new function is a
while;case...esac;shift;done block. This block matches the
parameters to the function with the defined section names and
executes the corresponding lines of code.
The special case all calls the same function
recursively with a list of sections in order. It's up to the
eclass's author to maintain this list.
The line before the block says that a call without
parameters should be treated the same as a call with the
single parameter all. As you see, this function
recurses a lot. Note, however, that the
call base_src_compile configure all make is also legal;
it will execute base_src_compile configure configure make
make.
Now, in your ebuild (or eclass) that inherits from
base.eclass, you get the stub function src_compile which calls
base_src_compile without parameters. This makes
base_src_compile execute all, that is, all its
sections. You can leave it as-is. If you wish to extend it,
you can define a new src_compile and call base_src_compile a
section at a time:
Code Listing 1.10: Using the sectioned src_compile() |
src_compile() {
run_my_code1
base_src_compile configure
run_my_code2
base_src_compile make
run_my_code3
} |
As you can see, the function sections add flexibility since
you can now insert code between the two sections, as well as
run them in a different order or run only some of the sections
provided. This makes for greater code reuse overall.
The debug-print-* functions
These are more functions provided by ebuild.sh. They add
verbose debug output facilities to eclasses, to allow you to
trace their execution more easily without having to read the
long traces provided by the bash debug mode. All my eclasses
call these functions a lot.
debug-print() simply prints all its parameters with the
'debug:' prefix. It is called whenever there's something
interesting to put in the debug log.
debug-print-function() prints 'debug: entering function $1,
parameters: $2 [$3 ....] It is called at the beginning of a
function.
debug-print-section() prints 'debug: now in section $1'. It
is called at the beginning of a function's section.
The debug output normally goes into
${T}/eclass-debug.log. You can set the ECLASS_DEBUG_OUTPUT
env. variable (in make.globals/conf or in the environment) and
output will be sent there as well. You can also set it to the
special value 'on', which echoes output to stdout together
with the other emerge messages.
Let's add typical debug output statements to our sample
function:
Code Listing 1.11: Adding debug statements |
base_src_compile() {
debug-print-function
[ -z "$1" ] && base_src_compile all
while [ "$1" ]; do
case $1 in
configure)
debug-print-section configure
./configure || die;;
make)
debug-print-section make
make || die;;
all)
debug-print-section all
base_src_compile configure make;;
esac
shift
done
debug-print "${FUNCNAME}: result is ${RESULT}"
} |
${FUNCNAME} is a bash built-in that returns the current
function's name.
2.b. Existing eclasses
eclass-manpages
You can emerge app-portage/eclass-manpages for documentation
on existing eclasses
[ << ]
[ < ]
[ Home ]
[ > ]
[ >> ]
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-2.5 license. The Gentoo Name and Logo Usage Guidelines apply.
|