Important: This tutorial is about creating Debian package for Ada Linux Packages Repository, not the official Debian packages. It uses greatly simplified way to create a package which will be not follow Debian Package guidelines or even guidelines for Ada packages for Debian. It may change over time. Also, this tutorial is in early stage of work. If you have any questions or ideas about it, feel free to contact with me. Below you will find the list of changes to the document.
Before start creating a package, it is a good idea to prepare your workshop. The best option is to work inside of a Docker container. It will allow you to keep your system clean, but also will be easier to find all required packages to build the project. As the example here, I will use, an existing package bob.
The most important thing needed to create a package is of course its content. In this situation it will be an archive file with the source code of the future package. Now one important note: Debian has requirement how that file and its content should be named:
During the tutorial, to make things easier we will be using a few Debian
Package Maintainer tools, which should be installed inside the Docker image.
Exactly two programs:
debuild and their dependencies. It is a
good idea to create a Docker image with them, because they will always be
needed, no matter what package we create.
You will also need any text editor. Some of them have even syntax highlighting for Debian packages files. We will be using NeoVim for that.
If you use a Docker image to create the package, please install also all packages required for build your package. In our example it will be:
apt install -y gnat gprbuild
The first we start with creating empty Debian package with the default settings. Unpack your program source code to the same directory where the archive file is. In our example it will be:
tar -xf bob-3.1.tar.gz
Next, would be good to start our Docker image. :) It can look in that way (replace the name of image (ubuntu:21.10) with your Image name):
sudo docker run --rm -it -v $(pwd):/app -w /app ubuntu:21.10 /bin/bash
Enter the uncompressed directory and create the template directory for the package:
cd bob-3.1 debmake
And that's all, now it is time to set basic information about our package.
debmake created a new directory in our source code directory,
called debian. It contains all needed files to create a Debian package. This
tutorial will not explain everything. If you want more information, please go
to proper Debian wiki page.
Now we enter the debian directory and start editing the file control:
cd debian nvim control
We start with changing Section of the package. It is important, because if we don't do it, the package will not build. All available options are listed here. In our example we set it to utils
Next, the Maintainer field. It should have value
Your Name <[email protected]>
Maintainer: Bartek thindil Jasicki <[email protected]>
The next field is the most important and sometimes the hardest to fill:
Build-Depends. It contains names of all Debian packages needed for build our
package. It can be listed in one line, but it is more convenient to have each
package in a separated line. Important: always include the default line,
don't remove it. In our example we need only two packages:
gprbuild (also default version).
Build-Depends: debhelper-compat (= 12), gprbuild, gnat
Notice: Each new line should start with one space. This informs the build system that it is continuation of the previous line. The last comma is simply ignored. The next field to change is Homepage. Enter here your main project page address:
As our example doesn't need any additional packages to run, don't change anything in Depends field. If your program depend on another package(s) you will have to add them here in the same way as we modified Build-Depends field.
The last thing to change in this file is to set field Description for the package.
Description: Bob is a Non-Intelligent console assistant. Bod doesn't try to replace any existing shells or build systems. It is designed to extend them. Often when you have few projects to work, they use different commands or build systems to maintain. To organize it, often you have to add or global aliases to your shell or create scripts which grow over time to maintain it. Bob trying to solve this problem by adding the ability to create local aliases for each directory. It is doing this by creating configuration files (in YAML) with defined aliases in each directory. When Bob is executed in a selected directory, it reads configuration file (if exists) for selected directory for aliases.
Notice: Also here, each new line should start with one space. This informs the build system that it is continuation of the previous line.
Now, save the control file and let's move to the next. More information about the fields in the file you can find here.
Now we start editing the file rules
Generally, this file is standard GNU Makefile. It contains commands which will be executed during creating the package, like configuring, build and installing the files. At the start it is a good idea to remove all unneeded comments from the start of the file as the comment there suggest. After that we can start modifying it to our needs. IMPORTANT: use only Tab in that file for indentation. In other case it will not works. The build program will report invalid file. If the example contains spaces, you will have to manually convert them to tabs. This is the reason why it is better to use a text editor with support for Debian packages (like Vim or Emacs). They automatically change all indentation in rules file into tabs. In the examples here, spaces are used, thus if you copy and paste them to your rules file you will have to convert them to tabs.
The first, we overwrite the default build action. Because our package uses gprbuild with custom variables, we have to set our own build command. Add at the end of the file lines:
override_dh_auto_build: gprbuild -P bob.gpr -XMode=release
The second thing, is to install our build binary in proper location. During
creation of a package, all files which later should be installed from the
package are located in debian/packagename/ directory. In our example it will
be debian/bob/ directory. We have to create it, with a proper Linux directory
tree structure and then put our binary there. Because we don't use for this
make install command, we have to override it, in the same way as we
have done it with the build command. Add at the end of the file lines:
override_dh_auto_install: mkdir -p $(CURDIR)/debian/bob/usr/ mv $(CURDIR)/bin $(CURDIR)/debian/bob/usr/
The last step is optional but useful. We override in it the default clean action. It is used at start and end of the build the package process. It can be useful if we will rebuild the package again. To do it, add at the end of the file lines:
override_dh_auto_clean: gprclean -P bob.gpr
That's all here. Save the file.
This is also important step during creating a package. The version number from the changelog file is used to create versioning for the package. The version number is in parentheses in the first line. In our example, it is 3.1-1. 3.1 is official version of the program, 1 is the first release as Debian package. When we will update the existing package of the same version, we should change this number and add a new changelog entry for it. In our example we can change word UNRELEASED (as a name for Debian version) to impish (the name of the current Ubuntu version). This step is optional. Also, it is good idea to change the entry of changelog to just:
* Initial release
And update our contact information, automatically generated by
command. Again, save the file. We finished setting our package. :)
If we set everything properly, and we gathered all needed prerequisites for the
package, the build process should be automatic and straightforward. In the main
directory of source code (outside debian directory) execute
command. If you are still in debian directory it will look that:
cd .. debuild -d
-d isn't needed, especially during the first try to build the
package. It instructs the build system that it is allowed to overwrite any
existing files like previously created .deb packages etc. If you build the
package inside container, there will be errors about lack of GPG key. Don't
worry about it, for Ada Linux Package Repository it is even better (look below
to the Notes section).
If everything is OK, our package now should be fully build. If not, please check all the information which are appeared on the screen during the build process to see what goes wrong. If the process finished successfully, you should end with a few files. Here is the list of only needed files:
There is also your newly created Debian package, thus you can test it now. :) Any other files are not needed to create a new package. You can delete them. There is also a good idea to rename our archive file to replace the link. Important: pay attention that link uses underscore in the name instead of dash:
rm bob_3.1-1.orig.tar.gz cp bob-3.1.tar.gz bob_3.1-1.orig.tar.gz
Now you can create your own repository at Open SUSE Build Service and check if everything works there too. You will need to upload there all three files. If everything is working, congratulation, you built your first Debian package. :) To add the package to the Ada Linux Packages Repository, use option Submit package.