Debian package management with GNU Arch
by Manoj Srivastava


Welcome to my repositories of Debian packages. These repositories use Arch, a distributed revision control system, similar in purpose to tools such as CVS, SCCS, and Subversion. It is used to keep track of the changes made to a source tree and to help programmers combine and otherwise manipulate changes made by multiple people or at different times. For example, this is how one can build the make package from source:

~% tla register-archive \
    http://arch.debian.org/arch/private/srivasta/archive-etch
~% tla get -A srivasta@debian.org--etch/packages--debian--0.13 \
    manoj

~% cd manoj
manoj% tla build-config ./configs/make/debian/make-3.80-6
manoj% arch-buildpackage make 3.80-6

I tend to cycle archives in the same time frame that Debian releases. Cycling archives lets one pare down repositories before they grow too large, and a release boundary seems a logical place to break the repository. You may browse the older Sarge packages here or the current Etch packages here, using the nice archzoom interface

Debian packages are, by far and large, a combination of external source archives, and various patches. (The exception being packages written specifically for Debian, which tend to not have separate upstream archives, or so many patches). These patches can be further sub-divided into packaging specific changes, which tend to be very similar to the packaging patches for most Debian packages, and far closer in heritage to each other rather than the software being packaged, Debian-specific changes (often required by Debian policy for integration), not relevant to or significant enough to warrant sending upstream, and features and enhancements not yet sent upstream. The upstream sources, and packaging changes, and feature sets, may have wildly dissimilar cycles of development, and yet must come together to create a Debian package.

During the development cycle. these patches

All these modifications to these changes don't all happen at once, and several change sets can even be modified in parallel. It is important to keep the patches separate, and up to date with the upstream versions. The protocol defined below is designed to facilitate and improve handling of these tasks.

Why arch?

It has the following features that set it apart from other revision control systems, such as CVS, Subversion or Bitkeeper:

What can I find in here?

What you'll find here is a full working set of sources for Debian packages. A short description follows below. All the packages here are live Debian packages currently in the Debian repository, complete with working Debian directories, with maintainer scripts and emacs .el files and menu files and all.

This should serve well as a learning by example set. Any feedback (especially patches) shall be appreciated. These packages are different in that they do not use Debian specific helper packages, instead restricting themselves to generic (mostly POSIX) utilities, and thus minimizing external dependencies and Debian specific jargon one has to learn.

I also have a separate repository dedicated to an effort to bring SELinux compatibility to Etch, which is very much a work in progress. This mini project is an effort to bring Debian's SELinux patched packages back in sync with the latest upstream and the latest SELinux patches, and to make it easier for Debian developers to access SELinux patches.

Package layout

One of the first things I discovered was that most of the packaging for my packages was very similar -- but not identical. Unfortunately, the previous incarnation of my packages with a monolithic rules file in each ./debian/ directory, it was easy for the rules files in packages to get out of sync -- and there was no easy way to merge changes in the common portions an any sane automated fashion. With the config mechanism in arch, however, it was easy to extract the common portion of each rules file into a separate project category, and take the bits that have to be customized for each package, but are very similar, into another package, thus separating the management of the packaging rules from the package code itself.

So, apart from the desire to separate out packaging details from the package code itself, the other requirement I had was the ability to be able to generate clean change-sets for upstream authors, one feature at a time. With this in mind, I have set up the following layout policy for packages I maintain.

Upstream sources

For every package I maintain, I create a separate category. Each package gets an upstream branch where I use tla_load_dir to import new versions from the original tar-balls. (Please see make--upstream--3.0). Every other branch in the category is a tag of some version in the upstream branch.

Features and changes

Next, any large changes made to the sources, or new features added, go into Pure feature branches, which start their lives as tags of the upstream branch. This common ancestry allows one to merge new upstreams into the feature branches using tla replay --skip-present, and thus keep my patch sets up to date and ready to be presented to the upstream. (Please see make--autotools--3.0, make--varbuf--3.0, make--i18n--3.0). Changes that are not large enough to warrant their own branches are collected into a debian branch (see make--debian--3.0). These are often changes required by Debian policy, minor typographical fixes that do not need a formal patch set -- mnemonic: changes made for Debian, and not meant to be report back upstream, but one can still provide a Debian patch if one needs to. These feature branches are mostly commit branches, where most changes are made via commits (or, occasionally, replays from the --upstream-- branch when a new upstream is released).

Sloppy Work Branches, Prism Merging, and Integration Branches

Of course, the ability to keep Pure feature branches, updated patch sets, etc. requires a little extra work. I create a sloppy work branch in a private arch repository on my work machine, and do my hacking there. I generally call these branches --scratch-- branches, and this is where I create changes, compile, and hack. These are, as the name suggests, throwaway branches. I also have an integration branch (typically labelled devo -- please see make--devo--3.0), where patches from the pure feature branches are merged in using star-merge, and this integration branch is used as the basis of my Debian packages. Please note that both the sloppy and the integration branches merge from every feature branch (using sync-tree liberally if I want to exclude some changes). Since all branches have --upstream-- as a parent, it is easy to merge back and forth between them.

The so called sloppy work branch (itself a tag of the upstream branch) is used for development. When I get a new change working, I create a diff with respect to the integration branch. On inspecting the diff, I determine which feature branch the change belongs to, and apply the diff to that branch, and commit the changes. Next, I run tla undo in the sloppy --scratch-- branch, and then I replay back the changes both to the scratch branch, and also to the integration (--devo--) branch (using replay --skip-present). This way I can break up the changes made on the sloppy working branch into multiple change-sets for possibly many feature branches. Code is never pulled from the sloppy branch to the feature branches; changesets created in the sloppy branch are manually applied to the relevant feature branch. This technique has been dubbed prism merge. The integration branch (--devo--) is a tag only branch: there are no commits ever made there, since no development work ever happens in the integration branch. I also ensure that the integration branch and the sloppy work branch are identical; since the sloppy branch is what is generally tested.each pull into the integration branch is supposed to be a single, tested, coherent change (well, in theory. In practise, I have been known to mess up).

Since tla replay --skip-present is idempotent, I can perform that action any time in the integration branch with any of the feature branches for that package. One can also use tla logs -scD --merges in the integration branch to see if there is anything missing. At some point I should script abrowse, to see what branches are available for the package, and run tla replay --skip-present for all non --devo-- branches.

The ./debian/ directory

So far, none of these branches contain any of the Debian specific ./debian directory. This is because the Debian directories for all my packages are branches of a different project, called, appropriately, debian-dir. This is because all these directories have far more in common with each other than they do with the package that they are instrumental in packaging (Please see debian-dir--make--1.0). All these package specific debian-dir branches are tailored versions of the ancestral branch named debian-dir--skeleton--1.0, which provides a template of the typical ./debian/ directory, very convenient when packaging a new package. Create a new debian-dir branch, tag it from debian-dir--skeleton--1.0, and we are well on our way.

