In this step by step guide, let us see how to build debian packages from source on Debian, Ubuntu and other APT-based systems like Linux Mint.
Debian and Debian-based systems like Ubuntu uses Advanced Package Tool, or APT in short, for installing, updating, upgrading and removing software from command line.
Usually, the APT package manager stores the list of repositories in the file named /etc/apt/sources.list
and in any file with the suffix .list
under the directory /etc/apt/sources.list.d/
.
When we install a package, apt
command retrieves the binary or pre-compiled version of the given package from these repositories.
In addition to installing binary packages, APT can also lets you to download the source code of a package. So you can then add some features in the source, build the package from the source code, and finally install the modified version of the package.
Table of Contents
Why should we build a package from source?
There could be many reasons to build a package from source. Here are a few reasons I could think of now:
- Inspect the source code to find a bug.
- Add new features in the packages that aren't being actively developed any longer.
- Install the most recent version of a package from source. Generally, the packages in the official repositories might be bit old.
- And more importantly - learn to build Debian packages from source.
Install necessary build tools
In order to build a binary package from source, first we need to install necessary build tools. Depending upon the command line tool to build the binary package, you may need to install any one of the following packages:
- dpkg-dev
- devscripts
These packages provides numerous tools to build binary packages from source code.
To install "dpkg-dev"
, run:
$ sudo apt install dpkg-dev
The command to install "devscripts"
package is:
$ sudo apt install devscripts
Enable source repositories
Make sure you have enabled the source repositories.
To do so, open /etc/apt/sources.list
file:
$ sudo vim /etc/apt/sources.list
You will see some lines in it like below:
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to # newer versions of the distribution. deb http://in.archive.ubuntu.com/ubuntu focal main restricted # deb-src http://in.archive.ubuntu.com/ubuntu focal main restricted [...]
In the above file, all the lines beginning with one or two hashes (#) are just comments, for information only. And the lines without hashes are the apt repositories.
In the apt repository lines that starts with "deb" are relative to binary packages, which can be installed using apt package manager by the users. And the lines starts with "deb-src" are relative to source packages. This is useful for developers. By default, the "deb-src" is commented out in the sources list.
To download the source packages, you need to uncomment the "deb-src" line. Remove the # symbol to uncomment a line. After uncommenting, the repository lines should look like below:
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://in.archive.ubuntu.com/ubuntu focal main restricted
deb-src http://in.archive.ubuntu.com/ubuntu focal main restricted
[...]
Save and close the file. Update the repository list using command:
$ sudo apt update
Download source packages
Download the source of a package using "apt source <package-name>"
command. For example, the following command will download the source code of the "Hello World!"
program:
$ apt source hello
Sample output:
Reading package lists... Done Need to get 734 kB of source archives. Get:1 http://in.archive.ubuntu.com/ubuntu focal/main hello 2.10-2ubuntu2 (dsc) [1847 B] Get:2 http://in.archive.ubuntu.com/ubuntu focal/main hello 2.10-2ubuntu2 (tar) [726 kB] Get:3 http://in.archive.ubuntu.com/ubuntu focal/main hello 2.10-2ubuntu2 (diff) [6560 B] Fetched 734 kB in 2s (336 kB/s) dpkg-source: info: extracting hello in hello-2.10 dpkg-source: info: unpacking hello_2.10.orig.tar.gz dpkg-source: info: unpacking hello_2.10-2ubuntu2.debian.tar.xz
As you can see, I have downloaded the source code of Hello World program.
$ ls hello-2.10 hello_2.10-2ubuntu2.debian.tar.xz hello_2.10-2ubuntu2.dsc hello_2.10.orig.tar.gz
View the actual contents of the source code:
$ ls hello-2.10/ ABOUT-NLS ChangeLog INSTALL NEWS README-release aclocal.m4 configure debian lib man tests AUTHORS ChangeLog.O Makefile.am README THANKS build-aux configure.ac doc m4 po COPYING GNUmakefile Makefile.in README-dev TODO config.in contrib hello.1 maint.mk src
Install build dependencies for the package
Next, we need to install the dependencies for that package as well. To do so, run:
$ sudo apt build-dep hello
We have now downloaded the source code of the package and installed the dependencies required to build this package. Next do the changes in the source code.
Modify source code of a debian package
Cd into directory that contains the package source. In our case, it is hello-2.10.
$ cd hello-2.10
Modify the code as per wish. The code is in the file "hello.c"
under "src"
directory.
$ vi src/hello.c
Tweak the code and/or make any changes. Once done editing the code, save and close the file.
Now is the time to build the actual .deb package.
Build Debian packages from source
We downloaded source code and modified the code. Let us build the package from source. We can do this in three ways:
- Using
"dpkg-buildpackage"
command - Using
"debuild"
command - Download the source and build it directly
Method 1 - Using dpkg-buildpackage:
Make sure you have installed "dpkg-dev"
package.
And then run the following command to build the package from source:
$ dpkg-buildpackage -rfakeroot -b -uc -us
Here,
dpkg-buildpackage
- Command to build binary or source packages from sources.-rfakeroot
- Create fakeroot environment to simulate root privileges (for avoiding ownership and permission issues).-b
- Build the binary package only.-uc
- Don not cryptographically sign the changelog. i.e. Do not sign the.buildinfo
and.changes
files-us
- Do not sign the source package.
Please make sure that you run the above command in the main directory of the source tree. Otherwise, it won't work.
If the build is successful, you will see a message like below:
[...]
dpkg-deb: building package 'hello' in '../hello_2.10-2ubuntu2_amd64.deb'.
dpkg-deb: building package 'hello-dbgsym' in 'debian/.debhelper/scratch-space/build-hello/hello-dbgsym_2.10-2ubuntu2_amd64.deb'.
Renaming hello-dbgsym_2.10-2ubuntu2_amd64.deb to hello-dbgsym_2.10-2ubuntu2_amd64.ddeb
dpkg-genbuildinfo --build=binary
dpkg-genchanges --build=binary >../hello_2.10-2ubuntu2_amd64.changes
dpkg-genchanges: info: binary-only upload (no source code included)
dpkg-source --after-build .
dpkg-buildpackage: info: binary-only upload (no source included)
Congratulations! We have successfully built a .deb package from source. Now, go back to the parent directory and you will see newly built .deb file:
$ cd ..
$ ls
Sample output:
hello-2.10 hello_2.10-2ubuntu2.dsc hello_2.10-2ubuntu2_amd64.deb
hello-dbgsym_2.10-2ubuntu2_amd64.ddeb hello_2.10-2ubuntu2_amd64.buildinfo hello_2.10.orig.tar.gz
hello_2.10-2ubuntu2.debian.tar.xz hello_2.10-2ubuntu2_amd64.changes
Method 2 - Using debuild
Make sure you have installed the "devscripts"
package.
Then, build the binary package by running the following command from the source tree:
$ debuild -b -uc -us
Upon successful build, the resulting .deb
package will be saved in the parent directory.
Method 3 - Download and build directly
This is easiest and straight forward method than the above two methods. In this method, we download the source code of the package and pass the "--compile"
option to build the binary in a single command line below:
$ sudo apt-get source --compile hello
The above command will download the source code of "hello"
program and build the .deb
package and save it in the current directory.
Install the .deb file
Go to the location where the .deb
file is saved and install it like below:
$ sudo dpkg -i hello_2.10-2ubuntu2_amd64.deb
If you see any missing dependencies error message, run:
$ sudo apt install -f
As you can see, building a debian package from source in Linux is very easy!
Hope this helps.
8 comments
nice article. step by step process loved it
Thanks. I noticed you copied our guides and posted them on your blog. Please remove them. Make your own original guides.Hope you understand.
So method 3 can only be used to “compile” the binary .dep from the unchanged downloaded source package. Why should I do this instead of downloading the binary package?
The method 3 will not download the binary hello.deb file. Instead, it will pull the source package, compile it and build hello.deb package in the current working directory.
Can I change the compiler used to compile the source packages
Good article. But you might tell us about the pros and cons of dpkg-buildpackage vs. debuild.
Also, if someone wants to change the code before compiling it, I have discovered that there is more work involved, at least for the debuild method. Maybe you can comment on the easiest way to make your own changed version?
Hello Jim, I am not a programmer by the way. I just discovered these tools on Reddit, worked out in my system and made this guide as per my understanding. So I can’t comment on your question. My apologies.
I’ve seen three of these “tutorials” and none explain why it fails with a missing debian/changelog, why it’s looking for a debian directory at all, or what that changelog file should contain. The man page for dpkg-buildpackage also neglects to mention this file anywhere at all. Sure I could touch it and see what happens, but that’s not really learning, is it?