exheres-0 is an experimental, fluid EAPI and tree layout (in theory, the two concepts are independent, but the only place using one without the other is the Paludis test suite). When we stop breaking things we’ll make an EAPI exheres-1 and carry on using exheres-0 for experiments.
metadata/
about.conf
accounts/
groups/
*.conf
users/
*.conf
categories.conf
layout.conf
options/
descriptions/
options.conf
*.conf
repository_mask.conf
packages/
cat-foo/
exlibs/
per-category.exlib
pkg-foo/
pkg-foo-1.23.exheres-0
per-package.exlib
exlibs/
foo.exlib
Repositories expose optional and required metadata to package managers. The metadata is stored in the metadata sub-directory.
about.conf: Provide basic information to the package manager. (key = value)
summary: A short summary.
description: A longer description.
homepage: The home page.
owner: The owner: Real Name <valid email address>.
status: One of the following values:
core: Official topic repository.experimental: Official topic repository which is considered experimental.dev: Official repository from an exherbo developer.third-party: Unofficial third-party repository.Some packages need to depend on a specific group or user. This can be achieved by adding group/<group's
name> or user/<user's name> to DEPENDENCIES (Note: in “build:” or “build+run:” if it’s needed by the exheres!). For both groups and users, a corresponding config file needs to be added, <group's
name>.conf or <user's name>.conf respectively.
accounts/groups/*.conf: Installable groups. (key = value)
preferred_gid: Preferred group ID. (optional)accounts/users/*.conf: Installable users. (key = value)
gecos: Information about the user. (required field, see passwd(5))preferred_uid: Preferred user ID. (optional)shell: Path to the login shell. (optional)home: Path to the home directory. (optional)extra_groups: List of extra groups. (optional)primary_group: The primary group. (optional)If the primary_group contains a group which is also tracked via accounts, user/<user's name> will have a dependency on that group.
categories.conf: Lists categories which are not provided by master repositories. This will be obsolete in the future, as we want to remove categories.
category1
category2
...
layout.conf: Provide extended information to the package manager. (key = value)
layout: Defaults to exheres on exherbo.profile_layout: Default to exheres on exherbo.eapi_when_unknown: Default to exheres-0 on exherbo.eapi_when_unspecified: Default to exheres-0 on exherbo.profile_eapi_when_unspecified: Defaults to exheres-0 on exherbo.masters: A list of master repositories (see Repository Masters).options/descriptions/
options.conf: Describes global options for installable packages. For local options refer to Annotations in MYOPTIONS.
*.conf: Describes sub-options (e.g. descriptions for the linguas suboption are in linguas.conf) for installable packages.
option - description
...
repository_mask.conf: Lists masked packages with mask reasons.
# Name (Date)
# Reason
cat/foo[>=2.7_alpha]
...
A master repository which is listed in metadata/layout.conf in your repository allows you to:
masters for that reason.Master repositories are not inherited from masters. So if you need an exlib from ::foo which needs another exlib from ::bar then you need to list both foo and bar in masters.
Keep in mind that you should not specify masters if you just depend on a package in that repository. The unavailable repositories track that and will tell users to add the repository if they need the package.
What Gentoo calls use flags we call options. We may support non-boolean options at some point if there are good use cases demonstrated. USE_EXPAND is called SUBOPTIONS, and uses a colon (e.g. video_cards:intel).
Keywords has become platforms. We’re still using arch and ~arch, for now. We don’t automatically inject PLATFORM into MYOPTIONS; platforms are regular SUBOPTIONS and should be managed as such.
Various things that were merely QA notices for ebuilds are strict errors.
Exheres packages may use all features of GNU bash 4.0, and may assume that the extglob and the globstar shell options are set. The locale is preset to C.
SLOTDOWNLOADS (like SRC_URI; see below)RESTRICT (for now)HOMEPAGELICENCESSUMMARY (short, like DESCRIPTION is in 0-based EAPIs)DESCRIPTION (long, optional)PLATFORMS (like KEYWORDS)DEPENDENCIES (see below)MYOPTIONS (like IUSE, but much more useful, see below)BUGS_TO (see below)REMOTE_IDS (see below)UPSTREAM_CHANGELOG, UPSTREAM_RELEASE_NOTES, UPSTREAM_DOCUMENTATION (see below)EAPI: The exheres format in use, (comes from the extension, don’t change it yourself).REPODIR: The path to the repository, (like PORTDIR).FETCHEDDIR: The path to where fetched files, enabled things in DOWNLOADS, get installed, (like DISTDIR).FILES: Path to the files/ dir for patches and small files used by the exheres, (like FILESDIR).ARCHIVES: Names of the fetched archives in FETCHEDDIR, (like A).WORKBASE: Path to the base work dir, (like WORKDIR).WORK: Path to the work dir where the primary archive typically gets unpacked, (like S). src_* phases after src_unpack start in this directory if it exists. src_prepare, src_compile and src_install die if they’re defined and this dir does not exist.IMAGE: Path to the image dir where files get installed before merge, (like D). The contents of this dir gets merged to ROOT during the merge phase.TEMP: Path to a temporary directory, (like T).AA, ARCH, KVPROVIDE (and no old style virtuals)REPLACING_IDS (see below)REPLACED_BY_ID (see below)ROOT: The absolute path to the root directory in which the package is to be merged. pkg_* phases must not try to touch anything outside this directory. ROOT is invalid outside pkg_* phases.PNV replaces P, package name and version, e.g. foo-1.PNVR replaces PF, package name, version and revision, e.g. foo-1-r3.PN, package name, e.g. foo.PV, package version, e.g. 1.PVR, package version and revision, e.g. 1-r3.PR, package revision, e.g. r3. A package named cat/foo-1 will have PR be r0.CATEGORY (for now)Not fully implemented on the package manager side.
DEPENDENCIES="
build+run:
foo/bar
run:
foo/baz
post:
foo/monkey
"
Labels affect all following atoms inside the current ( ) block, but not any higher level blocks. The default is build+run. So:
DEPENDENCIES="
blah? ( cat/build-and-run )
foo? (
cat/build-and-run
build:
cat/build-only
run:
cat/run-only
bar? (
cat/run-only
post:
cat/post-only
)
cat/run-only-again
)
cat/build-and-run"
The full list of labels is:
build: Dependency during build for the unpack, prepare, configure, compile and install phases.built-against: Dependency for things that need to build against me (has a build dependency on me).fetch: Depency for the src_fetch_extra phase.install: Dependency during install for the setup, preinst, postinst, prerm and postrm phases.post: Like run except may be installed after me to break a cycle.recommendation: Optional run-time dependency which is taken by default.run: Run-time dependency.suggestion: Optional run-time dependency which is not taken by default.test: Dependency for the test phase.test-expensive: Dependency for the test-expensive phase.Not all labels are fully implemented. For example, fetch and install are currently identical to build. Optional dependencies (recommendations and suggestions) should be accompanied by a description annotation.
The paludis client uses the old resolver, which doesn’t support test and test-expensive. When using paludis these labels will be treated as build dependencies.
Slot dependencies:
foo/bar:2 or foo/bar:2[>=2.1]foo/bar:= or foo/bar:=[>=2.1] . Means “any matching version, but at runtime I need the slot against which I was compiled.” (Strictly, I need the slot of the best matching version that was there at compile time.)foo/bar:* or foo/bar:*[>=2.1] . Means “any matching version, and I don’t mind if you change the slots available later on.Square brackets (these go after slot dependencies, so foo/bar:slot[bracket]):
Multiple version requirements: foo/bar[>=1.2&<2] or foo/bar[=1.1|=1.2|=1.3] . Do not mix with prefix-suffix requirements. Using only a single requirement is OK. Mixing | and & is forbidden. (Version requirements go before option deps, so foo/bar[>=1.0][baz]).
Option deps: foo/bar[opt] and foo/bar[-opt]. A dependency on several options: foo/bar[baz][quux]. We found that we had lots of code like opt? ( foo/bar[opt] ) !opt? (
foo/bar[-opt] ), so there are shortcuts:
foo/bar[opt] Enabledfoo/bar[opt=] Equal to my valuefoo/bar[opt!=] Not equal to my valuefoo/bar[opt?] Enabled if I’m enabledfoo/bar[opt!?] Enabled if I’m disabledfoo/bar[-opt] Disabledfoo/bar[-opt?] Disabled if I’m enabledfoo/bar[-opt!?] Disabled if I’m disabledIn any of the variants, opt may optionally end in a (+) or a (-) to indicate that, when matching the spec against a package that does not have the flag, that it should be assumed to be enabled or disabled respectively. If neither is specified, it is illegal for the remainder of the spec to match any such package. The (+) or (-) goes before the =, !=, ? or !?, if both are present.
Operators:
~> means the same as it does for Gems. For example [~>1.2.3] is equivalent to [>=1.2.3&<1.3].=...* is a component-wise prefix comparison, not stringwise.~ means equal to for package version and greater than or equal to the specified package revision.Additionally there are =, >, >=, < and <= operators.
Blockers:
Adding a blocker to a package will prevent that the package and the blocked package are installed together. The reason for blockers should be explained using a description annotation so that users can find out easily why they block.
DEPENDENCIES="
build+run:
!foo/bar [[ description = [ foo/bar and this package both install /usr/bin/quux ] ]]
"
In general, blockers should be used sparsely because they’re annoying for users to deal with. For example, instead of making all packages that install /usr/bin/sendmail block, we handle these using alternatives.
In the future we’ll add Annotations to blockers, to allow paludis to safely resolve blockers automatically where appropriate.
DOWNLOADS has two new things. First, labels:
DOWNLOADS="
like-primaryuri.tar.bz2
manual: fetch-restricted-stuff.tar.bz2
listed-only: will-not-look-on-mirrors.tar.bz2
local-only: only-on-local-mirrors.tar.bz2
"
Supported values are:
mirrors-firstmirrors-onlylisted-onlylisted-firstlocal-onlymanualSecond, arrows:
DOWNLOADS="http://sucky-upstream/download/foo/1.2/foo.tar.bz2 -> foo-1.2.tar.bz2"
When consulting the listed URI (which can be a mirror://) the filename is used. When consulting mirrors and for the saved download location, the value on the right of the arrow is used.
Options can be used to make a download conditional:
DOWNLOADS="platform:amd64? ( amd64-only.tar.xz )"
Annotations are another new dep-like toy. They don’t convey any critical information for DEPENDENCIES (as in, a compliant package manager need do nothing more than parse the contents, and an annotation-using package manager can ignore any particular key it wants). They look like this:
DEPENDENCIES="
build+run:
zoo/monkey [[
description = [ it needs a monkey ]
url = [ http://explain.exherbo.org/?zoo-monkey ]
]]
!zoo/clown [[
description = [ clowns will murder us in our sleep ]
url = [ http://explain.exherbo.org/?clowns-are-evil ]
resolution = uninstall-blocked-after
]]
suggestion:
zoo/snake [[
description = [ otherwise we can't strangle things ]
]]
"
Annotations start with [[ and end with ]]. Inside, they’re key = value or key = [ value that can
contain spaces ]. Note that whitespace is mandatory everywhere. Also note that currently the only ‘quote’ we allow is [ ] and you can’t use things that look like use? flags, ( dependencies ) etc., but if this proves too restrictive we might change it.
Annotation keys we recognise currently are:
description, which we might show to an end user in -pi.
url, for more information for an end user in -pi.
note, for more developer-oriented information. Shows up in -qD, but not -pi.
resolution, for blockers only. We don’t use this, but if we did:
manualuninstall-blocked-after would suggest uninstalling the blocked package after we are merged (you’re allowed to file collide if you do this).uninstall-blocked-before would suggest uninstalling the blocked package before we are merged (only use if you really really have to, and most definitely not just for collisions).upgrade-blocked-before would suggest upgrading the blocked package before we are mergedAnnotations are not limited to package and block dep specs. You can put them after other things too:
DEPENDENCIES="
build+run: [[ here = [ would apply to the labels ] ]]
foo? (
|| (
cat/one
cat/two
) [[ here = [ would apply to the || block ] ]]
) [[ here = [ would apply to the foo? block ] ]]
"
DOWNLOADS="
mirror://foo/${PNV}.tar.bz2 [[ here = [ would apply to the URI ] ]]
"
but we only use those for MYOPTIONS currently.
Don’t overdo annotations. Blockers almost always benefit from having them. So do suggestions and recommendations. Normal deps, not so much, although sometimes a little [[ note = [ configure.ac says
2.0, but we get runtime terminal corruption unless we use at least 2.3 ] ]] might not go amiss.
MYOPTIONS is a bit like IUSE, except more powerful. All flags have to be listed in MYOPTIONS, even SUBOPTIONS flags, and there is no special ARCH handling. Labels are used to select the active suboption. For example:
MYOPTIONS="
foo
bar
baz
linguas:
en
fr
platform:
x86
"
You need to list any platforms that will be used in dependencies or queried in any way; there is no need to list a platform simply because a package is keyworded on that platform.
Local flag descriptions, and more detailed descriptions for flags with a global meaning, are specified via annotations:
MYOPTIONS="
imlib2 [[ description = [ Use imlib2 to render icons ] ]]
"
Do not start your description with “enables support for”. This is superfluous. Do not describe foo as “Support for foo” unless even Wulf’s dead grandmother knows what foo is; you can at least manage “Support for the foo image format”.
Flags can also have requirements:
MYOPTIONS="
foo
bar
baz [[ requires = [ foo -bar ] ]]
linguas:
en
en_GB [[ requires = [ linguas: en ] ]]
"
These are checked just before pkg_pretend is called (and even if they fail, pkg_pretend will still be called). Theoretically you can override pkg_bad_options (being sure to call default to get the standard description displayed) to get improved error messages, but this may not be a good idea.
The requires annotation can be applied to an all-of block. This is a shortcut for applying the requirement to each child (this is special behaviour – annotations do not usually get applied to children when on a block):
MYOPTIONS="
X
python
(
gtk [[ requires = python ]]
qt
motif
) [[ requires = X ]]
"
Here, gtk requires both X and python (but we discourage this style – see below).
All-of blocks also support a number-selected annotation, which can have the value at-least-one, at-most-one or exactly-one:
MYOPTIONS="
X
python
(
gtk [[ requires = python ]]
qt
motif
) [[
number-selected = at-most-one
requires = X
]]
"
This can be done conditionally. Make sure you apply the annotations to an all-of block, not the conditional block. Any requirements inside a conditional block are tested only if the condition is met; any flags listed inside a conditional block are always considered part of MYOPTIONS, but the conditional flag itself must be explicitly listed beforehand.
MYOPTIONS="
X
python
(
gtk [[ requires = python ]]
qt
motif
) [[ requires = X ]]
X? ( ( gtk qt motif ) [[ number-selected = exactly-one ]] )
"
Negative flags are allowed, both as a requires value and inside an all-of block. Use sparingly.
In terms of style, it’s clearest to list all relevant flags first, along with any descriptions, and then go through and apply any requirements, avoiding grouping requirements together. So:
MYOPTIONS="
X [[ description = [ Build a graphical user interface ] ]]
python [[ description = [ Generate bindings for the Python programming language ] ]]
gtk
qt
motif
gtk [[ requires = python ]]
( gtk qt motif ) [[ requires = X ]]
X? ( ( gtk qt motif ) [[ number-selected = exactly-one ]] )
"
Currently BUGS_TO should look like this:
BUGS_TO="foo@exherbo.org python? ( bar@exherbo.org )"
This will probably change.
The REMOTE_IDS function provides a pointer to this package in a remote database. It is specified as a list of database:index tokens:
REMOTE_IDS="freshmeat:blah vim:1234"
A non-definitive list of remote databases:
cpan: the index is the project’s CPAN project name.freshmeat: the index is the project’s Freshmeat project name.launchpad: the index is the project’s Launchpad project name.pypi: the index is the project’s Python Package Index project name.rubyforge: the index is the project’s RubyForge project name.sourceforge: the index is the project’s Sourceforge project name.vim: the index is the project’s Vim Scripts script ID (number).When adding new remote databases, it is important that given the database name and index, a client can find the information being pointed to without any searching.
UPSTREAM_CHANGELOG contains URLs for upstream changelogs:
UPSTREAM_CHANGELOG="http://blah/changelog.txt [[ lang = en ]]"
UPSTREAM_DOCUMENTATION="
${HOMEPAGE}/doc/admin/ [[ lang = en description = [ Administration guide ] ]]
${HOMEPAGE}/doc/user/ [[ lang = en description = [ User manual ] ]]
"
Likewise, UPSTREAM_DOCUMENTATION contains documentation URLs and UPSTREAM_RELEASE_NOTES contains release notes (e.g. NEWS files). These are all for user use.
REPLACING_IDS is a whitespace-separated list of ids (e.g. cat/pkg-1:0::installed) that are being replaced (uninstalled or overwritten) as a result of this install. REPLACING_IDS is defined in pkg_preinst and pkg_postinst. In addition it may be defined in pkg_pretend and pkg_setup, but you should to take care to handle binary package creation and installation correctly if you need to use it in these phases.
REPLACED_BY_ID is a single id that is replacing this package, if it is being replaced as part of an install, or empty otherwise. REPLACED_BY_ID is defined in pkg_prerm and pkg_postrm.
The default phase functions are named default_src_blah, and you’re allowed to (and encouraged to) call them if you’re just adding functionality. But rather than calling default_src_blah, you can just call the special default function that’ll look at what phase we’re in and act accordingly.
Do not use the default functions if it involves doing something weird. Especially do not use the default functions if it means screwing around with the DEFAULT_ variables. If you are not simply setting the DEFAULT_ variables statically in global scope, you should write your own functions instead.
Phases are listed in running order. The pkg_config and pkg_info phases are separate user invoked phases.
Upgrade/reinstall/downgrade of a package:
New refers to the newly installed exheres. Old refers to the one that’s being replaced.
pkg_preinst()merge phasepkg_prerm()unmerge phasepkg_postrm()pkg_postinst()Run in the sandbox and with userpriv. Called for every package after a paludis --pretend --install or paludis --install (but not currently for binaries – not sure how we’ll handle those yet). You can die in here to tell the user to change config things etc. (but use option deps and the like if possible instead).
default_pkg_pretend()
{
:
}
Run in the sandbox and with userpriv if RESTRICT=fetch is enabled.
default_pkg_nofetch()
{
[[ -z "${ARCHIVES}" ]] && return
local f g=
for f in ${ARCHIVES} ; do
[[ -f "${FETCHEDDIR}/${ARCHIVES}" ]] && continue
if [[ -z "${g}" ]] ; then
echo "The following files could not be fetched automatically for ${PN}:"
g=no
fi
echo "* ${f}"
done
}
Run in the sandbox and with userpriv.
default_src_fetch_extra()
{
:
}
Run in the sandbox.
default_pkg_setup()
{
:
}
Run in the sandbox and with userpriv.
default_src_unpack()
{
[[ -n "${ARCHIVES}" ]] && unpack --if-compressed ${ARCHIVES}
}
Run in the sandbox and with userpriv. The DEFAULT_SRC_PREPARE_PATCHES array, if set, should be set in global scope and mustn’t be set dynamically. If you’re doing anything complicated, write your own src_prepare. The variable is just for the easy cases.
default_src_prepare()
{
if [[ -n "${DEFAULT_SRC_PREPARE_PATCHES[@]}" ]]; then
expatch "${DEFAULT_SRC_PREPARE_PATCHES[@]}"
fi
}
Run in the sandbox and with userpriv. Again, DEFAULT_SRC_CONFIGURE_* is just for the easy cases.
default_src_configure()
{
if [[ -x ${ECONF_SOURCE:-.}/configure ]] ; then
econf \
"${DEFAULT_SRC_CONFIGURE_PARAMS[@]}" \
$(for s in "${DEFAULT_SRC_CONFIGURE_OPTION_ENABLES}" ; do \
option_enable ${s} ; \
done ) \
$(for s in "${DEFAULT_SRC_CONFIGURE_OPTION_WITHS}" ; do \
option_with ${s} ; \
done )
fi
}
Run in the sandbox and with userpriv. DEFAULT_SRC_COMPILE_PARAMS is passed on to emake.
default_src_compile()
{
if [[ -f Makefile ]] || [[ -f makefile ]] || [[ -f GNUmakefile ]] ; then
emake "${DEFAULT_SRC_COMPILE_PARAMS[@]}"
fi
}
Run in the sandbox and with userpriv. Should be considered mandatory.
default_src_test()
{
if [[ -f Makefile ]] || [[ -f GNUmakefile ]] || [[ -f makefile ]] ; then
echo "Makefile found, looking for potential test targets"
if make -j1 -n "${DEFAULT_SRC_TEST_PARAMS[@]}" check ; then
echo "Found check target"
emake "${DEFAULT_SRC_TEST_PARAMS[@]}" check
elif make -j1 -n "${DEFAULT_SRC_TEST_PARAMS[@]}" test ; then
echo "Found test target"
emake "${DEFAULT_SRC_TEST_PARAMS[@]} test
else
echo "No check or test target, skipping tests"
fi
else
echo "No Makefile, skipping tests"
fi
}
Run in the sandbox and with userpriv. Used to run testsuites that takes a very long time or are otherwise expensive using a huge amount of diskspace, memory or other resource.
default_src_test_expensive()
{
:
}
Run in the sandbox.
This default function is fairly complex so it deserves a longer explanation. The first part simply looks for a Makefile and, if one is found, uses the install target with DESTDIR="${IMAGE}. It dies if an existing Makefile is missing an install target and it supports one variable for adding extra parameters for emake install. The emagicdocs function, however, tries to identify (case-insensitively) documents that are common in lots of packages and installs them by means of dodoc. It supports three variables for adding extra docs and one variable for excluding undesired docs.
DEFAULT_SRC_INSTALL_PARAMS
Extra parameters for emake -j1 DESTDIR="${IMAGE}" install.
DEFAULT_SRC_INSTALL_EXTRA_DOCS
File names listed here get added to the list of default doc targets. Any documents named exactly like these (still case-insensitive), prefixed by digits and/or starting with these followed by a dot, a dash or an underscore get installed.
DEFAULT_SRC_INSTALL_EXTRA_SUBDIRS
Useful when installing files with the same name (e.g. README) from multiple directories is desired. All identified targets inside these sub-directories are installed to the destination keeping the original directory structure.
DEFAULT_SRC_INSTALL_EXTRA_PREFIXES
Look for each target with this prefix too. This can also be used to install each match from any sub-directory directly to the top-level documentation directory, discarding the original directory structure.
DEFAULT_SRC_INSTALL_EXCLUDE
List of exceptions that shouldn’t be installed.
default_src_install()
{
local done_docs old_set f d p doc e
if [[ -f Makefile ]] || [[ -f makefile ]] || [[ -f GNUmakefile ]] ; then
if make -j1 -n "${DEFAULT_SRC_INSTALL_PARAMS[@]}" install ; then
echo "Found a makefile, using the install target"
emake -j1 DESTDIR="${IMAGE}" "${DEFAULT_SRC_INSTALL_PARAMS[@]}" install
else
die "default emake install located a makefile but no install target"
fi
else
echo "No makefile found, not using emake install"
fi
emagicdocs
}
The code for emagicdocs is listed under Helper functions.
Run in the sandbox.
default_pkg_preinst()
{
:
}
Run in the sandbox.
default_pkg_prerm()
{
:
}
Run in the sandbox.
default_pkg_postrm()
{
:
}
Run in the sandbox.
default_pkg_postinst()
{
:
}
Run in the sandbox.
default_pkg_config()
{
eerror "No configuration function is defined"
}
Run in the sandbox and with userpriv. Can be run for both installed and uninstalled packages.
default_pkg_info()
{
:
}
Organised by where they’re implemented in Paludis, to make it easy to keep this up to date.
We’re probably going to make most of these a lot stricter, and make forced die calls for things not existing and the like. Where it makes sense, we might also add a non-die version called try_blah.
We already have the nonfatal function which modifies how a function that usually dies on its own works: If a function, e.g. emake, dies on its own, it means that any code beyond that function (e.g. a || die “blah”) won’t ever be reached and, thus, a default error message is displayed. If you want to display a custom error message, you can add the prefix nonfatal to the function call, e.g. “nonfatal emake blah”. This will cause emake to just emit a non-zero return code which you can use with a regular || die “blah” function, i.e. emake will signal things went wrong but won’t die by itself.
die: Die unconditionally with its argument as a failure message and with a backtrace.assert: Checks the shell’s pipe status variable and if any component is non-zero (indicating failure) calls die with its argument as a failure message. See above.einfoelogewarneerrorebegineendeinfonewendSome commands optionally take a version argument – this is indicated as ever command [version]. Whenever a version is optional and omitted, ever functions default to the PV for the current id, unless stated otherwise.
Rather than being a number, the index parameter can be a separator character such as ‘-‘, ’.’ or ‘_’. In this case, the first separator of this kind is selected.
ever split [version]:
Returns the version with all version separators replaced by whitespace.
ever split 1.2.3
1 2 3
ever split_all [version]:
Returns the version, including version separators, separated by whitespace.
ever split_all 1.2.3
1 . 2 . 3
ever major [version]:
Returns the major version of version.
ever major 1.2.3
1
ever range <range> [version]: Returns the given range for a given version.
Ranges can be either…
A single number: Returns the version component at the given index
ever range 2 1.2.3
2
Two numbers separated by a dash: Returns the range of version components, defined by the two given indexes, separated by the dash.
ever range 1-2 1.2.3
1.2
A number preceded or followed by a dash: Returns an open range, defined by one given index, and either the start or the end of the version.
ever range 2- 1.2.3.4
2.3.4
ever range -3 1.2.3.4
1.2.3
ever remainder [version]:
Returns the remaining part of <version> after the major version.
ever remainder 1.2.3
2.3
ever at_least <versionA> [versionB]:
True when <versionB> is equal or newer than <versionA>, otherwise false.
When versionB is omitted, PVR is used instead.
ever at_least 1.2.3 1.3.5 && echo Yes
Yes
ever at_least 1.2.3 1.0.0 || echo No
No
ever delete <index> [version]:
Delete the version separator in position <index>.
ever delete 2 1.2.3
1.23
ever delete_all [version]:
Delete all version separators in <version>.
ever delete_all 1.2.3
123
ever replace <index> <replacement> [version]:
Replace the version separator in position <index> with <replacement>.
ever replace 2 - 1.2_rc1
1.2-rc1
ever replace_all <replacement> [version]:
Replace all version separators with <position>.
ever replace_all - 1.2.3
1-2-3
ever is_scm [version]: True when <version> is an scm version, otherwise false.
ever is_scm scm && echo Yes
Yes
ever is_scm 1.0-scm && echo Yes
Yes
echo is_scm 1.0 || echo No
No
keepdir: Dies on failure or when an argument begins with ${IMAGE} unless called via nonfatal.intoinsintoexeintodocintoinsoptsdiroptsexeoptsliboptsWe probably want to ban these at some point.
KV_majorKV_minorKV_microKV_to_intget_KVaddwrite Adds a path to the list of write-allowed path prefixes. The argument must be an absolute path. If the path argument of system calls starts with the given path prefix, it doesn’t cause an access violation and the system call is allowed.rmwrite Removes the given path prefix from the list of write-allowed path prefixes.addfilter Adds a pattern to the list of access violation filters. The argument is an fnmatch pattern. An access violation filter is a filter which, if it matches, prevents the access violation from being raised. Unlike addpredict the access to the system call is still denied.rmfilter Removes the given pattern from the list of access violation filters.die_unless_nonfatal: By default die with the provided error message. If called via nonfatal this function just prints the provided error message and emits a non-zero return value. Note that it is your job to make sure that this non-zero return value gets passed on to the callee of the function that uses this. E.g.:
ecmake() {
[...]
echo cmake ${cmakeargs} "$@" ${EXTRA_ECONF} "${WORK}"
cmake ${cmakeargs} "$@" ${EXTRA_ECONF} "${WORK}" || \
die_unless_nonfatal "Cmake failed" || return 1
[...]
}
is_nonfatal: Returns true when the current function was called via nonfatal, this can be used to make exlib functions behave differently depending on whether they’re called via nonfatal.
assert_unless_nonfatal: Like assert but calls die_unless_nonfatal rather than die on failure.
nonfatal: Make expatch, econf, einstall and keepdir emit a non-zero return value instead of dying upon failure.
expatch: Applies patches. Only allowed in the prepare phase. No patch level guessing is done. expatch can take five kinds of arguments:
`--recognised-suffixes`: Mostly for internal use. Makes expatch only apply patches that end in a
recognised file extension (`bz2`, `gz`, `Z`, `z`, `zip`, `ZIP`, `jar`, `diff` and `patch`). If
required those get uncompressed by `bzip2`, `gzip` or `unzip`.
`-p[0-9]*`: Set patch level for all following patches. This can be changed as often as needed
between applying patches. It defaults to `-p1`.
`-*` : All other arguments that begin with a dash are passed directly to patch for all subsequent
patches.
`[patch]`: If patch is a directory, recursively look for patches in that directory with a
recognised file extension, uncompress them if needed and apply them. If it is not a directory
uncompress if needed but apply regardless of file extension.
econf: Calls a standard autoconf configure script in ECONF_SOURCE or in the current directory with the following standard configure arguments followed by arguments supplied to econf.
--prefix=/usr
--host=${CHOST}
${CBUILD:+--build=${CBUILD}}
${CTARGET:+--target=${CTARGET}}
--mandir=/usr/share/man
--infodir=/usr/share/info
--datadir=/usr/share
--docdir=/usr/share/doc/${PNVR}
--sysconfdir=/etc
--localstatedir=/var/lib
--disable-dependency-tracking
--disable-silent-rules
--enable-fast-install
--libdir=${ECONF_PREFIX}/${LIBDIR:-lib}
ECONF_PREFIX gets set by --prefix or --exec-prefix being supplied to econf.
econf --hates=arg tells econf not to supply the standard argument --arg to the configure script. E.g. econf --hates=docdir. Use --hates if a configure script aborts on a standard configure argument.
econf automatically calls die on failure unless called via nonfatal.
einstall: Automatically calls die on failure unless called via nonfatal.
emagicdocs: Called by default_src_install to install documentation. Packages that don’t use Makefiles to build can use this function to just install documentation instead of calling default_src_install. See srcinstall](#srcinstall) for further documentation of the variables used below. The function looks like this:
emagicdocs() {
local done_docs old_set f d p doc e
done_docs=
old_set=$(shopt | grep 'nocaseglob[[:space:]]*on')
shopt -s nocaseglob
for d in '' "${DEFAULT_SRC_INSTALL_EXTRA_SUBDIRS[@]}" ; do
if [[ -n ${d} ]]; then
[[ -d ${d} ]] || die "${d} is not a dir"
pushd "${d}" > /dev/null || die "Failed to enter ${d}"
local docdesttree="${DOCDESTTREE}"
docinto "${d}"
fi
for f in README Change{,s,Log} AUTHORS NEWS TODO ABOUT THANKS {KNOWN_,}BUGS SUBMITTING \
HACKING FAQ CREDITS PKG-INFO HISTORY PACKAGING MAINTAINER{,S} CONTRIBUT{E,OR,ORS} RELEASE \
ANNOUNCE PORTING NOTES PROBLEMS NOTICE "${DEFAULT_SRC_INSTALL_EXTRA_DOCS[@]}"; do
for p in "${DEFAULT_SRC_INSTALL_EXTRA_PREFIXES[@]}" '' ; do
for doc in "${p}"*([[:digit:]])"${f}"{,+([._-])*} ; do
if [[ -s "${doc}" ]] ; then
for e in "${DEFAULT_SRC_INSTALL_EXCLUDE[@]}" ; do
[[ ${doc} == ${e} ]] && continue 2
done
done_docs="${done_docs} ${d%/}${d:+/}${doc}"
dodoc "${doc}" || die "dodoc ${d%/}${d:+/}${doc} failed"
fi
done
done
done
if [[ -n ${d} ]]; then
docinto "${docdesttree}"
popd > /dev/null || die "Failed to leave ${d}"
fi
done
if [[ -n "${done_docs}" ]] ; then
echo "Installed docs ${done_docs# }"
else
echo "Didn't find any docs to install"
fi
[[ -n ${old_set} ]] || shopt -u nocaseglob
}
edo: Convenience function to echo a command, run it, and die_unless_nonfatal if it fails
edo()
{
echo "$@" 1>&2
"$@" || paludis_die_unless_nonfatal "$* failed" || return 247
}
use_with is banned
use_enable is banned
option_enable:
option_enable()
{
if optionq "${1}" ; then
echo "--enable-${2:-$(optionfmt ${1} )}${3+=${3}}"
else
echo "--disable-${2:-$(optionfmt ${1} )}"
fi
}
For option_enable foo bar it echoes --enable-bar if foo is enabled and --disable-bar if foo is disabled
For option_enable suboption:foo it echoes --enable-foo if suboption:foo and --disable-foo if suboption:foo is disabled, so the suboption: string gets cut off
For option_enable foo bar zonk it echoes --enable-bar=zonk if foo is enabled and --disable-bar if foo is disabled
option_with. Similar to option_enable but using --with and --without.
export_exlib_phases (EXPORT_FUNCTIONS for exlibs)require (inherit for exlibs). Can take parameters for each exlib enclosed in [ ] (see exlibs section)myexparam, declare exlib parameterexparam, query exlib parameterdefault (see phases section)use is bannedusev is banneduseq is bannedoptionfmt: Probably not directly useful, echoes the name of the option without the foo: for suboptions.option: Alias for optionq.optionv: Like optionq but also echo the name of the option as reported by optionfmt.optionq: Returns true if the option is enabled and false otherwise.has: Alias for hasq.hasv: Like hasq but also echo the name of the first argument if found.hasq: Returns true if the first argument is found the list of subsequent arguments and false otherwise.has_version: Returns true if a package matching the provided dependency specification is installed in ROOT and false otherwise.portageq is bannedbest_version: Like has_version but also prints the category, package name and version of the highest installed match.vdb_path is bannedcheck_KV is banneddebug-print is banneddebug-print-function is banneddebug-print-section is bannedcanonicalise: Converts argument to an absolute path without symlinks.All of the following scripts die by default upon failure. If this isn’t desired call them via nonfatal:
dobindoconfddodirdodoc, dies on non-existent or empty files.doenvddoexedoinfodoinitddoinsdolibdolib.adolib.sodoman, dies on non-existent or empty files.domodosbindosym, dies if the target directory does not exist.emakenewbinnewconfdnewdocnewenvdnewexenewinitdnewinsnewlib.anewlib.sonewmannewsbinunpack, barfs on uncompressed unless --if-compressed. Doesn’t fix permissions.nonfatal, use this to make functions or scripts that die on failure by default nonfatal.
The following here* functions each take exactly one argument (the file name) and the contents of the file as a here document. They then use their do* counterpart to install the file. E.g.:
src_install() {
[...]
hereenvd 44qt4 <<EOF
LDPATH=${qt4_libdirs}
EOF
[...]
}
herebin
hereconfd
hereenvd
hereinitd
hereins
heresbin
All of the following scripts are banned:
prep*
dohard
donewins
dosed
dohtml
ecompress*
fowners
fperms
Not that different to eclasses yet. Can be per-category and per-package rather than global (this doesn’t work nicely with master repositories yet though). Loaded using require. Functions are exported using export_exlib_phases.
Exlibs can take parameters.
require foo [ bar=baz blah=bleh ] monkey [ in=space ]
This requires foo.exlib with bar=baz and blah=bleh parameters, and monkey.exlib with the in=space parameter. Exlib parameters need to be declared as early as possible in the exlib using the myexparam function. The following three examples declare the bar variable as a required parameter, blah as an optional parameter that is set to bloh if not provided and baz as an optional parameter that is set to an empty string if not provided:
myexparam bar
myexparam blah=bloh
myexparam baz=
To access the value of an exlib parameter use the exparam function. This takes one argument, the name of the exlib parameter, and outputs the value. It must be used only in the exlib that declares the parameter and only after it has been declared.
exparam bar
Unfortunately due to a limitation in bash and the way this functionality is implemented, using exparam in a subshell from a function that is called outside global scope will not work. So for instance this code will result in the error message “exparam is banned outside exlibs”:
foo_pkg_setup() {
var=$(exparam bar)
}
Therefore exparam has optional support for specifying a variable name to assign the value of the exlib parameter to:
foo_pkg_setup() {
exparam -v var bar
}
Exlib parameters can also be arrays. The following two examples are equivalent:
require foo [ bar=[ 1 2 "3 3" ] ]
require foo [[ bar=[[ 1 2 "3 3" ]] ]]
Allowing the latter notation makes it possible to have a regular variable with the value ”[”:
require foo [[ bar=[ ]]
Arrays must be declared via myexparam. The following three examples declare an exlib array as required, optional with three default elements and optional with an empty default value respectively:
myexparam bar[]
myexparam bar=[ 1 2 "3 3" ]
myexparam bar=[ ]
With exparam you can access either the number of elements, any individual element using an index or the full array:
exparam bar[#]
exparam bar[0]
exparam bar[1]
exparam bar[*]
exparam bar[@]
exparam bar is equivalent to exparam bar[0]. And again the value of the array can be assigned to a new array with exparam -v array bar[@] or of any individual element with e.g. exparam -v v3
bar[3].
For exlib parameters that specify a boolean option, the standard convention is to use the values true and false. To support this, myexparam takes a -b option to specify that only those two values are permitted, and exparam takes a -b option to return a true or false exit status instead of outputting to stdout. exparam -b is only permitted for parameters that were declared with myexparam -b. For example:
myexparam -b foo
myexparam -b bar=true
if exparam -b foo; then
DEPENDENCIES+=" dev-libs/libfoo"
fi
There are three types of sandboxing:
execve() sandboxingexecve() calls are sandboxed only in metadata phase. In this phase no external calls are allowed.
Path sandboxing and network sandboxing are enabled in the phases listed below:
Here’s a list of path prefixes that are allowed by default: Note: Environment variables are expanded.
prefix.write:
${CCACHE_DIR}
${PALUDIS_TMPDIR}
/var/cache
/var/tmp
/tmp
/proc/self/task
/proc/self/attr
/selinux/context
/dev/shm
/dev/pts
/dev/ptmx
/dev/tts
/dev/pty
/dev/tty
/dev/random
/dev/console
/dev/full
/dev/null
/dev/zero
/dev/stderr
/dev/stdout
/proc/self/fd
/dev/fd
Network sandboxing has two whitelists, one for bind and one for connect, sendto etc. By default network sandboxing allows bind to address 127.0.0.1/8 on ports 0 and 1024-65535. If a bind call is successful the address is automatically added to the connect whitelist.
The behaviour of sandboxing may be altered by using magic commands. These commands provide a simple way to interact with sydbox. Check sydbox manual page for the list of magic commands. The exheres command sydboxcmd is a simple wrapper around the magic stat. So instead of stat‘ing e.g. /dev/sydbox/off you may use sydboxcmd off.
Four space indents, no tabs.
Copyright goes to you, but you need to GPL v2 it if it goes in the tree. For stuff you wrote from scratch:
# Copyright 2008 Ciaran McCreesh
# Distributed under the terms of the GNU General Public License v2
If you make large changes to an exheres:
# Copyright 2007, 2008 Ciaran McCreesh
# Copyright 2008 Ivan Toby Rich
# Distributed under the terms of the GNU General Public License v2
If you rip off another non-trivial exheres:
# Copyright 2008 Ivan Toby Rich
# Distributed under the terms of the GNU General Public License v2
# Based in part upon 'foo-1.23.exheres-0', which is:
# Copyright 2008 Ciaran McCreesh
Basing your work upon ebuilds is fine, but if you did, make sure you include the Gentoo copyright notice. This applies even if you read the ebuilds for inspiration – unless you have a lawyer handy to tell you exactly what does or does not count as a derived work, it’s easiest to assume that if you looked at the ebuilds then it’s derived (not because it necessarily is, but because doing so imposes no additional restrictions, whereas not doing so gives certain Gentoo people with nothing better to do an opportunity to make nuisances of themselves). So then you need do this:
# Copyright 2008 Ciaran McCreesh
# Distributed under the terms of the GNU General Public License v2
# Based in part upon 'foo-1.23.ebuild' from Gentoo, which is:
# Copyright 1999-2007 Gentoo Foundation
All attempts should be made to keep the package as close to the upstream version as possible. In general, patches for compilation and runtime errors are okay. However, patches that introduce new features are discouraged, unless they are part of the upstream release cycle. Patches that alter external interfaces are particularly problematic. It is unacceptable to believe that it is sufficient to patch packages in our repository for such a change as this makes life harder for users who want to use packages that are not in our repositories. In the case that a patch is needed it must contain a header with the following information:
Source: written by, from distribution, etc
Upstream: yes, no, bug number, etc
Reason: reason for the patch
This allows for others (or yourself), who may work with the package in the future, to be able to determine why a specific patch was applied. In the case that a patch no longer applies, the header aids in determining what to do with the patch (port it, discard it, etc.).
If there is active upstream development, it is highly recommended that patches be passed along to them so that they may incorporate the fix in the next release. This is beneficial for both parties. Bugs in the upstream project are caught and fixed, and it reduces the effort required downstream to track and fix the bug with every release.
Packages should provide user options where reasonable and useful, but it is not necessary to spend excessive effort to support every obscure little tweak. Users can write their own custom exheres if they want these, although this should not require them to alter packages other than the ones they want to customise. In other words, if you make a definite decision instead of providing an option, avoid making other packages rely on that decision whenever reasonably possible.
Copyright 2008, 2009 Ciaran McCreesh
Copyright 2008, 2009, 2010 Bo Ørsted Andresen
This work is licensed under the Creative Commons Attribution Share Alike 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/; or, (b) send a letter to Creative Commons, 171 2nd Street, Suite 300, San Francisco, California, 94105, USA.