# Creating binary package with debcrafter
In this tutorial, we will explore how to use debcrafter, that simplifies the process of creating Debian packages. By following the steps outlined in this walkthrough, you will be able to create a Debian package.
## Prerequisite
You need to be on debian 10 to run debcrafter.
```bash
cd workspace
git clone https://github.com/Kixunil/debcrafter.git
cargo install --path .
```
You also need to install the required dependencies
```bash
sudo apt install dpkg dpkg-buildpackage debc make
```
## Final Directory Structure
Before we dive into the details of using debcrafter, let's take a look at the directory structure you will achieve by the end of this tutorial:
```bash
~/workspace/
├── deb-packages/
│ └── pkg-config/
│ ├── hello-world.srs
│ ├── hello-world.sps
│ ├── hello-world.sss
│ ├── hello-world.changelog
│ └── hello-world/
│ └── hello-world-<version-number>/
│ └── debian/
│ ├── changelog
│ ├── compat
│ ├── control
│ ├── hello.install
│ ├── hello.postinst
│ ├── hello.postrm
│ └── rules
│
│
│
└── hello-world/
```
```
deb-packages/: A directory where you'll organize all the packaging-related files for your Debian package.
pkg-config/: The working directory where we'll build the "hello-world" Debian package.
hello-world.srs: The Smart Repository Specification (SRS) file.
hello-world.sps: The Smart Packaging Specification (SPS) file.
hello-world.sss: The Smart Source Specification (SSS) file.
hello-world.changelog: The changelog file.
hello-world/: The Debian directory generated by debcrafter.
hello-world-<version-number>/: The Debian directory generated by debcrafter.
DEBIAN/: The Debian control directory.
control: The control file.
changelog: The changelog file for the Debian package.
```
If you would like the finished source it, you find it [here](https://github.com/eenagy/deb-packages)
## Walkthrough
We will be constructing a single package that exposes a solitary binary package. However, it's worth noting that debcrafter has the capability to assemble multiple software projects, each of which can expose numerous packages with various configurations.
### 1. Obtaining the package source
```bash
cd ~/workspace
git clone https://github.com/eenagy/debhello.git hello-world
```
### 2. Creating packaging directories
``` bash
mkdir -p ~/workspace/debian-packaging-files/pkg-config
cd ~/workspace/debian-packaging-files/pkg-config
```
### 3. SRS File
Create a smart repository configuration file. In this context, each repository corresponds to a single software project, and the SRS file enables the definition of multiple Debian packages derived from a sole repository.
Each repository is denoted by the `[sources.[repository-name]]` structure, where the `repository-name.sss` file will specify the packages to be constructed. A repository represents an individual software project and has the flexibility to encompass base, service, and configuration packages within it.
`hello-world.srs`
```toml
# Used for all in control file
maintainer = "John Doe <johndoe@example.com>"
# Each source defines a different source directory
[sources.hello-world]
# Upstream version
version = "0.1"
section = "net"
# Packages available within the source
# .sps files must be placed in the same directory this file is in
packages = ["hello-world"] # this will look for hello-world.sss
```
### 4. SSS File
Generate a Smart Source Specification (SSS) file to define the software you wish to package. However, please note that for this example, we are creating only one binary package:
`hello-world.sss`
```toml
name = "hello-world"
variants = [] # none as we don't provide in this case
build-depends = []
packages = ["hello-world"] # same as the sps file defined above
skip_debug_symbols = true
```
Within the packages section, the SSS file is configured to look for the `hello-world.sps` file, which provides the specifications for the binary package you intend to create. If we wish to expose multiple packages, we would add multiple packages into the `packages` field.
### 5. SPS File
The SPS file will be the lowest level, where we can define what our package will be exposing. In this case a binary package, the simplest package that we can create. A binary package is inferred from the `architecture` field. All the other field are requirements for debian packaging. Each `.sps` can expose one package. In later case we can see how can we expose more than 1 package through variants.
`hello-world.sps`
```toml
name = "hello-world" # name of your package
architecture = "any" # package architechture, pick debian supported one
summary = "Example hello world" # short summary
conflicts = [] # if this package conflicts with other, you would specify it here
recommends = [] # if this package would recommend packages, empty for this case
suggests = [] # suggested packages
add_files = []
# long documentation, shown on info command
long_doc = """Lorem Ipsum
"""
```
### 6. Changelog File
Prepare a changelog file that lists the changes made to your software. This is an essential component of the Debian package.
`hello-world.changelog`
```txt
hello-world (0.1-1) buster; urgency=medium
* Hello world debian package
-- John Doe <johndoe@example.com> Sat, 1 Aug 2020 18:51:27 +0100
```
### 7. Generating the debian directory
Run `debcrafter` with the SRS, SPS, SSS, and changelog files as inputs. This will generate the Debian directory structure for your package.
```bash
debcrafter hello-world.srs ../hello-world
```
### 8. Building the .deb package
Use the `dpkg-build` command to build the Debian package from the contents of the Debian directory. Make sure you are in the root directory of your project, which should contain the Debian directory created by `debcrafter`.
Edit `hello-world/hello-world-<version>/debian/hello-world.install` and remove the following
```txt
bin/hello-world /usr/bin
```
dpkg will include the built binary in our debian folder, we do not add this in this case.
Open `hello-world/hello-world-<version>/debian/rules` and add the following to the end of the file
```
override_dh_auto_install:
dh_auto_install -- prefix=/usr
```
This will be going to install under the `/usr` directory, instead the default `/usr/local`, which only directories can be installed with debian packages.
Let's build the debian package.
```bash
cd ~/workspace/hello-world
cp -R ~/workspace/deb-packages/hello-world/hello-world-0.1/debian .
dpkg-buildpackage -us -uc
```
If the `dpkg-buildpackage` succeeds you will end up with the following files at the `~/workspace` directory
**TODO: FIX version differences from the richt text files.**
```text
hello-world_0.1-1_amd64.buildinfo
hello-world_0.1-1_amd64.changes
hello-world_0.1-1_amd64.deb
hello-world_0.1-1.dsc
hello-world_0.1-1.tar.gz
hello-world-dbgsym_0.1-1_amd64.deb
```
### 9. Test the package
```bash
debc hello-world_0.1-1_amd64.changes
```
should output something similar
```txt
hello-world-dbgsym_0.1-1_amd64.deb
----------------------------------
new Debian package, version 2.0.
size 3792 bytes: control archive=512 bytes.
337 bytes, 12 lines control
106 bytes, 1 lines md5sums
Package: hello-world-dbgsym
Source: hello-world
Version: 0.1-1
Auto-Built-Package: debug-symbols
Architecture: amd64
Maintainer: John doe <johndoe@example.com>
Installed-Size: 18
Depends: hello-world (= 0.1-1)
Section: debug
Priority: optional
Description: debug symbols for hello-world
Build-Ids: 6673e0826b1e8bd84f511bac7772b2981912744e
drwxr-xr-x root/root 0 2020-08-01 17:51 ./
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/lib/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/lib/debug/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/lib/debug/.build-id/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/lib/debug/.build-id/66/
-rw-r--r-- root/root 7376 2020-08-01 17:51 ./usr/lib/debug/.build-id/66/73e0826b1e8bd84f511bac7772b2981912744e.debug
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/doc/
lrwxrwxrwx root/root 0 2020-08-01 17:51 ./usr/share/doc/hello-world-dbgsym -> hello-world
hello-world_0.1-1_amd64.deb
---------------------------
new Debian package, version 2.0.
size 2808 bytes: control archive=664 bytes.
220 bytes, 10 lines control
128 bytes, 2 lines md5sums
159 bytes, 15 lines * postinst #!/bin/bash
95 bytes, 10 lines * postrm #!/bin/bash
Package: hello-world
Version: 0.1-1
Architecture: amd64
Maintainer: John Doe <johndoe@example.com>
Installed-Size: 25
Depends: libc6 (>= 2.2.5)
Section: net
Priority: optional
Description: Example hello world
Lorem Ipsum
drwxr-xr-x root/root 0 2020-08-01 17:51 ./
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/bin/
-rwxr-xr-x root/root 14440 2020-08-01 17:51 ./usr/bin/hello
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/doc/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/doc/hello-world/
-rw-r--r-- root/root 148 2020-08-01 17:51 ./usr/share/doc/hello-world/changelog.Debian.gz
```
We can ignore the first package, which is only debug symbols. The interesting things is happening on the last lines of the output.
```
drwxr-xr-x root/root 0 2020-08-01 17:51 ./
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/bin/
-rwxr-xr-x root/root 14440 2020-08-01 17:51 ./usr/bin/hello
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/doc/
drwxr-xr-x root/root 0 2020-08-01 17:51 ./usr/share/doc/hello-world/
-rw-r--r-- root/root 148 2020-08-01 17:51 ./usr/share/doc/hello-world/changelog.Debian.gz
```
In this case each file under the `debian/hello-world/usr/*` file will be mapped to the actual `/usr/` file when debian installs the package. You can simply think that the directory content will be copied under `/usr`.
### 10. Install/uninstall package
```bash
cd ~/workspace
sudo dpkg -i hello-world_0.1-1_amd64.deb
hello
```
this should result in
```bash
Hello, world!
```
You can also check if hello indeed is invoked from the install debian file.
```bash
which hello
```
```bash
/usr/bin/hello
```
To uninstall simply
```bash
sudo dpkg -P hello-world
hello
```
which indeed
```bash
bash: command not found: hello
```