Eclass Writing Guide

This section provides a brief introduction to eclass authoring.

Purpose of Eclasses

An eclass is a collection of code which can be used by more than one ebuild. At the time of writing, all eclasses live in the eclass/ directory in the tree. Roughly speaking, there are three kinds of eclass:

Adding and Updating Eclasses

Before committing a new eclass to the tree, it should be emailed to the gentoo-dev mailing list with a justification and a proposed implementation. Do not skip this step — sometimes a better implementation or an alternative which does not require a new eclass will be suggested.

Before updating eutils or a similar widely used eclass, it is best to email the gentoo-dev list. It may be that your proposed change is broken in a way you had not anticipated, or that there is an existing function which performs the same purpose, or that your function may be better off in its own eclass. If you don't email gentoo-dev first, and end up breaking something, expect to be in a lot of trouble.

When removing a function or changing the API of an eclass, make sure that it doesn't break any ebuilds in the tree, and post a notice to gentoo-dev at least 30 days in advance, preferably with a patch included.

If there is an existing maintainer for an eclass (this is usually the case), you must talk to the maintainer before committing any changes.

It is not usually necessary to email the gentoo-dev list before making changes to a non-general eclass which you maintain. Use common sense here.

A simple way to verify syntax is bash -n foo.eclass.

Removing Eclasses

No longer used eclasses may be removed from the tree, but developers must adhere to the following process:

  1. Make sure that no packages or other eclasses in the tree inherit the eclass.
  2. Send a lastrite message to the gentoo-dev and gentoo-dev-announce mailing-lists, announcing that the not-used eclass will be removed in 30 days.
  3. Add a one line comment to the eclass, saying exactly # @DEAD so that the eclass-manpages package will not attempt to document it.
  4. Wait for the 30-day period to pass, then remove the eclass from the tree.

Documenting Eclasses

Eclasses are documented with comment blocks that follow a special markup syntax. The comment blocks are separated by blank lines and each block documents an individual element of an eclass.

Documentation tags for various eclass elements are explained in their respective sections below. Common to all the tags that accept multiline freetext, the @CODE tag should be used when necessary to create unformatted code chunks (such as example code) by placing the tag at the beginning and the end.

Basic Eclass Format

An eclass is a bash script which is sourced within the ebuild environment. Files should be a simple text file with a .eclass extension. Allowed characters in the filename are lowercase letters, the digits 0-9, hyphens, underscores and dots. Eclasses are not intrinsically versioned.

Eclasses should start with the standard ebuild header, along with comments explaining the maintainer and purpose of the eclass, and any other relevant documentation. Eclass documentation block should be the first documentation block to appear in the eclass. The following table summarizes the available documentation tags:

tag optional? arguments description
@ECLASS: NO Name of the eclass being documented. Documents various information about the eclass. Must appear as the first tag in the comment block.
@MAINTAINER: NO One or more name and email pairs. List of maintainers for the eclass to be contacted. One line per maintainer. Must start on a newline after the tag.
@AUTHOR: YES One or more name and email pairs. List of authors for the eclass. One line per author. Must start on a newline after the tag.
@BUGREPORTS: YES Multiline freetext. Describes how bugs related to this eclass should be reported.
@VCSURL: YES A URI string. Points to the URL of the VCS that contains the eclass source.
@BLURB: NO Single line freetext. Contains a short description for the eclass. Must be on the same line with the tag.
@DESCRIPTION: YES Multiline freetext. Long description for the eclass.
@EXAMPLE: YES Multiline freetext. Examples that illustrate various uses of this eclass.

Eclass Variables

Top level variables may be defined as for ebuilds. If any USE flags are used, IUSE must be set. The KEYWORDS variable must not be set in an eclass.

You should document the meaning, usage, and default value of every variable in your eclass. The tags available for documenting eclass variables are as follows:

tag optional? arguments description
@ECLASS-VARIABLE: NO Name of the eclass variable to which the documentation applies. This tag applies to eclass specific variables that affect the default behavior of the eclass. Read-only variables, which are exported by the eclass for developer use, are also documented with this tag. Must appear as the first tag in the comment block.
@DEFAULT_UNSET YES Indicates that this variable is unset by default if not set by the developer.
@INTERNAL YES Indicates that the variable is internal to the eclass.
@REQUIRED YES Indicates that this variable must be set by the developer.
@DESCRIPTION: NO Multiline freetext. Long description for the eclass variable.

Eclass Functions

Eclasses may define functions. These functions will be visible to anything which inherits the eclass.

You should document the purpose, arguments, usage, and return value of every function in your eclass. The standard tags available for documentation are:

tag optional? arguments description
@FUNCTION: NO Name of the function to which the documentation block applies. Documents information about an eclass function such as its calling convention etc. Must appear as the first tag in the comment block.
@USAGE: NO List of required and optional arguments to the function. List of arguments that the eclass function accepts, specified in the following syntax: <Required arguments> [Optional arguments]
@RETURN: * Return value of the function.

