Sign in Join
Wiki copytemporary

Debian package structure: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Installations on Debian are provided as files with .deb extension. This article discusses how to build them manually.
22
33If you would like to bring your program to Debian distributions, see how to make a [[Debian upstream]] source.
44
55## General
66
77### Two types of packages
88
99There are two types of packages, a source package and a binary package. This article is about the binary packages. They are a convenient way to bundle up pre-compiled binaries ready to be supplied directly to an end user. However, distributions like Debian and Ubuntu will not accept to add a binary package in their repositories, they require a [[Debian package source|source package]] that can be used to build the binary version on demand. The [[Debian package source|source package]] is somewhat more difficult to assemble and is subject to a number of technical and legal rules before being acceptable to the major Linux distributions.
1010
1111### Preparing the package
1212
1313In a Debian binary package, the installation files are compressed using **dpkg-deb** command. You can view the content of the resulting .deb files as any other compressed archive by right-clicking them and opening them with the archive manager.
1414
1515To make a .deb file, you need to prepare a directory structure with the appropriate files. This will be called the staging directory and expressed in this article with the variable `${STAGING_DIR}`. You can replace it with the adequate folder or define this variable in a script.
1616
1717You can for example create the staging directory as a subdirectory of the current folder. The simplest script would be:
1818
19-`STAGING_DIR=./staging`\
20-`mkdir ${STAGING_DIR}`
19+```text
20+STAGING_DIR=./staging
21+mkdir ${STAGING_DIR}
22+```
2123
2224Though if you write a script, it may be run from another location. So instead, you can ensure that the variable contains the subdirectory relative to the script with the following:
2325
24-`` cd `dirname $0` ``\
25-`STAGING_RELATIVEDIR="./staging"`\
26-`STAGING_DIR=$(readlink --canonicalize "${STAGING_RELATIVEDIR}")`
26+```text
27+cd `dirname $0`
28+STAGING_RELATIVEDIR="./staging"
29+STAGING_DIR=$(readlink --canonicalize "${STAGING_RELATIVEDIR}")
30+```
2731
2832Also you may need to remove the existing staging directory to make sure it is empty:
2933
30-`rm -rf "${STAGING_DIR}"`\
31-`mkdir "${STAGING_DIR}"`
34+```text
35+rm -rf "${STAGING_DIR}"
36+mkdir "${STAGING_DIR}"
37+```
3238
3339The content of this directory is explained in the rest of this article.
3440
3541### Finalizing the staging directory
3642
3743Read the section *Directory structure* to add all the necessary files. Then you can finalize the directory.
3844
3945The directories and files are supposed to be read-only in the package. To ensure that's the case, you can before calling **dpkg-deb** do the following:
4046
41-`find "${STAGING_DIR}" -type d -exec chmod 0755 {} \;  #set directory attributes`\
42-`find "${STAGING_DIR}" -type f -exec chmod 0644 {} \;  #set data file attributes`\
43-`find "${STAGING_DIR}/usr/bin" -type f -exec chmod 0755 {} \;  #set executable attributes`
47+``` pascal
48+find "${STAGING_DIR}" -type d -exec chmod 0755 {} \; #set directory attributes
49+find "${STAGING_DIR}" -type f -exec chmod 0644 {} \; #set data file attributes
50+find "${STAGING_DIR}/usr/bin" -type f -exec chmod 0755 {} \; #set executable attributes
51+```
4452
4553When you have all file in the staging directory, you can determine the installed size and add it to the **control** file:
4654
47-`SIZE_IN_KB="$(du -s ${STAGING_DIR} | awk '{print $1;}')"`\
48-`echo "Installed-Size: ${SIZE_IN_KB}" >> "${STAGING_DIR}/DEBIAN/control"`
55+```text
56+SIZE_IN_KB="$(du -s ${STAGING_DIR} | awk '{print $1;}')"
57+echo "Installed-Size: ${SIZE_IN_KB}" >> "${STAGING_DIR}/DEBIAN/control"
58+```
4959
5060### Creating the Deb archive
5161
5262Once the directory structure is ready, you can create the archive with:
5363
54-`dpkg-deb --root-owner-group --build "${STAGING_DIR}" "${PACKAGE_NAME}.deb"`
64+```text
65+dpkg-deb --root-owner-group --build "${STAGING_DIR}" "${PACKAGE_NAME}.deb"
66+```
5567
5668Or for older versions of dpkg-deb:
5769
58-`fakeroot dpkg-deb --build "${STAGING_DIR}" "${PACKAGE_NAME}.deb"`
70+```text
71+fakeroot dpkg-deb --build "${STAGING_DIR}" "${PACKAGE_NAME}.deb"
72+```
5973
6074`${STAGING_DIR}` is the path to the directory structure to compress. `${PACKAGE_NAME}` is the filename to use for the archive.
6175
6276Generally you will create the package as a regular user, not with the *root* account. But installation files must not belong to a specific user. Using `--root-owner-group` option or **fakeroot** prefix will save in the archive that the files belong instead to *root*.
6377
6478After that, you will probably not need the staging directory anymore, you can thus delete it:
6579
66-`rm -rf "${STAGING_DIR}"`
80+```text
81+rm -rf "${STAGING_DIR}"
82+```
6783
6884### Checking the archive
6985
7086Once you've created the package, you can check it follows the guidelines with the command **lintian**:
7187
72-`lintian "${PACKAGE_NAME}.deb" --info`
88+```text
89+lintian "${PACKAGE_NAME}.deb" --info
90+```
7391
7492Here is the list of potential problems: <https://lintian.debian.org/tags.html>
7593
7694With Lazarus, you will get by default the `hardening-no-pie` (and `hardening-no-bindnow` warnings in mentors). To avoid such warnings, add the following compiler options in the project options:
7795
78-`-Cg`\
79-`-k-pie`\
80-`-k-znow`
96+```text
97+-Cg
98+-k-pie
99+-k-znow
100+```
81101
82102## Directory structure
83103
84104Here is the structure of the staging directory that you need to prepare.
85105
86-`staging`\
87-`  ├─ DEBIAN`\
88-`  └─ usr`\
89-`      ├─ bin`\
90-`      └─ share`\
91-`          ├─ project1       #resources of your package`\
92-`          ├─ applications   #shortcut`\
93-`          ├─ pixmaps        #default icon`\
94-`          ├─ icons`\
95-`          │   └─ hicolor    #icons of various sizes`\
96-`          ├─ doc`\
97-`          │   └─ project1   #information about your package`\
98-`          └─ man            #user manual`\
99-`              └─ man1       #index`
106+```text
107+staging
108+ ├─ DEBIAN
109+ └─ usr
110+ ├─ bin
111+ └─ share
112+ ├─ project1 #resources of your package
113+ ├─ applications #shortcut
114+ ├─ pixmaps #default icon
115+ ├─ icons
116+ │ └─ hicolor #icons of various sizes
117+ ├─ doc
118+ │ └─ project1 #information about your package
119+ └─ man #user manual
120+ └─ man1 #index
121+```
100122
101123### DEBIAN directory
102124
103125The name of this directory is uppercase. It needs to contain one file called **control**. Here is an example for a package called **project1** at version 2.0.
104126
105-`Section: graphics`\
106-`Priority: optional`\
107-`Maintainer: myname <myname@webserver.com>`\
108-`Homepage: `[`https://www.project1.com`](https://www.project1.com)\
109-`Package: project1`\
110-`Architecture: amd64`\
111-`Version: 2.0`\
112-`Depends: libatk1.0-0 (>= 1.12.4), libc6 (>= 2.2.5), libcairo2 (>= 1.2.4), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.12.0), libgtk2.0-0 (>= 2.24.0), libpango-1.0-0 (>= 1.18.0), libx11-6`\
113-`Description: This is a test project.`\
114-` Long description blah blah blah.`
127+```text
128+Section: graphics
129+Priority: optional
130+Maintainer: myname <myname@webserver.com>
131+Homepage: https://www.project1.com
132+Package: project1
133+Architecture: amd64
134+Version: 2.0
135+Depends: libatk1.0-0 (>= 1.12.4), libc6 (>= 2.2.5), libcairo2 (>= 1.2.4), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.12.0), libgtk2.0-0 (>= 2.24.0), libpango-1.0-0 (>= 1.18.0), libx11-6
136+Description: This is a test project.
137+ Long description blah blah blah.
138+```
115139
116140Sample values for **Section**: comm, database, devel, editors, electronics, fonts, games, graphics, math, web, net, news, science, sound, utils, video.
117141
118142The **Architecture** field is the one used to compile the program. To know the current architecture, use the following command:
119143
120-`dpkg --print-architecture`
144+```text
145+dpkg --print-architecture
146+```
121147
122148The **Depends** field contains the list of Linux libraries used. You can get this list with the following commands run in the directory of your binary file:
123149
124-`mkdir debian                 #need a debian directory`\
125-`touch debian/control         #with one control file in it`\
126-`dpkg-shlibdeps -O project1   #supposing your binary is called project1`
150+```text
151+mkdir debian #need a debian directory
152+touch debian/control #with one control file in it
153+dpkg-shlibdeps -O project1 #supposing your binary is called project1
154+```
127155
128156You can then remove the almost empty *debian* folder if you don't use it.
129157
130158This will output the dependencies (after the equal sign):
131159
132-`shlibs:Depends=libatk1.0-0 (>= 1.12.4), libc6 (>= 2.2.5), libcairo2 (>= 1.2.4), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.12.0), libgtk2.0-0 (>= 2.24.0), libpango-1.0-0 (>= 1.18.0), libx11-6`
160+```text
161+shlibs:Depends=libatk1.0-0 (>= 1.12.4), libc6 (>= 2.2.5), libcairo2 (>= 1.2.4), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.12.0), libgtk2.0-0 (>= 2.24.0), libpango-1.0-0 (>= 1.18.0), libx11-6
162+```
133163
134164To be complete, it should be noted that all these packages are not absolutely necessary, because several packages on this list may already be part of the dependencies - and therefore be part of the installation - of another package listed in this same list (see \[<https://wiki.freepascal.org/Deploying_Your_Application#Tip%3A%5Dto> cross-check, and eliminate superfluous dependencies).
135165
136166### usr/bin directory
137167
138168This directory contains the binary file and only this file (*for information, avoid underscore in the name of your project - for example, dpkg-deb refuses it - because the package name should follow this regex: \${PackageName}_\${Version}_\${Arch}.deb, e.g. dpkg-dev_1.19.0.5ubuntu2_all.deb*). All resources files need to go in *usr/share/project1*. To access resources, your program can use a relative path like *../share/project1*.
139169
140170The directory *usr/local/bin* is invalid in a package[1](https://lintian.debian.org/tags/file-in-usr-local.html) because *local* is used for projects compiled locally and installed using their Makefile.
141171
142172### Resources directory
143173
144174It will be called *usr/share/project1* if the package name is "project1".\
145175You can put here all the data files needed by your program. Note that they will be read-only.
146176
147177### Configuration directory
148178
149179There are other places to store [[Multiplatform Programming Guide|configuration files]]. Configuration files should be originally created by the application itself (with default values), if they do not exist when the application starts.
150180
151181### usr/share/applications directory
152182
153183To add your application to the Linux menu, you need to add a file called **project1.desktop** containing:
154184
155-`[Desktop Entry]`\
156-`Name=Project1`\
157-`Comment=Cool project`\
158-`Icon=project1`\
159-`Exec=project1`\
160-`Terminal=false`\
161-`Type=Application`\
162-`Categories=Graphics`\
163-`GenericName=Project1`\
164-`Keywords=feature1; feature2; feature3`
185+``` pascal
186+[Desktop Entry]
187+Name=Project1
188+Comment=Cool project
189+Icon=project1
190+Exec=project1
191+Terminal=false
192+Type=Application
193+Categories=Graphics
194+GenericName=Project1
195+Keywords=feature1; feature2; feature3
196+```
165197
166198This file is similar to a shortcut to your program.
167199
168200The **Categories** field is similar to the one in the **control** file. It can be for example: Communication, Database, Development, Editors, Electronics, Fonts, Games, Graphics, Math, Internet, Networking, News, Science, Sound, Utility, Video.
169201
170202The keywords help search through applications.
171203
172204Note that you need to provide the icon as a PNG file, either in the directory *usr/share/pixmaps* or in *usr/share/icons/hicolor*.
173205
174206#### usr/share/pixmaps directory
175207
176208Will contain the single-size icon of your menu shortcut in PNG format called **project1.png**. A medium size like 48x48 will be fine.
177209
178210#### usr/share/icons/hicolor directory
179211
180212Will contain the multi-size icon. Here is the directory structure:
181213
182-`icons`\
183-` └─ hicolor`\
184-`     ├─ 8x8`\
185-`     │   └─ apps`\
186-`     ├─ 16x16`\
187-`     │   └─ apps`\
188-`     ...`
214+```text
215+icons
216+ └─ hicolor
217+ ├─ 8x8
218+ │ └─ apps
219+ ├─ 16x16
220+ │ └─ apps
221+ ...
222+```
189223
190224There is a subdirectory for each possible size. You can display all the sizes currently defined on your system by writing:
191225
192-`ls /usr/share/icons/hicolor`
226+```text
227+ls /usr/share/icons/hicolor
228+```
193229
194230In each apps folder, put an image with always the same name. If you project is called project1 then it will be called **project1.png** for most folders. In the scalable and symbolic folders you can put an SVG file.
195231
196232### Documentation directory
197233
198234It will be called *usr/share/doc/project1* if your the package name is "project1".
199235
200236The folder contains the **changelog.Debian.gz** and **copyright** files and optionally the **README** file.
201237
202238#### changelog file
203239
204240The minimum changelog would be:
205241
206-`project1 (1.0) unstable; urgency=low`\
242+```text
243+project1 (1.0) unstable; urgency=low
207244
208-`  * Initial release`\
245+ * Initial release
209246
210-` -- myname <myname@webserver.com>  Tue, 19 May 2020 11:06:00 +0100`
247+ -- myname <myname@webserver.com> Tue, 19 May 2020 11:06:00 +0100
248+```
211249
212250You can add many lines starting with * to indicate the list of changes in the version. The spaces at the beginning of the line are necessary. Only the line indicating the version starts directly at the beginning of the line.
213251
214252The latest version must be at the top of the file.
215253
216254The changelog must be compressed with maximum compression. To do that, supposing you already have the uncompressed **changelog** file, compress it with the following command:
217255
218-`gzip -9 -n usr/share/doc/project1/changelog.Debian`
256+```text
257+gzip -9 -n usr/share/doc/project1/changelog.Debian
258+```
219259
220260The -9 -n options are necessary for the package to follow the guidelines.
221261
222262#### copyright file
223263
224264If you provide the Deb package yourself, it is not mandatory to use the machine-readable format, however it will prepare you for publishing the package in Debian distributions. See: [[Debian package source|copyright in Debian package structure]].
225265
226266### usr/share/man directory
227267
228268Contains the user manual that you can view with the **man** command. It must contain at least **project1.1.gz** in the *man1* subdirectory, which will be the index page of your manual.
229269
230270The syntax is a bit peculiar. There are some tools to help but you still need to know the syntax.
231271
232272- description of the syntax: <https://liw.fi/manpages/>
233273- editor with wizard and WYSIWYG preview mode: **gmanedit**
234274- live preview editor (toggle to AN mode): <https://roperzh.github.io/grapse/>
235275
236276Here is a sample file:
237277
238-`.TH Project1 1 "19 May 2020" "" Project1`\
239-`.SH NAME`\
240-`Project1 - My cool project`\
241-`.SH SYNOPSIS`\
242-`.B project1`\
243-`[PARAMETER]`\
244-`.SH DESCRIPTION`\
245-`What my program does.`\
246-`.PP`\
247-`More description.`
278+``` pascal
279+.TH Project1 1 "19 May 2020" "" Project1
280+.SH NAME
281+Project1 - My cool project
282+.SH SYNOPSIS
283+.B project1
284+[PARAMETER]
285+.SH DESCRIPTION
286+What my program does.
287+.PP
288+More description.
289+```
248290
249291The manual, like the changelog, must be compressed using the following command:
250292
251-`gzip -9 -n usr/share/man/man1/project1.1`
293+```text
294+gzip -9 -n usr/share/man/man1/project1.1
295+```
252296
253297The -9 -n options are necessary for the package to follow the guidelines.
254298
255299---
256300*From the Free Pascal wiki, page "Debian package structure", as it stood on 2022-01-02 after a change by FTurtle, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history