swirlbuild(5) | File Formats Manual | swirlbuild(5) |
swirlbuild
— the
swirlbuild packager manual
This manual includes all informations to create and maintain a
swirl, as well as details about swirlbuild
. It tries
to be exhaustive, but cannot replace practice and analysis of already
existing swirls.
Looking at swirls/oksh is a good point to get started. USUAL WORKFLOW describes a typical workflow when creating a swirl, with a real-life example.
If you want to build a swirl as a simple user, please read buildswirl(1).
The general idea of swirlbuild
is to give
you a lot of freedom to turn around its limitations. It will not stop you
from doing stupid things, not many checks are done.
$SWIRLBUILD is used in this documentation to
represent the root directory of swirlbuild
, where
the buildswirl(1) script can be
found.
Buildfiles, known as
swirls/<swirlname>/build are simple shell
scripts sourced by swirlbuild
. As such, standard
shell conventions apply when it comes to quoting, and all our usual shell
utilities can be used inside of it.
dash(1) as
/bin/sh is implied. Note that using utilities out of
the Debian base utilities and packages pulled during the deployment of
swirlbuild
should be avoided, and otherwise
safeguards should be added to tell the user to install said utilities.
It's recommended to use the same ordering used in $SWIRLBUILD/build.template.
Presented in alphabetical order.
ARCH
(readonly) The current architecture
swirlbuild
is being run on, according to
dpkg-architecture(1).
You can use it in your buildfile if you need particular things for a
given architecture.
BREAKS
(facultative) If your swirl breaks another package(s), put the package(s) here. It is here for convenience but should be used as a last resort. See BUILD_DEPENDS about the format used, and deb-control(5) for more informations.
BUILD_DEPENDS
(facultative) The build and test dependencies. This is a multiline shell string, with one dependency per line. Blank lines are ignored. The versioning scheme is described in deb-src-control(5), and a full example can be found in infrastructure/templates/build.template.
Note that dh_make(1)
tends to add the configure/build system as a BUILD_DEPENDS out of the
box. There is no TEST_DEPENDS
in
swirlbuild
, you must specify them in
BUILD_DEPENDS.
If your swirl depends on another swirl, see SWIRL_DEPENDS.
CONFLICTS
(facultative) If your swirl conflicts with an official Debian package, put the Debian package here and it will be added as a conflict. It is here for convenience but should be used as a last resort. See BUILD_DEPENDS about the format used.
DESCRIPTION
(mandatory) A description for your package. This string should
be 1 line long at least, but can span on several lines. The first
non-empty line will be the description that will appear in
dpkg
-l
. It should not
be longer than 60 characters.
(facultative) The following lines are the long description
that are shown when using apt
show <PKGNAME>
. When in doubt, look at
infrastructure/templates/build.template.
EPOCH
(facultative) Epoch number of the swirl. Its value is 0 by default and is implied if not added to the buildfile. If it appears that the upstream versioning scheme changed and dpkg(1) does not see the new version as newer than the old version, you need to increment EPOCH by one. See also VERSION.
EXTRA_SOURCES
(facultative) a list of extra sources to download. This is a multiline shell string, with one URL per line. Blank lines are ignored. An example of that can be found in infrastructure/templates/build.template.
They are not extracted, just downloaded by curl(1) in $SWIRLDIR/distfiles/{PKGNAME}-{VERSION} and eventually checked against a checksum as described in THE CHECKSUM FILE. You can work with them later thanks to a prebuild hook. See also SOURCE, and comments in the download hook if these extra sources cannot be extracted by bsdtar(1), which should be used as the default extractor.
GO_IMPORT_PATH
(mandatory for golang modules) The import path of the go module. This must match the "module" line that can you find in the source's go.mod. See unmaintained-swirls/golang-helloworld for an example.
HOMEPAGE
(mandatory) The upstream www homepage. If there is none, leave this empty, but not undefined.
LICENSE
(mandatory) The license file(s) that can be found in upstream tarball. These are relative to the root of the sources or absolute, separated by space(s). If files have spaces or special characters, you should quote them. They are concatenated with one blank line between each others in debian/copyright. If the files mentioned in LICENSE are non-existant buildswirl(1) will immediatly exit with a failure. There are more informations about this in Providing a license in the package is mandatory.
MAKE_JOBS
(facultative) By default, swirlbuild
will use a number of build jobs that is equal to the
nproc(1) output. Sometimes this is
not adequate, for example if the software you are building does not
support parallel processing or takes too much memory. MAKE_JOBS defines
the number of parallel jobs during different steps of the build. By
convention, if some software needs 4GB of RAM or more by job
consistently put MAKE_JOBS=1.
Adding a comment about why MAKE_JOBS is used is considered good practice.
OVERRIDE_SRCDIR
(facultative) The extracted SOURCE tarball directory is supposed to be in the {PKGNAME}-{VERSION} format. If it is not (github for example), you can override the source directory by defining that variable.
PKGNAME
The generated Debian package name. It is discouraged to clash
your package name with Debian, if needed add a suffix, for example vim
-> vim-swirl. Most often you want to use the official tools for
customising an official package, using
swirlbuild
for that is discouraged.
The Debian
wiki has a tutorial for this.
PROVIDES
(facultative) If your swirl provides a virtual package, put the package(s) here. See BUILD_DEPENDS about the format used, and deb-control(5) for more informations.
REPLACES
(facultative) If your swirl overwrites another package's files, put the filenames here. This one is supposed to be used with CONFLICTS. and should be used as a last resort. See BUILD_DEPENDS about the format used, and deb-control(5) for more informations.
REVISION
(mandatory) There are swirl revisions, not Debian ones. They start at 1, and should be incremented if you need to modify a package without changing VERSION. If VERSION is changed, REVISION should be brought back to 1.
Debian revisions are not supported because
swirlbuild
´s simplicity is leading us to
not use the 3.0/quilt format but the native one, and we should not mess
with Debian proper mechanics. For more informations about Debian package
formats, see
dpkg-source(1).
RUN_DEPENDS
(facultative) Runtime dependencies, in the same format and
restrictions than BUILD_DEPENDS.
There is no LIB_DEPENDS
in
swirlbuild
, there are generated during the
Debian package creation if binaries are produced AND libraries linked.
If not, like dh_python(1)
managed builds, library dependencies should be mentioned in
RUN_DEPENDS.
If your swirl depends on another swirl, see SWIRL_DEPENDS.
SOURCE
(facultative) The source tarball download location. It supports all protocols supported by curl(1), and it will be extracted by bsdtar(1) that supports the following archive formats (or use "apt show" on your version of libarchiveNN).
Only one source is allowed by dh_make(1). If you need more files to download, see EXTRA_SOURCES. OVERRIDE_SRCDIR explains the expected directory format of the extracted archive and how to cope when it is not compliant.
SOURCE can be checked against a checksum, see THE CHECKSUM FILE.
SWIRL_DEPENDS
(facultative) Unused for now. If your swirl depends on other swirls, just add them to this variable in the format explained in BUILD_DEPENDS, with dependencies by order of precedence. Note that you still need to mention said depends packages name in BUILD_DEPENDS and RUN_DEPENDS. The paths must be relative to $SWIRLBUILD. For an example of this, see infrastructure/templates/build.template.
VERSION
(mandatory) The upstream version of the package. The local package version will be: [{EPOCH}:]{VERSION}+swirl{REVISION}.
Debian versioning scheme is explained at deb-version(7). You can compare versions with the dpkg(1) --compare-versions flag. If it appears that the upstream versioning scheme changed and dpkg(1) does not see the new version as newer than the old version, see EPOCH.
Hooks are a fairly advanced topic, and should be used only as a last resort, unless you just want to package some local files.
They are simple shell functions that can be used for various intents. You could override internal (starting with an underscore) functions, but this is a recipe for disaster. Internal variables not detailed here should not be used as well.
The following shell variables from buildswirl(1) can be used in your hooks:
The temporary directory where the upstream source and the generated dh_make(1) files are present.
The directory where the upstream source is. The debian/ directory is a subdirectory of it, see also THE DEBIAN SUBDIRECTORY .
The directory where the current buildfile being used is located.
The directory where the files downloaded by SOURCE and EXTRA_SOURCES can be found. Useful in a prebuild hook.
Here are the available hooks:
download
()Avoid using it for publicly distributed swirls, because we cannot get any checksum.
Substitute the usual source download and extraction by your own. This can be useful to create a package from local files, or use alternative download methods. At this stage, $swirldir, $distdir and $tmpdir are defined, but not $srcdir.
Everything is up to you, but the good practice is to create the ${tmpdir}/${PKGNAME}-${VERSION} directory and put files into it. Downloads should be made with curl(1). If you need a "fetcher" other than curl(1), you will need to put a safeguard asking the user to install "fetcher" on their build machine. Same for the extractor used. A simple example of this hook can be found in $SWIRLBUILD/unmaintained-swirls/justsomefiles/build.
prebuild
()Run some custom actions before the source package build. This is useful to inject files from your buildfile's files/ directory, notably a Makefile.
This is also where you can work on your EXTRA_SOURCES files that are placed in ${distdir}.
Example of this hook can be found in unmaintained-swirls/findfiles.
postbuild
()Run a custom action after the package build and repository update. Unused, but it is meant to be used to display some message to users after the build if needed.
There are meant to be used not only when you create a swirl. Final users can also make use of them as environment variables. It is recommended to keep them around in the build file until you have finished your work.
Here is the list of available debug variables:
DEBUG_SOURCE
If you define DEBUG_SOURCE, the build will stop before building the binary package and open a shell, where you can debug issues in your patches, debian/ files and so on. As soon as the shell is exited, the temporary directory is removed. That is necessary if you need to add a patch to your swirl.
At this stage the source tarball than
pbuilder(8) will use is already
generated as you can see if you enter the debug source shell. The
SWIRLDIR
environment variable is set and points
to the current swirl directory.
DEBUG_RMPKG
Build a package even though it is already built. You should not use it if said package version and revision has been installed somewhere. It is here in case it appears that your built package has some issues like misplaced files.
Actually it is lowercase. Whatever is present in this directory will override what dh_make(1) did.
The Debian Maintainer Guide contains a lot of informations about what can be used to make your building process easier, simply by defining some files, like adding users, services, documentations etc.
The whole swirlbuild
tree has many
examples for these files.
Try your best to use the "facilities" provided by this directory. Using them is more future proof than injecting a Makefile through prebuild.
It is mandatory to include the software license, and/or the end user license agreement (EULA), and potentially other files required by upstream into the produced package if you intend to make your swirl public, and as such being used by third parties.
As mentioned in the documentation for
LICENSE this variable must point to valid
license file(s). swirlbuild
does not include license
markers to avoid misinterpretation of upstream licensing terms. Here are
some special cases when upstream does not provide some valid license
file(s). That list may grow over time.
LICENSE
.This matters for users, in case they inavertendly distribute generated Debian packages to the general public, given that the full license text and the SOURCE URL are provided in /usr/share/doc/<PKGNAME>/copyright, it respects said license conditions in many, but not all, cases.
This matters for swirls creators, in case upstream's licensing file layout is not clear and the license is misrepresented in your swirl, then contested by upstream. Upstream got to do their homework and provide either a single license file or location including all the possible licences used in their software source code. Veracrypt and PPSSPP are good examples of that.
See also LEGAL in swirlbuild(7).
This is where you can drop various files needed to the build. Note that these files are not automatically added to the build. Using the prebuild hook is recommended to do so. A good example is unmaintained-swirls/findfiles.
This is lowercase as well.
swirlbuild
has a very basic patching
system. Every file ending with the patch extension
in the patches directory of the swirl is considered
a patch to be applied. Patches management is fully manual.
Patches from VCS like git(1) cannot be pushed as is. Creating patches for swirls is shown in USUAL WORKFLOW.
Lowercase as well, this file should be present if you distribute your swirl. This contains the checksum of the downloadable SOURCE and EXTRA_SOURCES.
If SOURCE is not defined, that file is totally ignored.
While you can generate it manually with sha512sum(1), buildswirl(1) includes an option to generate it, and its usage is detailed there.
Here is the list of everything included in $SWIRLBUILD.
Present in that list for exhaustivity
Contains mostly documentations and helper scripts.
This script is a small helper that installs necessary packages
for swirlbuild
operation.
Build all the swirls in swirls/. Used for development tests, do not try this at home.
Update your repository if some packages have been removed from there. Usage is detailed in buildswirl(1).
It is also used internally by buildswirl to update the repository indices after a successful build.
All the manpages for swirlbuild
.
All the manpages for swirlbuild
in
HTML format. They're up to date with the manpages, since i use them a
lot, thanks to infrastructure/docs/Makefile.
Some pbuilder(8) hooks, whose names clearly indicates the intent. See its manpage for the format used.
Templates that you may need when creating a swirl.
swirlbuild
generates logs for every
build thanks to
pbuilder(8).
Files included in this directory are not tracked by
git(1). If you want to put personal
swirls inside your copy of the swirlbuild
repository, you can put them there.
All the officially maintained swirls. They are demo for the project.
These swirls are probably out-of-date, finally officially packaged, or kept as examples to show x or y feature. And also probably broken.
The status of every unmaintained swirls, and what they are featuring that can be interesting for your own swirls.
See also BUILDFILES DEBUG VARIABLES.
DEBEMAIL
Used by dh_make(1) and pbuilder(8). This defines the maintainer email address present in the package.
DEBFULLNAME
Used by dh_make(1) and pbuilder(8). This defines the maintainer firstname, lastname present in the package. By default, it tries to fetch that from your account infos.
buildswirl(1) details
basic informations on how to build a swirl and several maintenance tips.
swirlbuild(7) is an intro to
swirlbuild
and details its deployment, scope,
motivations and caveats.
The Debian Maintainer Guide is a good basic reference, as well as the debhelper(7) manpage.
pbuilder(8) maintains its
own apt(8) cache.
swirlbuild
does not clean the
/var/cache/pbuilder/result directory as well. You
can clean up by using:
sudo pbuilder clean sudo rm /var/cache/pbuilder/result/*
By default pbuilder(8)
cannot access to any network when starting to build a package.
This is not the case in the
swirlbuild
system. This avoids
packaging dozen of crates or go modules simply by using cargo and "go
build" in a Makefile.
The ca-certificates package should added as a BUILD_DEPENDS if you encounter TLS certificate errors during the build.
If the build fails a shell will be opened in the pbuilder(8) chroot, and will get you to the source directory of the package. vi(1) will be installed. That can help you see the reason for a failure. Quitting that shell will destroy the chroot. It is a hook than can be found at infrastructure/pbuilder/hooks/C99build_open_debug_shell.
You can trigger the pbuilder(8) failure shell for any dh_*(1) command, with a specially crafted debian/rules file, allowing you to debug the build. An example can be found at $SWIRLBUILD/infrastructure/templates/rules.template.
I will go with a non trivial yet easy real world example that can
you find at $SWIRLBUILD/swirls/badwolf. This is
lengthy because i wanted to showcase a lot of things
swirlbuild
can propose.
cd your_swirlbuild_root_directory mkdir swirls/badwolf && cd swirls/badwolf cp ../../infrastructure/templates/build.template build # modify the buildfile to something that looks sensible # and uncomment DEBUG_SOURCE=1 in the build file. While # here add the checksum file. ../../buildswirl $PWD checksum ../../buildswirl $PWD exit # This looked okayish out of the box. Comment DEBUG_SOURCE=1 and try the build. ../../buildswirl $PWD # dh_auto_clean # make -j12 distclean # Failed with Error: You need to execute ./configure before running make # I'll need to override dh_auto_clean mkdir debian cp ../../infrastructure/templates/rules.template debian/rules # I edit debian/rules and try again ../../buildswirl $PWD # Missing dependencies, so editing the buildfile again ../../buildswirl $PWD # dh_usrlocal: error: debian/badwolf/usr/local/bin/badwolf is not a directory # I will need to change PREFIX in debian/rules, also the configure script # asked for more changes, to specify some extra environment options ../../buildswirl $PWD # It builds! But I have found out by inspecting the built package with # xarchiver that BadWolf installs its documentation where it should not. I # should override that destination directory with an environment variable in # debian/rules, but for the sake of the demonstration, I will make a patch. # Also I set up DEBUG_RMPKG=1 in the buildfile. env DEBUG_SOURCE=1 ../../buildswirl $PWD cd badwolf-1.2.2 cp configure{,.orig} # I change the DOCDIR variable to what we need in configure, # then check the result: diff -u configure{.orig,} # Looks good, time to add it as a patch and exit: mkdir $SWIRLDIR/patches diff -u configure{.orig,} > $SWIRLDIR/patches/fix_documentation_path.patch exit # This should be our final build! ../../buildswirl $PWD # After inspection it is fine. I remove all the unnecessary comment stuff in # build. Time to test the runtime and have fun! sudo apt update sudo apt install badwolf
May 13, 2025 | Debian stable |