Description for the value returned by the function.

*: Not optional for functions that return a value.

@MAINTAINER: YES Multiline freetext. List of contacts for the eclass function. One line per maintainer. Must start on a newline after the tag.
@INTERNAL YES Indicates that the function is internal to the eclass and should not be called from outside.
@DESCRIPTION: * Multiline freetext.

Long description for the eclass function.

*: Not optional if RETURN: is absent.

Eclass Function Variables

Eclass functions may make use of variables just like any other bash function. Special function-specific variables should be documented using the following tags:

tag optional? arguments description
@VARIABLE: NO Name of the function-specific variable to which the documentation applies. This tag applies to variables consumed by specific functions of the eclass. They are in effect only when the specific function is called.
@DEFAULT_UNSET YES Indicates that this variable is unset by default if not set by the developer.
@INTERNAL YES Indicates that the variable is internal to the eclass function.
@REQUIRED YES Indicates that this variable must be set by the developer.
@DESCRIPTION: NO Multiline freetext. Long description for the function variable.

Simple Common Functions Eclass Example

As an example, the following eclass was written to illustrate a better way of installing OSX application files during a discussion on this subject. It defines a single function, domacosapp.

# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# @ECLASS: macosapp.eclass
# @MAINTAINER:
# Ciaran McCreesh <ciaranm@gentoo.org>
# @BLURB: install macos .app files to the relevant location.

# @FUNCTION: domacosapp
# @USAGE: <app-file> [new-file]
# @DESCRIPTION:
# Install the given .app file into the appropriate location. If
# [new-file] is given, it will be used as the new (installed) name of
# the file. Otherwise <app-file> is installed as-is.
domacosapp() {
    [[ -z "${1}" ]] && die "usage: domacosapp <file> [new file]"
    if use ppc-macos ; then
        insinto /Applications
        newins "$1" "${2:-${1}}" || die "Failed to install ${1}"
    fi
}

Export Functions

An eclass may provide default implementations for any of the standard ebuild functions (src_unpack, pkg_postinst etc). This can be done either as a simple function definition (which is not multiple eclass friendly) or using EXPORT_FUNCTIONS. Functions given to EXPORT_FUNCTIONS are implemented as normal, but have their name prefixed with ${ECLASS}_.

If multiple eclasses export the same function, the latest (inherited last) defined version wins. If an ebuild defines a function that is exported, this gets priority over any eclass version. This can be used to override eclass-defined defaults — for example, say we had fnord.eclass:

EXPORT_FUNCTIONS src_compile

fnord_src_compile() {
    do_stuff || die
}

Then an ebuild could do this:

inherit fnord.eclass

src_compile() {
    do_pre_stuff || die
    fnord_src_compile
    do_post_stuff || die
}

Simple Build System Eclass Example

A simple eclass which defines a number of functions and a default src_compile for the (hypothetical) jmake build system might look something like the following:

# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# @ECLASS: jmake.eclass
# @MAINTAINER:
# Gentoo Devmanual Project <devmanual@gentoo.org>
# @AUTHOR:
# Ciaran McCreesh <ciaranm@gentoo.org>
# @BLURB: Demonstrate a simple build system eclass.
# @DESCRIPTION:
# Demonstrates EXPORT_FUNCTIONS and defines simple wrappers for the
# (hypothetical) jmake build system and a default src_compile.

EXPORT_FUNCTIONS src_compile

DEPEND=">=sys-devel/jmake-2"

# @FUNCTION: jmake-configure
# @USAGE: [additional-args]
# @DESCRIPTION:
# Passes all arguments through to the appropriate "jmake configure"
# command.
jmake-configure() {
    jmake configure --prefix=/usr "$@"
}

# @FUNCTION: jmake-build
# @USAGE: [additional-args]
# @DESCRIPTION:
# First builds all dependencies, and then passes through its arguments
# to the appropriate "jmake build" command.
jmake-build() {
    jmake dep && jmake build "$@"
}

# @FUNCTION: jmake-src_compile
# @DESCRIPTION:
# Calls jmake-configure() and jmake-build() to compile a jmake project.
jmake_src_compile() {
    jmake-configure || die "configure failed"
    jmake-build || die "build failed"
}

Handling incorrect usage of an eclass

Sometimes an eclass is used incorrectly by an ebuild and the eclass knows it is being used incorrectly- the common example is an eclass that only works with a specific set of EAPIs, but is being accessed inherited by an ebuild with a different EAPI. In those cases, used sparingly as a last resort, it is allowed for an eclass to invoke die from the global scope. For example:

# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# @ECLASS: eapi-die.eclass
# @MAINTAINER:
# Gentoo Devmanual Project <devmanual@gentoo.org>
# @BLURB: Calls die when used with an invalid EAPI.

case ${EAPI:-0} in
  0) die "this eclass doesn't support EAPI 0" ;;
  *) ;;
esac