# 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 ```