Now, there is a lot of boiler plate code in the ./debian/ directory -- some things need to be there in order to placate Debian policy. Rather than duplicate all this in each debian-dir branch, I abstracted out all of this boilerplate into its own package, skeleton-make-rules, which provides the ./debian/common/ directory for every one of my packages.

Putting it all together

Now, in order to compile one of my packages from scratch, you need to get the devo branch, the package specific debian-dir branch created into ./debian/ directory, and the skeleton-make-rules category in ./debian/common/ directory. All this would be very tedious, were it not for the build-config support in arch, and the excellent arch-recordpackage and arch-buildpackage scripts, which I use in conjunction with user mode Linux pbuilder.

In this setup, the package foo-1.0-1 maps to the configurations configs/foo/debian/foo-1.0-1 and configs/foo/upstream/foo-1.0. So, referring back to the example above, you can do:

~% tla register-archive \
    http://arch.debian.org/arch/private/srivasta/archive-etch
~% tla get -A srivasta@debian.org--etch/packages--debian--0.13 \
    manoj

~% cd manoj
manoj% tla build-config ./configs/make/debian/make-3.80-6
manoj% arch-buildpackage make 3.80-6

This builds make 3.80-6, calling tla build-config or tla update as appropriate for you to get the source trees in ./make/make-3.80 and ./make/upstream/make-3.80. However, if ./make/make_3.80.orig.tar.gz exists, then the upstream config is ignored and that tar-ball is used. Otherwise, the upstream version is prepared from the relevant config, and then packed into the tar-ball (ignoring junk, pristine trees, and .)

If a file make/make-3.80/=RELEASE-ID exists, then it will be updated to contain a comment and the string make-3.80. This is to support the package-framework build system.

With make/make-3.80 as the current directory, debian/rules prebuild is run under fakeroot. The exit code is ignored. This hook is for things which have to happen before the tree is ready to build, but which should not happen when the resulting Debian source package is built (unlike the clean target, which runs every time). It can be used to run autoconf and automake here, for packages where it is necessary.

dpkg-buildpackage is invoked within the tree. The default arguments are -i'\\+\\+pristine-trees|\\+\\+saved.*|,,.*'. The commands invoked for dpkg-buildpackage and tla can be controlled via the ~/.archdeb.conf file. arch-recordpackage can be used to scan the current directory tree and creates the config files ./configs/make/debian/make-3.80-7 and ./configs/make/upstream/make-3.80, in preparation for the next release.

Here is what the config for an upstream package looks like, complete with all the feature branches:

./make/upstream/make-3.80 srivasta@debian.org--etch/make--upstream--3.0--base-0
./make/upstream/autotools--3.0 srivasta@debian.org--etch/make--autotools--3.0--patch-1
./make/upstream/debian--3.0 srivasta@debian.org--etch/make--debian--3.0--patch-1
./make/upstream/i18n--3.0 srivasta@debian.org--etch/make--i18n--3.0--patch-1
./make/upstream/varbuf--3.0 srivasta@debian.org--etch/make--varbuf--3.0--patch-1

And here is the config for the latest Debian package, which, as you can see, uses the devo branch.

./make/make-3.80 srivasta@debian.org--etch/make--devo--3.0--patch-4
./make/make-3.80/debian srivasta@debian.org--etch/debian-dir--make--1.0--patch-9
./make/make-3.80/debian/common srivasta@debian.org--etch/skeleton-make-rules--main--0.1--patch-7

After all that, feel free to proceed to the archive, or browse the raw directory directly.

Arch and Debian releases

Debian development cycles consist of package development going on the in the unstable, or Sid, branch, followed periodically by freezing development and stabilizing the distribution in the testing branch, before releasing the set of packages in testing as the next stable release. Arch lends itself naturally to this develop/freeze/release cycle.

Most people cycle archives periodically since that allows pruning of revisions, and thus all the revisions, versions, branches and categories are no longer in one place. So, commands that act on the whole archive (or category, or branch) do not take as long. However, instead of selecting an arbitrary time interval to cycle the archive, but linking archive cycling to Debian releases, allows one to have a distinct boundary in development, and allows one easily determine what version of ones software released with a particular release of Debian. Additionally, it is easy to create an update to stable (or the frozen testing) even after the development on the package has moved on into the newer archive.

To aid the humans browsing the archive, I generally seal the category in the old archive, and tag the sealed version in t the new. Sealing an archive does not make it harder to upload new fixes; it just is different enough that I would tend not to forget and upload to the older, sealed version by mistake.

Since Debian tends to freeze in stages. not all packages in an archive may freeze at the same time. For instance, required, important, and standard packages freeze earlier; in my case that is make and flex. It is easy enough to seal and cycle one package at a time; look below.

for i in $(tla branches flex); do
    tla get $i $i;
    cd $i;
    tla commit --seal -s \
      "$i is frozen for Sarge, look at http:// ...";

    cd ..;
    rm -rf $i;
    for j in $(tla versions $i); do
        tla archive-setup -A srivasta@debian.org--etch $j;
        tla tag srivasta@debian.org--etch/$j \
            srivasta@debian.org--etch/$j;

    done;
    echo $i done;
done

For sealing off and recycling a whole repository, barring any branches that have already been frozen, I use the script below:

OLD_REPO=srivasta@debian.org--2003-primary
NEW_REPO=srivasta@debian.org--etch
NEW_URL=http://arch.debian.org/arch/private/srivasta/archive-etch
EXCLUDE_BRANCHES=
withecho () {
    echo " $@" >&2
    "$@"
}
action='withecho'
for category in $(tla categories -A $OLD_REPO | sort); do
    sealed_already=$(tla branches -A $NEW_REPO $category)
    for branch in $(tla branches -A $OLD_REPO $category |sort); do
        NEXT=""
        for seen in $EXCLUDE_BRANCHES $sealed_already; do
            if [ "$seen" = "$branch" ]; then
                echo >&2 "not processing $branch"
                NEXT=YES
            fi
        done
        if test -z "$NEXT"; then
            $action tla get $branch $branch;
            $action cd $branch;
            $action tla commit --seal \
                -s "$branch is frozen, look at $NEW_REPO/$branch";
            $action cd ..;
            $action rm -rf $branch;
            for version in $(tla versions -A $OLD_REPO $branch); do
                $action tla archive-setup -A $NEW_REPO $version;
                $action tla tag $OLD_REPO/$version $NEW_REPO/$version;
            done;
            echo >&2 "$branch done"";
        fi
    done
