Howto to rebuild Debian packages

Being able to rebuild an existing Debian package is a very useful skill. It’s a prerequisite for many tasks that an admin might want to perform at some point: enable a feature that is disabled in the official Debian package, rebuild a source package for another suite (for example build a Debian Testing package for use on Debian Stable, we call that backporting), include a bug fix that upstream developers prepared, etc. Discover the 4 steps to rebuild a Debian package.

1. Download the source package

The preferred way to download source packages is to use APT. It can download them from the source repositories that you have configured in /etc/apt/sources.list, for example:

deb-src http://ftp.debian.org/debian unstable main contrib non-free
deb-src http://ftp.debian.org/debian testing main contrib non-free
deb-src http://ftp.debian.org/debian stable main contrib non-free

Note that the lines start with “deb-src” instead of the usual “deb”. This tells APT that we are interested in the source packages and not in the binary packages.

After an apt-get update you can use apt-get source publican to retrieve the latest version of the source package “publican”. You can also indicate the distribution where the source package must be fetched with the syntax “package/distribution“. apt-get source publican/testing will grab the source package publican in the testing distribution and extract it in the current directory (with dpkg-source -x, thus you need to have installed the dpkg-dev package).

$ apt-get source publican/testing
Reading package lists... Done
Building dependency tree       
Reading state information... Done
NOTICE: 'publican' packaging is maintained in the 'Git' version control system at:
git://git.debian.org/collab-maint/publican.git
Need to get 727 kB of source archives.
Get:1 http://nas/debian/ squeeze/main publican 2.1-2 (dsc) [2253 B]
Get:2 http://nas/debian/ squeeze/main publican 2.1-2 (tar) [720 kB]
Get:3 http://nas/debian/ squeeze/main publican 2.1-2 (diff) [4728 B]
Fetched 727 kB in 0s (2970 kB/s)  
dpkg-source: info: extracting publican in publican-2.1
dpkg-source: info: unpacking publican_2.1.orig.tar.gz
dpkg-source: info: unpacking publican_2.1-2.debian.tar.gz
$ ls -dF publican*
publican-2.1/                 publican_2.1-2.dsc
publican_2.1-2.debian.tar.gz  publican_2.1.orig.tar.gz

If you don’t want to use APT, or if the source package is not hosted in an APT source repository, you can download a complete source package with dget -u dsc-url where dsc-url is the URL of the .dsc file representing the source package. dget is provided by the devscripts package. Note that the -u option means that the origin of the source package is not verified before extraction.

2. Install the build-dependencies

Again APT can do the grunt work for you, you just have to use apt-get build-dep foo to install the build-dependencies for the last version of the source package foo. It supports the same syntactic sugar than apt-get source so that you can run apt-get build-dep publican/testing to install the build-dependencies required to build the testing version of the publican source package.

If you can’t use APT for this, enter the directory where the source package has been unpacked and run dpkg-checkbuilddeps. It will spit out a list of unmet build dependencies (if there are any, otherwise it will print nothing and you can go ahead safely). With a bit of copy and paste and a “apt-get install” invocation, you’ll install the required packages in a few seconds.

3. Do whatever changes you need

I won’t detail this step since it depends on your specific goal with the rebuild. You might have to edit debian/rules, or to apply a patch.

But one thing is sure, if you have made any change or have recompiled the package in a different environment, you should really change its version number. You can do this with “dch --local foo” (again from the devscripts package), replace “foo” by a short name identifying you as the supplier of the updated version. It will update debian/changelog and invite you to write a small entry documenting your change.

4. Build the package

The last step is also the simplest one now that everything is in place. You must be in the directory of the unpacked source package.
Now run either “debuild -us -uc” (recommended, requires the devscripts package) or directly “dpkg-buildpackage -us -uc”. The “-us -uc” options avoid the signature step in the build process that would generate a (harmless) failure at the end if you have no GPG key matching the name entered in the top entry of the Debian changelog.

$ cd publican-2.1
$ debuild -us -uc
 dpkg-buildpackage -rfakeroot -D -us -uc
dpkg-buildpackage: export CFLAGS from dpkg-buildflags (origin: vendor): -g -O2
dpkg-buildpackage: export CPPFLAGS from dpkg-buildflags (origin: vendor): 
dpkg-buildpackage: export CXXFLAGS from dpkg-buildflags (origin: vendor): -g -O2
dpkg-buildpackage: export FFLAGS from dpkg-buildflags (origin: vendor): -g -O2
dpkg-buildpackage: export LDFLAGS from dpkg-buildflags (origin: vendor): 
dpkg-buildpackage: source package publican
dpkg-buildpackage: source version 2.1-2rh1
dpkg-buildpackage: source changed by Raphaël Hertzog 
 dpkg-source --before-build publican-2.1
