Here’s a quick example. To create a basic Debian package, you need to—
Create a new directory called
debian at the root of your project directory. Inside this directory, create these files:
control, which contains the name, description, and dependencies of your package,
rules, which basically tells it how to build your package,
changelog, a change log of your program
You can try to write these files yourself by following the documentations, using tools like
dh_make to help generate them. Or, more simply, you can just look at how other projects are packaged and imitate them.
After setting up the files in the
debian directory, you can now run
dpkg-buildpackage -us -uc to create the .deb file.
A tarball is just an archive file. It often refers to source code tarballs, which contains the source of your program. A tarball is used simply for downloading a version of the software, so you can create a package out of it. If you are packaging your own software, you don’t necessarily have to first make a tarball in order to make a package. You can add Debian packaging information directly to your source code tree.
I’ll try and do an ELI5-style (Explain Like I’m Five) explanation of everything. A bit long but hopefully would be helpful to someone reading this thread.
Before users can use your program, they need to (1) download it, and (2) install it.
First, downloading — It’s usually much more convenient to download a tarball (a compressed file containing all the files of the program) than to download each file separately. This is why tarballs are provided by developers. In some cases, people might prefer cloning the git repo instead of downloading a tarball.
Second, installing — Installing means copying files to specific locations on the user’s computer so they can be accessed. But there’s one problem: very often, the source code is not directly usable—you need to process the source code in some way before installing. This usually involves compiling the source code, but often there are other things that you need to do (e.g. generating translation files). This whole process is known as building. If the program is only a single hello-world script, you probably don’t need to process it before installing it. But things can get complicated when you have many files and many things that you want to do before or even after installing. You can still do everything manually, if you want. But it’s usually easier to use a build system like Meson to automate this process.
When you create a Debian package, what you’re doing is essentially building your software and “installing” it onto the .deb file. If you inspect a .deb file (which is just an archive file that you can open with an archive manager), you’d see that it contains not the source, but the processed (e.g. compiled) result of the source. But this is all still contained in the .deb file. Only when the user actually installs the .deb file will the contents be copied to the specified locations on the user’s system.
Here are some simplified diagrams that I hope will make things clearer.
Diagram 1. Installing directly from source. In this simple case, there’s no build step and no build system, because the source code is, for example, only a single Python script file that can be run as is by the user.
(simply copy the files to the user's system)
┌─────────────┐ │ ┌────────────────┐
│ Source code ├───────┴───────────────────────────────┤ Installed code │
Diagram 2. Building and installing from source, using a build system.
Building and installing
(e.g. with Meson)
┌─────────────┐ │ ┌────────────────┐ │ ┌────────────────┐
│ Source code ├──┴────┤ Processed code ├──┴───────────┤ Installed code │
└─────────────┘ └────────────────┘ └────────────────┘
Diagram 3. The contents of the .deb package, marked by the dashed border.
Building and installing
(e.g. with Meson) ╭╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮
Building ╎ Installation ╎
instructions ╎ instructions ╎
│ ╭╌╌╌╌╌╌╌╌╌╌╌╌┘ │ ╎
┌─────────────┐ │ ╎ ┌────────────────┐ │ ╎ ┌────────────────┐
│ Source code ├──┴──╎─┤ Processed code ├──┴──────╎────┤ Installed code │
└─────────────┘ ╎ └────────────────┘ ╎ └────────────────┘
Diagram 4. Simplified view of the workflow when building and installing with the .deb package. Compare this with the previous diagram.
Developer User installs
builds .deb .deb package
┌─────────────┐ │ ╭╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ │ ┌────────────────┐
│ Source code ├──┴──┤ .deb package ├──┴─┤ Installed code │
└─────────────┘ ╰╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ └────────────────┘
If you want it to be included in Debian’s repositories, you need to follow their policies and procedures, which, depending on the situation, can be a lot more complicated than just building a .deb that just “works”. Usually it’s better to see if an existing Debian maintainer is willing to create and maintain the package for you. This is what most people do, traditionally. Developers are responsible for writing applications, and maintainers are for packaging them.
If you want to package and distribute things yourself, you will probably be better served by Flatpak, which is made with the goal of enabling upstream packaging—it makes distributing software much easier for the upstream developer. It’s probably the quickest way to make your program available to the public.