Now that we have Debian tools ready, it's time to define the package. In this guide however, we won't be showing steps by steps as an independent guide but rather complements from the existing document.
Debian system allows you to compile either the binary form or the source form. They are both different in terms of deployment and maintainability. From Debian Buster onward, the official guide requires us to build the source package. Let's stick to the source package.
The primary difference between them are:
$ mkdir DEBIAN$ mkdir debianOnce you created the Debian directory inside your project, it's time to pack the necessary files in it. In this guide, we'll be strictly building the source package.
$ mkdir debiandebian/control file is the most critical file of all. It carries the instruction and the metadata for your package. This file follows a very strict rules and template, like the one specified in the guide. We'll go through each of them accordingly.
1 Source: <software name> 2 Section: <software type> 3 Priority: optional 4 Maintainer: Josip Rodin <joy-mg@debian.org> 5 Build-Depends: debhelper (>=10) 6 Standards-Version: 4.0.0 7 Homepage: <insert the upstream URL, if relevant> 8 9 Package: gentoo10 Architecture: any11 Depends: ${shlibs:Depends}, ${misc:Depends}12 Description: <insert up to 60 chars description>13 <insert long description, indented with spaces>Source is the software name or the package. This name should be like a 1 word or 2 words with/without connected with hyphen(-).
Avoid using long name. If it happens to you, you should greatly consider the level of details in the name and place them in the descriptions instead.
Example: gentoo, bashell, nuko, shellcheck, coreutils
Section is the software distribution your software should goes into. It is a controlled value listed in the Debian Policy Manual. Generally, we use these sections but you can browse the policy to search for more:
main - the free softwarenon-free - the not free softwarecontrib - the free software that depends on non-free software.devel - the programmer toolsdoc - the documentationlibs - the librariesmail - the email and its associated daemonsnet - the network applications and daemonsDenotes the priority to install your package to user. It is a controlled value listed in Debian Policy Manual. In summary, the values are as follow:
required - for software critical enough that it can break dpkg packaging software, brick the operating system and make the system totally broken.important - for bare minimum software that is common across all Linux system, such as coreutils, grub, etc. standard - for bare minimum of your software. The core system. You should only have one standard package with many optional packages.optional - commonly used for majority of the archive. If you don't know what to do, use optional.
The contact email when something happens to your package. Please ensure you provide a proper send-able email address. This email follows the format:
FULL NAME <email address>Example:
Josip Rodin <joy-mg@debian.org>Specify the dependent tools/software for building your software package. Based on the guide, since most implementation is now using dh command, you should append debhelper (>=10) into Build-Depends. A good example would be:
Build-Depends: debhelper (>=9), bash (>=4.3)The version number for the standards you're planning to use. Do not confused this field as your software version. It is strictly referring to the Standards-Version list. Keep in mind that not all versions are available in every operating system or distribution branches. You should use the appropriate version that is compatible to your build machine.
The web URL for your software. Keep it short and simple.
This empty line is mandatory. It splits the source section and binary section of the control file. Leave it a clean blank line.
Name for the binary package. It is usually the same as Line 1 Source name.
Specify the package is architecture dependent or otherwise as per Debian Policy Manual. You can check the architecture list using the command dpkg-architecture -L. Some common values are:
armhfarmelmipsn32mipsn32elmipsn32r6mipsn32r6elmips64mips64elmips64r6mips64r6elpowerpcspex32arm64ilp32i386ia64amd64armebarmarm64avr32Debian also supplies 2 common value for architecture independent software like scripts, images, and docs; and "compile at install" software. These are:
any - for "compile at install" softwareall - for architecture independent softwareSpecify the dependencies for the binary package. This is the list where user will get software lists to be installed when installing your software using dpkg. By default, you must include ${shlibs:Depends}, ${misc:Depends}. These 2 flags are for packager to include the dependencies identified via automation .
There are a lot more keywords aside "Depends". You can refer to the guide: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html.
The short description, should be around 60 characters, written in the following styles:
Style 1: This package <name> <do what in a nutshell>Style 2: collection of <something> from <where>Style 3: <what's inside in a nutshell>Style 4: <do what in a nutshell> with <name>Some guidelines:
.). Lintian will notify you if it detects such phenomenon.This short description is meant pitching your software package during package shopping. User may use certain keywords in his/her search. Therefore, just like Search Engine Optimization, you should always do a good research with the keywords and let user find your software easily! Here are some examples when a user search for coreutils:
$ sudo apt search coreutilsbsdmainutils/stable,now 9.0.12+nmu1 amd64 [installed] collection of more utilities from FreeBSDcoreutils/stable,now 8.26-3 amd64 [installed] GNU core utilitiesgotail/stable 1.0.0+git20160415.b294095-3+b2 amd64 Go implementation of taillibsemanage1/stable,now 2.6-2 amd64 [installed] SELinux policy management librarymktemp/stable 8.26-3 all coreutils mktemp transitional packagepolicycoreutils/stable 2.6-3 amd64 SELinux core policy utilitiespolicycoreutils-dev/stable 2.6-3 amd64 SELinux core policy utilities (development utilities)policycoreutils-gui/stable 2.6-3 all SELinux core policy utilities (graphical utilities)policycoreutils-python-utils/stable 2.6-3 amd64 SELinux core policy utilities (Python utilities)policycoreutils-sandbox/stable 2.6-3 amd64 SELinux core policy utilities (graphical sandboxes)progress/stable 0.13.1-1 amd64 Coreutils Progress Viewer (formerly known as 'cv')python3-sepolgen/stable 2.6-3 all Python3 module used in SELinux policy generationrealpath/stable 8.26-3 all coreutils realpath transitional packageThis section holds the long description for your software. There isn't any limit to the long description but please keep it concise and straight to the point. A sensible length is usually 2-4 paragraphs at 6 maximum lines each.
User views this long description using apt show <package> command. Here's an example:
$ sudo apt show zooPackage: zooVersion: 2.10-28Priority: optionalSection: utilsMaintainer: Debian QA Group <packages@qa.debian.org>Installed-Size: 140 kBDepends: libc6 (>= 2.14)Homepage: http://www.ibiblio.org/pub/packages/ccic/software/unix/utils/Tag: implemented-in::c, interface::commandline, role::program, scope::utility, use::compressing, use::storing, works-with::archiveDownload-Size: 64.3 kBAPT-Sources: http://ftp.us.debian.org/debian stretch/main amd64 PackagesDescription: manipulate zoo archives Zoo is used to create and maintain collections of files in compressed form. It uses a Lempel-Ziv compression algorithm that gives space savings in the range of 20% to 80% depending on the type of file data. Zoo can store and selectively extract multiple generations of the same file. . This package exists for its historical value. If you are looking for a compression tool for serious use, check tar and gzip.There are a few things to take note of:
) for each line..) instead of leaving it empty.Here's an example for a debian/control file or see the one in the official guide:
Source: fennecSection: develPriority: optionalMaintainer: ZORALab Enterprise <tech@zoralab.com>Build-Depends: debhelper (>=9), bash (>=4.3)Standards-Version: 3.9.8Homepage: https://gitlab.com/ZORALab/fennecPackage: fennecArchitecture: allDepends: ${misc:Depends}, ${shlibs:Depends}, bash (>= 4.3)Description: This package fennec provides a way to handle CI script fennec is a software management tool to handle web supported git repository. It structures the repository for a semi-automatic continuous integration alongside with web platform supports, such as GitLab.This defines the software license for using the your software package. It is a UTF-8 encoded only file and strictly machine parse-able document. The entire detailed information is documented in the Debian Policy Manual - Copyright File section. While it takes time to create one, you can follow the main guide. Here's one example:
1 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 Upstream-Name: <package name> 3 Upstream-Contact: Emil Brink <emil@obsession.se> 4 Source: <url to source> 5 6 Files: * 7 Copyright: 1998-2010 Emil Brink <emil@obsession.se> 8 License: GPL-2+ 910 Files: icons/*11 Copyright: 1998 Johan Hanson <johan@tiq.com>12 License: GPL-2+1314 Files: firmware/*15 Copyright: 1998-2010 Josip Rodin <joy-mg@debian.org>16 2008, John Doe <jdoe@example.com>17 2007, Jane Smith <jsmith@example.org>18 2007, Joe Average <joe@example.org>19 2007, J. Random User <jr@users.example.com>20 License: Proprietary2122 License: GPL-2+23 This program is free software; you can redistribute it and/or modify24 it under the terms of the GNU General Public License as published by25 the Free Software Foundation; either version 2 of the License, or26 (at your option) any later version. 27 .28 This program is distributed in the hope that it will be useful,29 but WITHOUT ANY WARRANTY; without even the implied warranty of30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the31 GNU General Public License for more details.32 .33 You should have received a copy of the GNU General Public License along34 with this program; if not, write to the Free Software Foundation, Inc.,35 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.36 .37 On Debian systems, the full text of the GNU General Public38 License version 2 can be found in the file39 '/usr/share/common-licenses/GPL-2'.4041 License: Proprietary42 PROPRIETARY AND CONFIDENTIAL43 Unauthorized copying of any files and any codes within this project, via any44 medium is strictly prohibited.45 .46 Any line of code and file in this repository CANNOT be copied and/or47 distributed in any means, any forms, any medium and any channels, without the48 express written permission of the owner mentioned above.Declares the copyright format version for the package. It tells how this copyright document to parse. Currently there is only version 1.0, in which you can read it here:
TIP: read the document itself to populate the necessary information in this file.
The package name. This should be the same as "Source" and "Package" fields in debian/control.
The maintainer contact. This should be the same as "Maintainer" field in debian/control.
The URL to your source repository / website. This can be the same as "Homepage" field in debian/control.
This is an empty line to split the file header, which is Line 1 to Line 4.
The license binding for a file/set of files. In a bind, you need to specify the filename with its relative path, copyright owner and the corresponding license tag. Keep in mind that the license tag is a recognized short-code, in which you'll define the license later. We'll go through each line one by one here.
The list of files you plan to bind to. Use asterisk (*) to indicate all files within a directory. If you use a single asterisk alone like in Line 6, it means the entire package is bind to that license.
State the copyright owner for the specified files. When applicable, this can be the same as "Maintainer" field in debian/control. If you have multiple owners, you can list them out in the following line with aligned indentation. Here's an example:
Copyright: 1998-2010 Josip Rodin <joy-mg@debian.org> 2008, John Doe <jdoe@example.com> 2007, Jane Smith <jsmith@example.org> 2007, Joe Average <joe@example.org> 2007, J. Random User <jr@users.example.com>This field also supports multi-year copyright. See line 15 in the example above.
The license tag you wish to bind with. Keep in mind that this is a tag. You'll need to declare the license's body in later section. It is a controlled value specified inside the specification format that you use. Example, for version 1.0, see License Specification section. These license tags are also available at SPDX License List alongside with their respective license body.
If you are using dual or multiple licensing, you can use them with "and" or "or" words for additional bindings. Here's an example:
License: GPL-1+ or ArtisticLicense: GPL-2+ and BSD-3-clauseHere's how it works, as per version 1.0 format:
A or B ➔ ( A or B).
A and B ➔ A and B.
A or B and C ➔ A or (B and C).
A or B, and C ➔ (A or B) and C.
You are, however, not allowed to mislead known keywords to a foreign license body. Example: your tag is "GPL-2.0-only" but your license body declares the tag has "NRL License".
Exception
If you really need to use private tag, such as "proprietary" or "fair-use", make sure they are not declared in the known list. As long as the license body is declared in later section that matches the keyword, you're good.
When a license bind is completed, this line indicates that binding statements are completed. You should leave an empty new line.
This is a different tag to demonstrate how to bind the same license across different files. Notice the similarity.
This is a different tag to demonstrate how to bind a different license, with multiple copyright owners alongside their copyright years. Notice the similarity.
Specify the license body for a particular tag. This line specify GPL2+ tag as deployed in Line 6 and Line 12 license binding. You should append the short text / license header in the following line.
The written license body. There is a machine formatting for this section:
) to indicate it's a long text..). See line 27, 32, and 36.When a license body is done writing, this line indicates that the declaration is completed. You should leave an empty new line.
This is a different declaration for multiple licenses. Notice the similarity.
Indicate the software changes in the package. This changelog serves a series of vital information for your package:
We'll go through one by one later.
1 <name> (<version><-revision>) <distribution>; urgency=<level>23 * <changes 1>4 * <changes 2>56 -- Josip Rodin <joy-mg@debian.org> Mon, 22 Mar 2010 00:37:31 +01007The changelog follows a very strict format, especially with the spacing and parenthesis shown above. As per Debian Policy Manual:
<name> - the package name. It is the same as "Source" and "Package" in debian/control.<version><-revision>- the version of the software.()".(", and before closing parenthesis ")".)".<distribution> - The distribution for this package to deliver to.;) after completion.<level> - urgency level to notify user's system to update this package. It is a controlled value.Necessary Empty Line - Splitting release header<changes N> - your changelog items. Each item: )*) )Necessary Empty Line - Splitting changelog itemsSignature and Email - The package maintainer / developer signature and email. )--) follows up.<)>)Signed-off Date and TimeNecessary Empty Line - Splitting release entriesKeep Line 1 consistent for each release entries.Here's an example for Debian unstable branch:
bashell (1.2.0) unstable; urgency=low *README.md: updated snap installation to have --classic flag *bashell.sh: implement strict test workspace cleaning *bashell.sh: added local cache download and install *test/scripts/bashell/create_bash: fix improper filepath for diff *bashell.sh: fix incorrect checking for $TERM *bashell.sh: fix run test exit always return 0 even in failed cases -- ZORALab Enterprise <tech@zoralab.com> Fri, 25 May 2018 10:41:26 +0800 bashell (1.1.1) unstable; urgency=low *README.md: added Fedora installation guidelines using snaps *rpmbuild: added rpmbuild build system into repository -- ZORALab Enterprise <tech@zoralab.com> Mon, 14 May 2018 07:53:42 +0800 bashell (1.1.0) unstable; urgency=low *SNAP: added ubuntu snaps packaging automation *bashell.sh: change bash template to use VERSION instead of version *README.md: updated documentation to relfect the bash creation feature *bashell.sh: added create bashell friendly linux bash script feature *bashell.sh: consolidate printouts under single echo -- ZORALab Enterprise <tech@zoralab.com> Wed, 02 May 2018 22:10:44 +0800 This is to indicate the changes belongs to this package. It is also meant to identify the origin of the changelog. At minimum, this field must shares the same value as "source" in debian/control.
The common version number. Debian follows [epoch:]upstream_version[-debian_revision]. However, it allows Major.Minor.MajorPatch.MinorPatch format and the commonly use Major.Minor.Patch format as well.
Keep in mind that it does follows the Debian Package Manual definition of version number, such as the specific use of hyphen (-) delimiter: the specific [-Revision] indicator. This delimiter is only meant for indicating upstream build/revision; which makes the upstream testing process easier. With this delimiter, we can also identify the package origin: either it was from an upstream compiled package or an independent native compiled package.
Alternatively, to compensate that hyphen delimiter, the manual encourages us to use the period (.) delimiter, plus (+) delimiter, colon (:) delimiter, and tilde (~) delimiter for conventional version numbering control across different distributions. Here are some good examples:
1.15.351.150.5.0+0ubuntu1~xenialppa11.15~unstable11.15~unstable21.15-12:1.15-1 (with epoch version 2)You should not use epoch at all except under the instruction of the distributor's maintainer. Epoch is mainly used for facilitating scheme changes in the upstream system and it is not meant for user consumption.
The distribution channel for your package. This varies from different Debian-based operating system such as Debian and Ubuntu. You should follows the upstream guide of the targeted operating system. Example:
xenial, artful, etc.stable, unstable, testing, experimental, sidMulti-line entries describing the list of changes per release. This changelog uses asterisk line indicator instead. You should keep each line as short as a terminal 80 column lines. Anything additional should enter a separate files inside your software repository like Release Note document.
The signed-off for the release. It follows a strict pattern:
-- [FULL NAME] <[EMAIL ADDRESS]> [RFC-2822 DATE AND TIME]This signed-off is highly recommended to be done by the package maintainer. The date is RFC-2822 format, in which the following command produces:
$ date -RIf you're creating one manually, ensure it complies to the following format, as specified in the manual:
day-of-week, dd month yyyy hh:mm:ss +zzzzExample:
Sat, 22 Sep 2018 13:16:54 +0800This is a Makefile dedicated for building your package. To date (2018), the ecosystem does supply the debhelper to simplify things up. We'll be using this method for building the package.
As per the Debian guide, you're allowed to customize this rules Makefile. However, this guide will focus on copy and paste software as our highest priority is to get things work. If you're looking for customization guide, it will be in a separate topic.
Keeping it simple, we only need this (NOTE: the "TAB" spacing here is TAB, not space):
#!/usr/bin/make -f# Uncomment this to turn on verbose mode.#export DH_VERBOSE=1%: dh $@Declare compatibility for the debhelper. As per guide, you can create this file with the number version in it, like "10". A quick way to create this file is:
$ echo 10 > debian/compatYou should build your compatibility version to 10 to avoid outdated disruption.
Creating manual page for your package. You must follow the guide, especially the numbering extension. The manpage format follows the standard man-page format. The number level however, indicates the particular manual page at certain operating system level:
Use the correct numbering to indicate the content. You can save the documents anywhere inside the debian directory. A good way would be grouping them inside a debian/doc directory.
Create the list of manpages for your package. This file serves as an index for all your manuals. You just need to list your manpages path relative to debian directory in this file. Here's an example of what's inside the file:
doc/package.1doc/package.2doc/package.3doc/package.4doc/package.5doc/package.6doc/package.7doc/package.8doc/package.9The system is smart enough to identify the manpage's level through the file numbering.
This is to tell the build system to use the source format. There are a series of versions available. The commonly used are:
3.0 (quilt)3.0 (native)3.0 (git)1.0You just need to create a directory called source and then a file containing the value in it. Quilt is a version control for the package and is compulsory to use it if you're building an upstream package.
Otherwise, stick to the native version 3 by default.
Keep in mind that git version 3 is still experimental and it may not work properly in the upstream version. Use with caution.
Tells the package manager to install files at the correct location. In this file, we declare what files to be placed at which location. As per guide, you should declare the path in a pure relative manner. Example:
<relative path from current source to file> <relative to root directory>Here are some examples:
bin/executable usr/bin/programsrc/bar usr/bin/barfennec usr/bin lib/fennec usr/share/fennecNow you can't simply copy your files anywhere in the Linux root system. All the corresponding files should comply to the Debian File Hierarchy Standards.
For our power-on objective, let's keep things simple by copying 1 file to a known location of your desire.
Once you're done, you should have your Debian directory ready. A quick look over the package should produce something as follows (an example):
debian├── changelog├── compat├── control├── copyright├── fennec.1├── fennec.manpages├── install├── rules└── source └── formatThere are more files specified by the policy manual and the guide. However, these are the minimum requirements for the package builder to build a successful deb package.