done

Once the old archive is sealed, we switch the checked out working trees over to the new repository, like so:

WORKDIR_BASE=/usr/local/src/arch/packages--debian
OLD_REPO=srivasta@debian.org--2003-primary
NEW_REPO=srivasta@debian.org--etch
withecho () {
    echo " $@" >&2
    "$@"
}
action='withecho'
find $WORKDIR_BASE -type d -name '{arch}' | sort | while read i; do
    case $i in
        *,,*)
            echo Skipping $i
            ;;
        *)
            j=${i%%\{arch\}};
            (
                builtin cd $j;
                v=$(baz tree-version) ;
                case $v in
                    $OLD_REPO*)
                        $action tla-switch $NEW_REPO;
                        ;;
                    *)
                esac
            );
            echo ${j##${WORKDIR_BASE}/} done;
            echo "";
    esac
done

New upstream versions and feature branches

This is the part that causes people most concern -- and with some reason. What happens when you have a new upstream release? Doesn't this cause much more work with more branches? And the answer is, well, yes and no ;-). I have a process that is now semi automated, which is important if one intents to follow active upstream development with lots of patches. At the time of writing I am tracking CVS repositories for fvwm and Gnus, using cscvs. Both these packages are under active development, I can get several changesets a day at times, and manually doing patches would have been hard.

The vast majority of updates to upstream the changes do not physically overlap (or conceptually conflict) with the changes in the feature branches, so a process that leverages that fact is efficient. In the cases where upstream changes overlap or conflict feature branch code, my attention to code details and reworking of the conflicting changes is unavoidable in any case, but the script below shows how things can be managed when there are no conflicts. (I still eyeball the changes made in upstream before attempting the automated merge, since conceptual conflicts can be subtle).

Consider the case of fvwm, which has 4 pure feature branches, and an integration branch (labelled devo). Once I have updated the upstream branch, using cscvs, for example, and I have a score or so fairly small patches, I can run the following little script:

pkg=fvwm
dev=$(baz versions ${pkg}--devo | tail -n 1)
ups=$(baz versions ${pkg}--upstream | tail -n 1)

for branch in $(baz branches $pkg | egrep -v '(devo|upstream)$'); do
    for version in $(baz versions $branch | tail -n 1); do
        (set -e; echo $version; cd $version>/dev/null;
            for missing in $(baz missing $ups); do
                baz replay $missing
            done
            baz commit -L 'Synch with upstream'
        )
        (set -e; cd $dev >/dev/null;
            for missing in $(baz missing $version); do
                baz sync-tree $missing
            done
        )
        echo $version done
    done
done

(set -e; cd $dev >/dev/null;
    for missing in $(baz missing $ups); do
        baz replay $missing
    done
    baz commit -L 'Synch with upstream and other branches'
)

A day in the life ...

In order to give a feel for what it is like maintaining packages under this scheme, I am going to lead us through the steps take to update tome to a new upstream version, namely, 2.2.6. The first step is to download the sources and unpack 'em.

~/% WD=/usr/local/src/arch/packages-debian/
~/% TOME=$WD/tome/
~/% cd $TOME/
$TOME/% wget http://www.t-o-m-e.net/dl/src/tome-226-src.tar.gz \
            -O tome_2.2.6.orig.tar.gz

$TOME/% cd upstream/
$TOME/upstream/% tar zvvfx ../tome_2.2.6.orig.tar.gz

The upstream code unpacks in the dir tome-226-src. I already have tome-2.2.5/ from the last time around (it is an unpacked version of tome--upstream--2.2) In the scheme of things, ./tome/tome-2.2.6 is the integration branch, and ./tome/upstream/tome-2.2.6 is the upstream branch. (It ain't confusing to me ;-)

We'll move the dir to the 2.2.6 version name. Next, we import the newly unpacked upstream sources into the already checked out upstream tree. I could have done the import and commit in just one step, using tla_load_dirs -L 'Imported new upstream version' ../tome-226-src/ but I like being careful. However, all the steps below can be rolled into a CD and a single tla_load_dirs invocation.

$TOME/upstream/% mv tome-2.2.5/ tome-2.2.6/
$TOME/upstream/% cd tome-2.2.6
$TOME/upstream/tome-2.2.6/% tla_load_dirs -n ../tome-226-src/
$TOME/upstream/tome-2.2.6/% tla changes
$TOME/upstream/tome-2.2.6/% tla tree-lint
$TOME/upstream/tome-2.2.6/% diff -uBbwr . ../tome-226-src/
$TOME/upstream/tome-2.2.6/% tla commit -L 'Imported new upstream version'
$TOME/upstream/tome-2.2.6/% cd ../
$TOME/upstream/% rm -rf tome-226-src/;
$TOME/upstream/% cd ../

The new revision is automatically signed using my archive key, and, thanks to my hook script, it is also automatically pushed out to this mirror. Now, I maintain a set of changes to the upstream tome package, and I want to ensure that my patch set is kept up to date. But first, I go into my scratch work tree and make sure that this update would work.

$TOME/ % cd sloppy
$TOME/sloppy/% tla replay --skip-present tome--upstream--2.2

Once I am satisfied that the upgrade does not break anything (which means my patches were not affected by the upgrade), I update all my Pure feature branches. This step is only required if I wish to continue to keep an updated set of patches related to the current upstream version.

$TOME/sloppy/ % cd debian--2.2
$TOME/sloppy/debian--2.2/ % tla replay --skip-present tome--upstream--2.2
$TOME/sloppy/debian--2.2/ % tla commit -L 'Synchronize with v:2.2.6'
$TOME/sloppy/debian--2.2/ % cd ../
$TOME/sloppy/ % cd docs--2.2/
$TOME/sloppy/docs--2.2/ % tla replay --skip-present tome--upstream--2.2
$TOME/sloppy/docs--2.2/ % tla commit -L 'Synchronize with v:2.2.6'
$TOME/sloppy/docs--2.2/ % cd ../
$TOME/ % mv tome-2.2.5/ tome-2.2.6/
$TOME/ % cd tome-2.2.6/
$TOME/tome-2.2.6/ % tla replay --skip-present tome--upstream--2.2
$TOME/tome-2.2.6/ % tla commit -L 'Synchronize with v:2.2.6'

Confusingly, $WORK_DIR/tome/tome-2.2.5 is actually a checked out version of the integration branch (tome--devo--2.2)

If I had needed to hack my sloppy work tree to make it work for the new upstream release, this is where I would be creating patches with tla changes --diffs -o ,changes, and applying the changes to the corresponding pure tree with mv ,changes $PURE; cd $PURE; tla redo -p ,changes; tla commit, and then synchronizing the working sloppy dir with tla sync-tree $PURE; tla commit. Luckily, I do not have to do that here.

Since there had been no changes made in the feature branches, we already have all the changes. If there had been prism merge work done on the feature branches, this is where those changes would have been star merged in. In this case, we are done. Just confirming that.

$TOME/tome-2.2.6/% tla replay --skip-present tome--debian--2.2
$TOME/tome-2.2.6/% tla replay --skip-present tome--docs--2.2

Almost done here. Now, I edit the $WORK_DIR/tome/tome-2.2.6/debian/changelog, and also fix a bug in $WORK_DIR/tome/tome-2.2.6/debian/menuentry, and am ready to roll. We need to check in the changes I just made to debian-dir--tome--1.0.

$TOME/tome-2.2.6/% cd debian/
$TOME/tome-2.2.6/debian/% gnuclient $(tla make-log)
$TOME/tome-2.2.6/debian/% tla commit
$TOME/tome-2.2.6/debian/% cd ../../..
$WD/% arch-recordpackage --upstream tome 2.2.6
$WD/% arch-recordpackage tome 2.2.6
$WD/% arch-buildpackage tome 2.2.6-1
$WD/% cd tome
$TOME/% lintian -vi *.changes
$TOME/% sudo dpkg -i *.deb

Now test the package, and then upload to the repository.

Lately, I have taken to running the build inside a SELinux UML, but I haven't fully automated it a la pbuilder-uml. It should be relatively easy to do so, I think.

The Archive Key

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.3 (GNU/Linux)

mQGiBD/wecMRBADgA34V7S+xZ7JVitvLiGDs5lbntNCyU4hFfS1xM73GM6P6yozc
9O3nOATstXQegkm77tjW9jQkc1Tu48UepWmIZEcsIY4wfpesEoIfLytcTRvewL+l
OaZeS/jJo2ZVi2/FSZvM9VVkgT4zliV41BB48MSAjf+ex+ZoMQp1g00UTwCgrzyg
WdBDjun+g9vzKLnbXhQNeAsD/AmxjAmrQXH+hkZw+z00xw2ax2wL5DLV7vX4raF4
UHoPWuG/68SVOYOTa7fsgTC6LkY6DvB7ipdRdPRK0CtwKRZvzGZtsZG2LYcjDvwE
NwWDKVxAB8fBhIGkp36tS6LwqI+Ou2u1jL/3V9wTVWuiHoL77gysYIkQdrsZOcpE
NqJEA/0ZF3nabmWIdCrjc16jME2lIkXjDvoTIMTPh96JRu6vSevblYVpOeY8l5w1
UgBiP7Q7t14LJJOVlX5ReRitS8cyMqkvsNOrdwZCO6fOuO2P8m4SEr+LTIuR4F3Z
ge5IWEE5tePmw8UAKRlofWGNetdxZbfKkEGbU3FHYRInShzba7Q2QXJjaGl2ZSBL
ZXkgZm9yIE1hbm9qIFNyaXZhc3RhdmEgPHNyaXZhc3RhQGRlYmlhbi5vcmc+iF4E
ExECAB4FAj/wecMCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQgxLXMEBhLIRF
cACfbgV87+iPBQ0AcRFdJ/qeCB7O9GQAn2JnmPyKLbI9HffIGshBsf5sIPYjiEYE
ExECAAYFAj/x1HQACgkQIbrau78kQkzyQACg+TZ/nCHft9PVgLUg5QOciBVg+uIA
n0iybTVnhBnpCSuxUHCJQqIfhxR9uQENBD/wecMQBAC7oKJ+io/cjZxMP1V6jUzi
pmQ3yAAUbOgCsr/ah9izwG9k+u6xXnNyHkYChNP1zd1K6y9ZSWVWz4fryqlfmjFn
fvKqwUrXohYBIVSUjiIgQMTUNrJR3HIJ0WKgz5fm7AGScydVSqTEsXKG9QwWo1ql
iM1X9APljSL8LhsFnmS2pwADBQP8DUBUzHYc7AUDw7DS7maBlIASicSIhk5cbiiI
ie2d1nTy6vF+Ahnq9XHj3/lJJ+2/T6jR/2K2B+HAx90Ni/akTFY3IMuVOTKxWax+
mPAf7EOaWIytgRSPkPACbI+3hLZChdqo+t1MNJL9isrDyHPlkgKHeaEkS4ZLGRYX
4XTKCf6ISQQYEQIACQUCP/B5wwIbDAAKCRCDEtcwQGEshPh9AKCTtIabRD4ZO/fO
QspxKZD6a+cAhgCgo1LVnE4m895HZM/E4inEpnoFa/s=
=lPRe
-----END PGP PUBLIC KEY BLOCK-----
          

Description of packages

In the following sections, there appears a description of all the packages I maintain. Each package description contains pointers to the components from which the Debian package is built. Also, there should be links to each "pure feature" branch, and, thanks to the excellent RCSGraph package, there is a graph of patch and branch ancestory data. It is interesting to see how wild and undisciplined my patching history was initially, and how it has gotten better over time. Also, please not that the patch history is far more complex for packages I track upstream CVS repositories with (namely, Gnus and FVWM).

The packaging infrastructure Packages

skeleton-make-rules

This package contains the common parts of the Debian rules file, including the target dependencies, and other common idioms. This package provides the ./debian/common/ directory present in all packages. These rules draw inspiration from CDBS, though are considerably simpler since arch actually does the patch management, and I do not have allow for a debhelper variant.

Branch and Patch History

skeleton-make-rules, 15 Kb
debian-dir
This package is a collection of ./debian/ directories from all the packages -- each package getting its own branch, and tagged from the debian-dir--skeleton branch. The common ancestor branch provides a template to start debianizing a new package, with placeholder maintainer scripts that contain ready to edit examples.
packages
This package is a collection of configs, and placeholder build directories for all the packages I have in the archive. This is all that you need to download; and then run tla build-config ./config/package/debian/version

The Easy Packages

cvs-buildpackage, cvs-buildpackage/debian, cvs-buildpackage/debian/common

One of the simplest packages I have. This is a set of Debian package scripts for CVS source trees. It provides the capability to inject or import Debian source packages into a CVS repository, build a Debian package from the CVS repository, and helps in integrating upstream changes into the repository. This can be used to generate a unified CVS source tree, for example.

Branch and Patch History

cvs-buildpackage, 12 Kb
devotee, devotee/debian, devotee/debian/common

This is still a work in progress, but the packaging aspect makes this one of the simple packages. This package is the one I plan on using to get though NM.

Branch and Patch History

devotee, 23 Kb
angband-doc, angband-doc/debian, angband-doc/debian/common

This is documentation for the single-player, text-based, dungeon simulation angband. Essentially there are just help files that need to be installed.

Branch and Patch History

angband-doc, 8 Kb
wm-icons, wm-icons/debian, wm-icons/debian/common

The Window Manager Icons is a set of generic icons for use by window managers in a graphical environment. It is an efficient icon distribution designed to be standardized and configurable. It includes several themed icon sets, a template icon set to help building new themed icon sets, scripts and configurations for several window managers.

As for packaging, we create a bunch of symbolic links on the fly here. Apart from that, this is a pretty vanilla package.

Feature Branches

  • The autotools branch. This branch is used to run newer versions of autoconf, to get the configuration files updated from time to time.
  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

wm-icons, 57 Kb
checkpolicy, checkpolicy/debian, checkpolicy/debian/common

This is the NSA's Security Enhanced Linux security policy compiler. This is dreadfully easy to build, since the heavy lifting is mostly done by the upstream build system. Just make, and install (with the proper DESTDIR set, of course). The only interesting thing is checking DEB_BUILD_OPTIONS before stripping the binary produced.

Branch and Patch History

checkpolicy, 51 Kb
policycoreutils, policycoreutils/debian, policycoreutils/debian/common

This contains utilities for manipulating the NSA's Security Enhanced Linux security policies, including load_policy to load policies, setfiles to label filesystems, newrole to switch roles, and run_init to run /etc/init.d scripts in the proper context. The only thing nominally different about this is the Debian specific wrapper scripts for dpkg, apt, and friends, so they can be run in a pty with the proper context. Note also the use of find to find things to strip.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

policycoreutils, 123 Kb
selinux-doc, selinux-doc/debian, selinux-doc/debian/common

This package contains build instructions, porting information, and a CREDITS file for SELinux. Some of these files will be split up into per-package files in the future, and other documentation will be added to this package (e.g. an updated form of the Configuring the SELinux Policy report).

This is about as straight forward a package as something built from SGML can be, thanks to the simple, but robust upstream build system.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

selinux-doc, 71 Kb
tla-tools, tla-tools/debian, tla-tools/debian/common

This package contains a collection of tools to make life with GNU Arch easier. This is also unusual in the sense that the upstream repository is also in arch, so I did not have to create a local branch for upstream. Also, there was very little that needs to be done to package it, and this is really one of the simplest packages I have.

Branch and Patch History

tla-tools, 19 Kb

The Normal Packages

make-dfsg, make-dfsg/debian, make-dfsg/debian/common

GNU Make is a program that determines which pieces of a large program need to be recompiled and issues the commands to recompile them, when necessary.

The package I used as a learning tool; in my eyes, this is the typical package. This was a good example to see how to get HTML files into a separate package. Unfortunately, due to DFSG reasons, the documentation has now been split off into another package, which is in the non-free archive. The Make package now merely holds the executable, and the source package is now called make-dfsg.

Feature Branches

A number of feature branches for make have been retired, since the patches have been merged in upstream. At this point, there are very minor differences between Debian's versions and upstream, but this did not always use to be the case.

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.
  • The Autotools refresh branch. This branch is for the changes to Makefiles, configure scripts, and related files when they were regenerated with newer versions of autoconf and friends.

Branch and Patch History

make-dfsg, 223 Kb
make-doc-non-dfsg, make-doc-non-dfsg/debian, make-doc-non-dfsg/debian/common

This is the other half of the Make package, and contains just the non-free documentation. The tricky part was getting the minimal build system in place to be actually able to build the documentation, without adding bloat tot he archjive by needlessly duplicating amterial already in the make-dfsg package.

Branch and Patch History

make-doc-non-dfsg, 147 Kb
fvwm, fvwm/debian, fvwm/debian/common

FVWM is a powerful ICCCM-1.1 compliant multiple virtual desktop window manager for the X Window System. FVWM requires relatively little memory. This version includes new features like full support of the EWMH (Enhanced Window Manager Hints) specification, internationalization, improved window decoration code (no flickering anymore), bi-directional asian text support, FreeType font support (antialiasing), image rendering, Perl based module library, support for PNG images, side titles and much more.

The interesting part of this package is the menu mechanisms, and the number of binaries that need to be put in private bin directories.

Feature Branches

  • The autotools branch. This branch is used to run newer versions of autoconf, to get the configuration files updated from time to time.
  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.
  • The terminal emulator branch. Changed the hard-coded xterm into x-terminal-emulator.

Branch and Patch History

fvwm, 847 Kb
angband, angband/debian, angband/debian/common

Angband is a single-player, text-based, dungeon simulation derived from the game Moria, which was in turn based on Rogue. It is often described as a "roguelike" game because the look and feel of the game is still quite similar to Rogue.

Angband features many enhancements over Moria: unique foes, artifacts, monster pits and vaults to name a few. Many of these new creatures and objects are drawn from the writings of J.R.R Tolkien, although some of the monsters come straight from classical mythology, Dungeons & Dragons, Rolemaster, or the minds of the original Angband coders.

A fairly generic autoconf enabled package, with all that entails. Has an branch where we upgraded automake, autoheader, and autoconf related files. Otherwise pretty vanilla, with the exception that there are a lot of library files involved in a special hierarchy, and some of them need to be conf files. The rules file does not need to know the names of these files, which is good since they change often.

Feature Branches

  • The autotools branch. This branch is used to run newer versions of autoconf, to get the configuration files updated from time to time.
  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

angband, 45 Kb
tome, tome/debian, tome/debian/common

Tome, short for Troubles of Middle Earth, is a single-player, text-based, dungeon simulation derived from the game Angband, which in turn is derived from the older game Moria, which was in turn based on Rogue. It is often described as a "rogue-like" game because the look and feel of the game is still quite similar to Rogue.

The first main difference from Angband a new player to ToME will need to be aware of is that it has implemented a skills based system where instead of the adventurer automatically improving in their abilities as they become more experienced. The second major difference is that the main dungeon from Angband has been split into 4 "dungeons", each of which has a different look and feel based loosely on Tolkien's Middle Earth. The third main difference between Vanilla Angband and ToME is the difference in character classes and races, as well as a very different magic system.ToME also offers the player the ability to undertake a series of quests.

A fairly generic makefile, but, like Angband, with the exception that there are a lot of library files involved in a special hierarchy, and some of them need to be conf files. This used to be what Angband packages looked like, until Angband went autoconf.

Feature Branches

  • The documentation branch. This branch is for additional TOME documentation, starting with a manual page (as required by policy).
  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

tome, 79 Kb
ucf, ucf/debian, ucf/debian/common

Debian policy states that configuration files must preserve user changes during package upgrade. The easy way to achieve this behavior is to make the configuration file a conffile, in which case dpkg handles the file specially during upgrades, prompting the user as needed.

This script attempts to provide conffile like handling for files that can not be labelled conffiles, are not shipped in a Debian package, but handled by the postinst instead. This script allows one to maintain files in /etc, preserving user changes and in general offering the same facilities while upgrading that dpkg normally provides for conffiles.

Really very simple, with little out of the ordinary. The only thing of significance is using debconf to ask the questions, otherwise this used to be in the easy packages list.

Branch and Patch History

ucf, 11 Kb
slat, slat/debian, slat/debian/common

Slat is concerned with information flow security goals, which describe desired paths by which information moves throughout a system. SLAT provides a simple syntax by which to express these goals, and tools that check a policy configuration against the goals.

Branch and Patch History

slat, 31 Kb
polgen-dfsg, polgen-dfsg/debian, polgen-dfsg/debian/common

SELinux policy generation scripts. This package contains a collection of scripts and tools developed by the MITRE corporation to automate the SELinux policy generation process. However, the sources have been modified from the original; documents under a non-free license have been split off into a non-free package. Only the free binaries distributed under the GPL are in this package.

Branch and Patch History

polgen-dfsg, 58 Kb
polgen-doc-non-dfsg, polgen-doc-non-dfsg/debian, polgen-doc-non-dfsg/debian/common

This package contains documentation for a collection of scripts and tools developed by the MITRE corporation to automate the SELinux policy generation process. This package has been stripped down to only contain the documentation; since the documentation is covered under a non-free license and thus has been moved to non-free/doc. Polgen itself remains in Debian.

Branch and Patch History

polgen-doc-non-dfsg, 50 Kb
debian-policy
This package is unique in the sense that it is not just my package, it is owned by the mailing list debian-policy@lists.debian.org, and there are a number of people who, along with me, have commit access to the central repository on arch.debian.org. (For reference, if it at http://arch.Debian.org/arch/dbnpolicy/etch/). This is a fairly large package, and has a complex sequence of generation of documents in a number of formats, and is different from my other packages in how it is put together. As other peoples repositories come on line, I'll put in a reference here.

Branch and Patch History

debian-policy, 10 Kb

Old style Emacs Packages

psgml, psgml/debian, psgml/debian/common

PSGML is a major mode for the editor Emacs used for editing SGML documents. It contains a simple SGML parser and can work with any DTD. (The most popular nowadays are the HTML DTDs. This package turns your emacs into the one of most powerful HTML editors and will be ultimately flexible as well, since you could upgrade your editor by just installing new DTDs). Functions provided includes menus and commands for inserting tags with only the contextually valid tags, identification of structural errors, editing of attribute values in a separate window with information about types and defaults, and structure based editing.

As far as packaging goes, this is an emacs package, with byte compilation, info files, and a site-start.d file. We also provide an added emacs-lisp file, psgml-html.el, which replaces the normal emacs HTML mode. The interesting parts of this and all other emacs packages are the need to adhere to emacs policy.

Feature Branches

  • The speed fix branch. This branch is for a patch that typically makes parsing several times faster in Emacs if sgml-set-face is on. It doesn't have any effect in XEmacs or Emacs when sgml-set-face is nil. Also, it also corrects some compilation warnings and eliminates the initialization of an unused variable, which was outside the package's name space in the first place.
  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

psgml, 50 Kb
vm, vm/debian, vm/debian/common

VM (View Mail) is an Emacs subsystem that allows UNIX mail to be read and disposed of within Emacs. Commands exist to do the normal things expected of a mail user agent, such as generating replies, saving messages to folders, deleting messages and so on. There are other more advanced commands that do tasks like bursting and creating digests, message forwarding, and organizing message presentation according to various criteria. With smtpmail in modern emacsen, you do not need a MTA locally in order to use VM.

Another emacs package, with the el files split into another package. The interesting part is that we also generate an arch dependent binary package called mime-codecs, which contains fast Quoted-Printable and BASE64 MIME transport codecs. This juxtaposition of architecture independent emacs lisp packages, with an architecture dependent binary auxiliary package could be of interest.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.
  • The MIME view fix branch. If you have vm-auto-decode-mime-message set to t, then you will have no trouble seeing mime encoded messages. However, you are right: once you've hit D (twice) for some reason, you can't go back. I get an error no presentation buffer. This is a modified patch from Jeff Dwork to recreate the presentation buffer and also hide the headers.
  • The sexp virtual selector branch. This branch is for a patch that adds a new sexp virtual selector, thanks to Ian Jackson.

Branch and Patch History

vm, 73 Kb
gnus, gnus/debian, gnus/debian/common

Another large emacs package. A versatile News and mailing list reader for Emacsen. Gnus is a message-reading laboratory. This is by far the most powerful and extensible news reader that I am aware of. It will let you look at just about anything as if it were a newsgroup. You can read mail with it, you can browse directories with it, you can FTP with it---you can even read news with it! It handles single file groups, MH format folders, mbox files, digests, knows about POP, etc. It can split incoming mail a la procmail.

This is no longer my package, and while I am leaving the code in the repository, it is not maintained, please see the current package for an up to date packaging. This is the version of the code I had before the non-free documentation was removed from the package.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.
  • Read lists.debian.org archives in Gnus. This patch for nnwarchive.el is to support lists.debian.org. Now one may read the web list archive with Gnus, In Group buffer, type B, select nnwarchive, and enter lists.debian.org as Address. It'll fetch the whole list of monthly subgroups. Use U to subscibe to one or more of them. They'll show up in your Group buffer, and you can select them.

Branch and Patch History

gnus, 53 Kb
calc, calc/debian, calc/debian/common
This is an advanced calculator and mathematical tool for GNU Emacs.Very roughly based on the HP-28/48 series of calculators. Mostly the same as the other emacs packages.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

calc, 8 Kb

Typical CPAN Packages

liblog-log4perl-perl, liblog-log4perl-perl/debian, liblog-log4perl-perl/debian/common

Log::Log4perl is a pure Perl port of the widely popular Apache/Jakarta log4j library for Java. In the spirit of log4j, Log::Log4perl addresses the shortcomings of typical ad-hoc or homegrown logging systems by providing flexible, consistent mechanisms to control the amount of data being logged and where it ends up at.

A package to handle a typical CPAN style package. This shows how to get the man pages in the correct directories, and all.

Branch and Patch History

liblog-log4perl-perl, 76 Kb
libcgi-perl, libcgi-perl/debian, libcgi-perl/debian/common

This is a set of modules for perl5, for use in writing CGI scripts. Initially, this package was destined to replace libcgi-pm-perl, but at the moment libcgi-pm-perl (as in the library CGI.pm) serves as the rapid prototyping version, and may be more featureful than this package. Indeed, there has been a hiatus of several years in the development of this module.

Packaging wise, this is not very interesting -- just a vanilla CPAN package -- as are these packages below.

Feature Branches

Branch and Patch History

libcgi-perl, 21 Kb
libgraphics-colorobject-perl, libgraphics-colorobject-perl/debian, libgraphics-colorobject-perl/debian/common

A module to convert color specifications between all the common color spaces. It is not very fast, and so it you want to convert entire images, this is probably not what you want. The emphasis is on completeness and accurate conversion.

Supported color spaces are: RGB (including sRGB, Rec 601, Rec 709, ITU, and about a dozen other RGB spaces), CMY, CMYK, HSL, HSV, XYZ, xyY, Lab, LCHab, Luv, LCHuv, YPbPr, YCbCr. Future support is planned for YUV, YIQ, YCC and possibly others.

Branch and Patch History

libgraphics-colorobject-perl, 16 Kb
libgraphics-colornames-perl, libgraphics-colornames-perl/debian, libgraphics-colornames-perl/debian/common

This package defines RGB values for common color names. The intention is to:

  1. provide a common module that people can use with other modules to specify colors; and
  2. free module authors from having to re-invent the wheel whenever they decide to give the users the option of specifying a color by name rather than RGB value.

Branch and Patch History

libgraphics-colornames-perl, 17 Kb
libgraphics-colordeficiency-perl, libgraphics-colordeficiency-perl/debian, libgraphics-colordeficiency-perl/debian/common

This module allows easy transformation of colors for color deficiency simulation. All the known and theoretical color deficiencies are represented here, with the exception of 4-cone vision (tetrachromatism).

Branch and Patch History

libgraphics-colordeficiency-perl, 15 Kb
libmodule-load-perl, libmodule-load-perl/debian, libmodule-load-perl/debian/common

This module eliminates the need to know whether you are trying to require either a file or a module. Perl's require has a nasty quirk: it behaves differently when given a bareword or a string. In the case of a string, require assumes you are wanting to load a file. But in the case of a bareword, it assumes you mean a module.

This gives nasty overhead when you are trying to dynamically require modules at runtime, since you will need to change the module notation to a file notation fitting the particular platform you are on. This module eliminates this overhead..

Branch and Patch History

libmodule-load-perl, 7 Kb

Packaging wise, most CPAN packages have a cookie cutter packaging infrastructure.

Packages using the Perl Configure mechanism

c2man, c2man/debian, c2man/debian/common
A simple package, except that it shows how to deal with a Perl style Configure file. This package is mostly obsolete, and rarely changes anymore. Please do not use c2man -- it is unmaintained upstream now, and only exists because other packages depend on it. Doxygen does all this, and much better.

Feature Branches

Branch and Patch History

c2man, 27 Kb
dist, dist/debian, dist/debian/common

The dist package is a set of tools meant to ease the construction and maintenance of portable software. A large package, which shows how to deal with a Perl style Configure file.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

dist, 22 Kb
mailagent, mailagent/debian, mailagent/debian/common

Mailagent allows you to process your mail automatically. This has far more functionality than procmail, and is easier to configure (providing, of course, that you grok perl). As a mail processing tool, this slices, it dices, it ...

Given a set of lex-like rules, you are able to file mails to specific folders (plain Unix-style folders and also MMDF and MH ones), forward messages to a third person, pipe a message to a command or even post the message to a newsgroup. It is also possible to process messages containing some commands. It can serve as a vacation program, which will automatically answer your mail while you are not there, but more flexibly than the Unix command of the same name. You only need to supply a message to be sent and the frequency at which this will occur. Some simple macro substitutions allow you to re-use some parts of the mail header into your vacation message, for a more personalized reply.

It is possible to extend the mailagent filtering commands by implementing them in perl and then having them automagically loaded when used.

A Configure style package, with a large examples directory and an in place patch of the binary in the postinst. It is also debconfized now.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.

Branch and Patch History

mailagent, 15 Kb

Packages with shared libraries

Shared library packages are widely held to be some of the more complex packages to initially create, and to properly maintain, and novices are (not incorrectly) advised to select something simpler to start with. Indeed, this segment of packages has spawned a number of tutorials and guides for packaging, and most of the complexity comes from trying to correctly automate dependency relationships for the packages that shall be built against the shared libraries that are being packaged. It is important that these relationships be defined correctly -- since if the shared library is missing (or has an incorrect version) on the target system the binary shall fail to run.

The relationship between a package containing binaries and the shared libraries the binary is linked with has been handled in Debian using the shlibs mechanism. The libraries in question provide files that map share library SONAMES to dependency relationships (package name and optionally version information) formatted nicely for inclusion in the binary package control file used during .deb file creation, and the packaging system inserts the information into place holders in the binary package control file.

So the critical dependency relationship is only as correct as the contents of the shlibs files are. This places an additional responsibility on the maintainer, one may no longer just run black-box system tests on a new upstream version, one must needs delve into the details of the code, and examine the shared library interface.

An important concept in determining these relationships is the so (shared object) name, which generally has a version component. A general rule of thumb is that if prototypes (and hence symbols) change or are removed, that's an SONAME bump. symbols are added, but current ones don't change, just a bump in the dependency relationship (the binary package must depend on a version of the share library package greater than or equal to the current version of the shared library)..

I prefer to hand craft my shlibs file, but some people generate it based on package versions. I do not recommend that practice.

So what happens when you need to bump the SONAME of package libfoo? We change the name of the package containing the shared library libfoo0.deb -> libfoo1.deb, for starters. The full upgrade scenario is slightly more complicated (the next bit is based on a series of messages by A. J. Towns on the debian-devel mailing list):

  1. The main libfoo package should provide the current library, and have no extraneous non-versioned files.
  2. The -dev package name shouldn't change unnecessarily.
  3. A compat package should be in oldlibs only if necessary.

So, starting with

Starting State
libfoo builds libfoo0, libfoo-dev
Simple upgrade

libfoo builds libfoo1, libfoo-dev

This is all that the package itself needs. We have bumped the revision of the library package. We may also bump the Provides for libfoo-dev. This does assume that you hunt down and also upgrade other packages that link with libfoo to the new ABI at the same time. This means getting a list of those packages, making sure the maintainers of those packages know what's happening, filing serious bugs when the old libfoo1.deb package is removed from the archive, and possibly NMUing those packages. Obviously, this means that we should only use this method where there are none or small API changes, and there are very few packages that depend on libfoo. If any code changes were required to those packages, we also need to change their control files to add a Build-Depends on the current version of libfoo-dev.

Ideally, libfoo1 would disappear quickly from unstable. Old versions of any package that depend on libfoo0 would become uninstallable at that point; so there is not much of a transition window.

Simple level of compatibility
The simplest level of compatibility (if it's going to take ages to rebuild all the packages, but they're relatively easy to rebuild, or if important non-Debian/non-free applications require the old version)

libfoo builds libfoo1, libfoo-dev
libfoo0 builds libfoo0

That is, take the old version, and make it only build the lib, not the -dev package and rename the source package. People will automatically build to the new library version, and do not need to add a versioned dependency on the current version of libfoo-dev unless the API change affects their code. Make sure everyone who uses your package knows there's a new ABI to be upgraded to. File wish-list bugs to ensure they know what's going on. File patches to those bugs. If any code changes were required to those packages, also remember to change their control files to add a Build-Depends on the current version of libfoo-dev.

Now libfoo0 sticks around for a while, allowing for a slower rate of recompilation of dependant packages; but still every package that depends on libfoo would be now compiled against the new version of libfoo-devat the next upload, so again, there had better not have been too many API changes (since we are responsible for helping package maintainers in this scenario -- all kinds of packages may fail to build from source due to this change, though the packages in question did not change).

Large installed base, full compatibility
If people need to be able to build packages against the old library as well.

libfoo builds libfoo1, libfoo-dev
libfoo0 builds libfoo0, libfoo0-dev

That is, take the old version, rename its -dev package, and the source package. Move the old library package, and move the new source (libfoo0.dsc) and dev (libfoo0-dev) packages to oldlib. People will automatically build to the new library version, and a special effort has to be made to build to the older revision. The package flex below has a variation on this theme: the libfoo and libfoo0 versions can conflict with and provide the same files, so people can only install one version, but then they do not have to change Makefiles in order to compile.

Make sure everyone who uses your package knows there's a new ABI to be upgraded to. File wishlist bugs to ensure they know what's going on. File patches to those bugs. NMU them to ensure none of them continue to depend on oldlibs libraries. If any code changes were required to those packages, also remember to change their control files to build-depend on the current version of libfoo-dev.

Major API change
If there's a major API change, and packages are continuing to be developed against the old library because, say, the new version has dropped some features as part of a major rewrite that haven't yet been redone, you'll want:

libfoo1 builds libfoo1, libfoo1-dev
libfoo builds libfoo0, libfoo-dev

Note that in this case, libfoo stays the same, and it's a matter of uploading a new libfoo1 source package, that builds .debs under new names. Why? Because you've effectively got a completely new library, old binaries won't work with it, old sources won't build against it, and it doesn't even obsolete the old one. This way of doing things means you don't break any old dependencies, and have complete control over what dependencies (normal or Build-) the new packages satisfy. It also means you only have to wait for one package to be processed through NEW. You should not need this case.

In this case, the default is to build to the older version; people shall have to modify things in order to build to the new library.

In general, having two different versions of dev packages installable simultaneously is only rarely desirable. It wastes disk space, forces people to edit build-depends and potentially makefiles, and generally ends up just being confusing. On the other hand, it is the normal case to have more than one version of the shared library package installed at the same time, so these packages should not have anything in them that is not versioned, so that there is no conflict. In short:

libselinux, libselinux/debian, libselinux/debian/common

Apart from being a package that provides shared libraries, and all the complications thereof, this package is also a multi-binary package --- one package providing the shared libraries for Security-enhanced Linux, one package for the static libraries and header files, and one package for various utility programs for a SELinux system. In more detail:

libselinux1

libselinux1 provides an API for SELinux applications to get and set process and file security contexts and to obtain security policy decisions. Required for any applications that use the SELinux API.

libselinux1-dev

This package provides the static libraries and header files needed for developing SELinux applications.

selinux-utils

This package provides utility programs to get and set process and file security contexts and to obtain security policy decisions.

selinux-utils

This package provides Python bindings to SELinux shared libraries.

The interesting part of this package was the shlibs file handling -- and how the utility package needed to use the shlibs file generated by its sibling shared library package. The other interesting part was how exactly to break up the result of the build into the component packages, and how to handle the shared library symbolic links.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.
  • Static linking toolchain helper. In Debian, dpkg compiles in libselinux statically in order to prevent dependency loops. Now, as libselinux acquired a build time dependency on libsepol, automated dpkg builds failed -- since there was no way for packages to detect the transitive dependencies when linking statically. This branch fixes that issue -- by generating a .pc file to be used with pkg-config.
  • Removing dependency on thread local storage implementation.

    On a number of architectures, glibc 2.4 is not yet stable enough for use (this is the case on mipsel, mips, arm, m68k and hppa). This means that thread local storage is not available on these architectures. A recent change in matchpathcon.c made a static file scoped variable (myflags) thread local -- the reason being, that the file local variable was temporarily modified by a couple of calls, and then reset back; and if any other threads used these variables, or worse, cached a local copy [which would save the modified version], modified it temporarily, and restored the cached version, the value would be corrupted.

    Simply changing the signatures of the calls to pass the variable along, instead of using the file scoped variable, was not viable, since this would change the API and thus the soname of the library.

    The solution in this patch is to keep the function calls as wreappers, and create _real versions of all functions that explicitly pass around the flag variable. All functions call the _real versions of the internal functions in the function body. This makes the myflags variable thread safe again.

Branch and Patch History

libselinux, 152 Kb
libsepol, libsepol/debian, libsepol/debian/common

This is very similar to the libselinux package above -- down to also providing three packages: one providing a shared library for changing binary policies, one package providing the static libraries and header files, and one package providing a utility to rewrite existing mandatory access control policy with different boolean settings. The only think missing are Python bindings. In more detail:

libsepol1

libsepol provides an API for the manipulation of SELinux binary policies. It is used by checkpolicy (the policy compiler) and similar tools, as well as by programs like load_policy that need to perform specific transformations on binary policies such as customizing policy boolean settings.

libsepol1-dev

libsepol allows programs to easily modify SE Linux policy binaries. This means changing the default values for booleans, or reading the policy for analysis. This package contains the headers and archives used for linking it into your programs.

sepol-utils

This package provides utility programs to get and set process and file security contexts and to obtain security policy decisions.

Feature Branches

  • The Debian specific changes branch. This is the branch in which changes are made to make the package conform to Debian practices and policies. Most of these are not likely to be interesting upstream, or are too trivial to rate their own branch.
  • Static linking toolchain helper. In Debian, dpkg compiles in libselinux statically in order to prevent dependency loops. Now, as libselinux acquired a build time dependency on libsepol, automated dpkg builds failed -- since there was no way for packages to detect the transitive dependencies when linking statically. This branch fixes that issue -- by generating a .pc file to be used with pkg-config.

Branch and Patch History

libsepol, 95 Kb
libsemanage,