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 Hertzogdpkg-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.
Marius Gedminas says
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?
Raphaël Hertzog says
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.
anonymous says
What does debuild do that dpkg-buildpackage doesn’t? I’ve always wondered this.
Raphaël Hertzog says
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. 🙂
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.
Raphaël Hertzog says
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”.
udienz says
I Think it’s better when building with pbuilder or at chroot and keep your system clean
Hadret says
Definitely!
andrew says
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.
Raphaël Hertzog says
Andrew, there are many solutions to this: sbuild, pbuilder, manual building in a dedicated chroot setup with debootstrap, etc. I’ll probably cover the topic in a future article.
Tobias says
Try pbuilder or even cowbuilder 🙂
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
Alexander Batischev says
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 😉
Raphaël Hertzog says
Alexander, thanks for the translation and the kind words!
Hadret says
I believe it would be good idea to provide some license note regarding your posts here. I’d love to translate your post too, to Polish this time (:
Raphaël Hertzog says
Hadret, go ahead with your polish translation. I will try to create a license page at some point to clarify how the content can be reused but in general I like to know when people use my work, so I appreciate to be asked/informed instead of giving a permanent authorization to do everything.
Hadret says
I believe that’s exactly how Creative Commons licenses work (:
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?
Debian novice says
Replying myself,
You need add to sources.list deb+deb-src line too:
deb http://ftp.us.debian.org/debian/ testing main contrib non-free
deb-src http://ftp.us.debian.org/debian/ testing main contrib non-free