dpkg-buildpackage: host architecture i386
[...]
dpkg-deb: building package `publican' in `../publican_2.1-2rh1_all.deb'.
 dpkg-genchanges  >../publican_2.1-2rh1_i386.changes
dpkg-genchanges: not including original source code in upload
 dpkg-source --after-build publican-2.1
dpkg-buildpackage: binary and diff upload (original source NOT included)
Now running lintian...
Finished running lintian.

The build is over, the updated source and binary packages have been generated in the parent directory.

$ cd ..
$ ls -dF publican*
publican-2.1/                    publican_2.1-2rh1.dsc
publican_2.1-2.debian.tar.gz     publican_2.1-2rh1_i386.changes
publican_2.1-2.dsc               publican_2.1-2rh1_source.changes
publican_2.1-2rh1_all.deb        publican_2.1.orig.tar.gz
publican_2.1-2rh1.debian.tar.gz

Do you want to read more tutorials like this one? Click here to subscribe to my free newsletter, you can opt to receive future articles by email.

Additional Resources

Get the Debian Administrator's Handbook

After a successful liberation campaign, the Debian Administrator's Handbook is now freely available. If you appreciate my articles and what I do for Debian, check out the book and grab a copy.

Comments

  1. At some point I recall having to use debuild -i, to avoid editor backup files and version control metadata (I like putting the extracted tree in git so I can see what I’ve changed) in the source package that is built. Is this still a good idea, or do new versions of the tools skip random junk by default?

    • Source packages using the latest “3.0 (quilt)” and “3.0 (native)” formats do not have this problem anymore, the -i -I options are enabled by default for them.

      For the old (“1.0″) source format, it’s still needed.

  2. What does debuild do that dpkg-buildpackage doesn’t? I’ve always wondered this.

    • It calls lintian after dpkg-buildpackage so that you can verify that your package doesn’t contain common mistakes/problems. It also uses debsign to sign the .changes and .dsc (but we disabled that here with -us -uc).

      And it generates a log of the build process in a .build file. It also sanitizes the environment in which dpkg-buildpackage is called (i.e. only a few environment variables are kept).

      Compare the manual pages if you want to know everything. :-)

  3. Sami Liedes says:

    I think mk-build-deps (from package devscripts) is worth mentioning. Especially when invoked with `mk-build-deps -i’, it creates a package (named like $PACKAGE-build-deps) that depends on all the build-dependencies of the package and installs it. Then you can later remove the extra cruft by just removing that package, while with apt-get build-dep you don’t have this option.

    • Actually you can do something like this with apt-get. Put the snippet below in /etc/apt/apt.conf.d/local and any package installed by “apt-get build-dep” will be marked as automatically installed and will be removed by the next “apt-get autoremove”.

      APT::Get::Build-Dep-Automatic true;
      
  4. I Think it’s better when building with pbuilder or at chroot and keep your system clean

  5. I would also love to see how this is done from a slightly-less system bloating way :) I’m very comfortable packaging on distros like slackware, that already include a full tool chain and depenency set out of the box, but on debian, I like to try and keep my system relatively clean regarding the package set. So, I often avoid building packages there, since I don’t want to add the toolchain and a load of dependencies on to a near-perfect setup :) I’d love to see the best way to achieve perhaps building a minimal chroot environment to produce the same package.

  6. Guillermo Garron says:

    I was suppose to cover this topic since Monday, but the video card of my debian pc got burned :(
    I’ve recently fix it as I have not much time these days.
    Finally I’ve published it at: http://www.go2linux.org/linux/2010/12/how-compile-sources-ubuntu-or-debian-871
    But yours have more info, I’ll put a link to this post at the end of mine.

    Thanks

  7. Hi!

    Thank you for the post, it’s really nice and useful! I just rebuild coreutils with Advanced Copy patch using your guidelines.

    I translated post into Russian and posted in my blog. There’s a link to your article at the beginning of translation, so I think you won’t mind.

    Thanks one more time, and keep posting that nice pieces of knowledge ;)

  8. Debian novice says:

    I’m trying rebuild from testing(wheezy) to stable(squeeze), in source.list:
    deb-src http://ftp.us.debian.org/debian/ testing main contrib non-free
    apt-get update
    apt-get source -t testing terminator
    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    E: Ignore unavailable target release ‘testing’ of package ‘terminator’
    E: Unable to find a source package for

    Why this error? Possible fix?