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.>
packages/
cat-foo/
per-category.exlib
pkg-foo/
pkg-foo-1.23.exheres-0
per-package.exlib
exlibs/
foo.exlib
What Gentoo calls use flags we call options. We may support non-boolean options at some point if there're 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 PLATFORMS into MYOPTIONS; platforms are regular SUBOPTIONS and should be managed as such.
Various things that were merely QA notices for ebuilds are strict errors.
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"
Labels aren't just for *DEPEND replacement. We'll also have them for host vs target deps:
DEPENDENCIES="
build,host: foo/bar
run,target: foo/other
"
Note the use of a comma rather than plus. Plus is for labels of the same group, comma is for different groups.
There're also suggested, recommended and required labels.
When specifying labels, if no value is specified for a given group, its current value is propagated. So:
DEPENDENCIES="
suggested:
cat/suggested-build-and-run
run:
cat/suggested-run
"
The full list of labels divided by group at present is:
Slot deps:
Square brackets (these go after slot deps, so foo/bar:slot[bracket]):
Operators:
~> means the same as it does for Gems.
SRC_URI has two new things. First, labels. Just one type:
SRC_URI="
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:
Second, arrows:
SRC_URI="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.
Annotations are another new dep-like toy. They don't convey any critical information (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
]]
post,suggested:
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:
Annotations are not, in principle, 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 ] ]]
"
SRC_URI="
mirror://foo/${P}.tar.bz2 [[ here = [ would apply to the URI ] ]]
"
but we don't do anything with any of those keys.
Don't overdo annotations. Blockers almost always benefit from having them. So do suggestions. 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.
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.
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.
default_pkg_setup()
{
:
}
Run in the sandbox and with userpriv.
default_src_unpack()
{
[[ -n "${A}" ]] && unpack --if-compressed ${A}
}
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[@]} || die "emake failed"
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 check ; then
echo "Found check target"
emake -j1 check || die "make check failed"
elif make -j1 -n test ; then
echo "Found test target"
emake -j1 test || die "make test failed"
else
echo "No check or test target, skipping tests"
fi
else
echo "No Makefile, skipping tests"
fi
}
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="${D}". It dies if an existing makefile is missing an install target. The remaining part tries to identify (case-insensitively) documents that are common in lots of packages and installs them by means of dodoc. default_src_install supports one variable for adding extra parameters for emake install, three varialbes for adding extra docs and one variable for excluding undesired docs.
DEFAULT_SRC_INSTALL_PARAMS
Extra parameters for emake -j1 DESTDIR="${D}" 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="${D}" ${DEFAULT_SRC_INSTALL_PARAMS[@]} install || \
die "default emake install failed";
else
die "default emake install located a makefile but no install target"
fi
else
echo "No makefile found, not using emake install"
fi
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 *([[:digit:]])${p}${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
}
Run in the sandbox.
default_pkg_preinst()
{
:
}
Run in the sandbox.
default_pkg_postinst()
{
:
}
Run in the sandbox.
default_pkg_prerm()
{
:
}
Run in the sandbox.
default_pkg_postrm()
{
:
}
Run in the sandbox and with userpriv.
default_pkg_nofetch()
{
[[ -z "${A}" ]] && return
local f g=
for f in ${A} ; do
[[ -f "${FETCHEDDIR}/${A}" ]] && 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.
default_pkg_config()
{
eerror "No configuration function is defined"
}
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.
ecmake() {
[...]
echo cmake ${cmakeargs} "$@" ${EXTRA_ECONF} "${S}"
cmake ${cmakeargs} "$@" ${EXTRA_ECONF} "${S}" || \
die_unless_nonfatal "Cmake failed" || return 1
[...]
}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'.
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.