lubuntu-packaging-guide/lubuntu-packaging-guide.rst
2025-11-17 18:01:40 -06:00

712 lines
34 KiB
ReStructuredText

==============================
Packaging Software for Lubuntu
==============================
This document provides information about how to to create and maintain the
Debian packages that comprise the core of Lubuntu. We'll go over how to set up
your system for packaging, basic packaging concepts, best practices for
Lubuntu's packages, and advice for what to do and not do in order to make your
life as a packager easier.
Copyright and Licensing
-----------------------
The text of this document may be used under the terms of the CC-BY-SA 4.0
license. The copyright info for this document is as follows:
* Copyright (c) 2025 Aaron Rainbolt <arraybolt3@ubuntu.com>.
.. NOTE::
If you make a substantial contribution to this document, you should add
your own copyright info to the above list.
High-level overview of a Debian "package"
-----------------------------------------
There are two distinct kinds of packages in Debian, *binary packages* and
*source packages*. Binary packages are the packages you actually install on
your system. For the most part, you won't need to worry about the details of
how they work internally. Source packages are bundles of source code with
Debian packaging metadata. This metadata describes (among other things) how to
build the package, and where the files it installs should go. *Building* a
source package will create one or more binary packages, along with some other
files that we'll describe as we go.
To get an idea of how source packages are structured, we'll start with a
fairly simple package, ``lxqt-about``::
aaron@pkg-builder:~/lubuntu-dev/lxqt-about$ tree
.
├── aboutdialog
│   ...
├── AUTHORS
├── CHANGELOG
├── CMakeLists.txt
├── COPYING
├── debian
│   ├── changelog
│   ├── control
│   ├── copyright
│   ├── docs
│   ├── ...
│   ├── ...
│   ├── lxqt-about.install
│   ├── lxqt-about-l10n.install
│   ├── lxqt-about.lintian-overrides
│   ├── rules
│   ├── ...
│   ├── source
│   │   ├── format
│   │   └── options
│   ├── upstream
│   │   ├── metadata
│   │   └── signing-key.asc
│   └── watch
├── languages
├── main.cpp
├── README.md
├── resources
│   ...
├── translations
│   ...
└── translatorsinfo
...
(The contents of the ``aboutdialog``, ``translations``, and
``translatorsinfo`` dirs are omitted for brevity, and a few irrelevant files
from the ``debian`` directory have been hidden for clarity.)
If you look at `the lxqt-about Git repo
<https://github.com/lxqt/lxqt-about>`__, you'll see that this looks very
similar to the lxqt-about source code repository. The primary difference is
there is a ``debian`` directory here, with a number of files in it. This
``debian`` directory contains all the instructions necessary to take code, and
turn it into Debian binary packages.
We won't go into the details about what these files contain quite yet, but we
will briefly cover what each one does.
* ``changelog``: As one would expect, this contains a record of all changes
made to the package over time. It also specifies the version number of the
package, the version of Ubuntu (or Debian) the package is intended for, and
the identity of the person or people who made changes to the package.
* ``control``: This file defines critical information about the package,
including the names of the source package and each binary package, build and
runtime dependencies, what CPU each binary package is designed to run on,
and a description of each binary package.
* ``copyright``: This file contains copyright notices and authorship
information for (almost) every file in a source package. This is necessary
because many license agreements require or encourage a software distributor
(like Ubuntu) to include copyright notices, license text, and authorship
information for software they distribute. Thanks to the somewhat complex
nature of software licensing, this can be tricky and tedious to maintain,
but it is necessary.
* ``docs``: This file isn't present in all packages. When it is present, it
specifies files that should be installed in a subdirectory of
``/usr/share/doc`` for the user to reference later if they care to.
* ``lxqt-about.install``: This file contains information about what files
should be placed in the ``lxqt-about`` binary package. There are some simple
source packages that don't need a ``.install`` file for a binary package,
but those are rare.
* ``lxqt-about-l10n.install``: This file serves the same purpose as
``lxqt-about.install``, but for the ``lxqt-about-l10n`` binary package. (As
you can probably guess, the ``lxqt-about`` source package builds two binary
packages, named ``lxqt-about`` and ``lxqt-about-l10n``.)
* ``lxqt-about.lintian-overrides``: This file is used to silence
false-positive warnings from Lintian, a package checking tool that we'll
discuss later.
* ``rules``: This is a Makefile that provides the instructions for building
the source code of the source package into binaries. Previously this file
was rather large and complicated (and with some more advanced packages it's
still large and complicated), but thanks to some of Debian's more modern
tooling it is a lot easier to work with than it was in the past.
* ``source/format``: This file contains a string indicating what "format" the
package is in. We'll cover formats later.
* ``source/options``: You can usually ignore this file. It contains some
configuration for the ``dpkg-source`` tool, which you will very rarely have
to work with.
* ``upstream/metadata``: This file contains some basic information about the
source package's *upstream*, i.e. the entity that actually wrote the
software you are now packaging for Debian. It's good to know how to work
with these files, but you won't have to touch them very often.
* ``watch``: This file is used to locate, download, and sometimes repack
source code from upstream. It's rare that you'll have to change this file,
and it is usually very painful to work with it, but nonetheless it's good to
understand how to work with it.
Most of the simpler packages you'll work with (including the entire LXQt
stack) will have a ``debian`` directory that more-or-less follows this
structure. More complicated packages may feature a substantially different
package structure, but for now we won't worry about those.
The above is mainly meant to be a teaser of what you'll be working with as a
packager. Before we get into the details of packaging and how it works though,
you should have a good environment for packaging set up. That's what we'll
cover in the next few sections, starting with setting up PGP keys.
PGP keys in Ubuntu development
------------------------------
One critical tool you'll use as an Ubuntu packager is PGP. Put simply, PGP is
a powerful tool used to prove that you take responsibility for some data (i.e.
a Debian package), and to ensure confidential data you send to someone can
only be read by them. This is useful, because as a packager, you will
frequently be uploading packages to Launchpad, and you need to prove that you
are the one doing the uploads for them to be accepted. Rarely, you will also
run into instances where someone has to send you confidential data.
Using PGP effectively requires some understanding of how it works, so we'll
start with an overview of how PGP does what it does.
Overview of PGP concepts
^^^^^^^^^^^^^^^^^^^^^^^^
PGP is a system for encrypting and signing arbitrary data using public key
cryptography. The basic idea behind PGP is that:
* Each PGP user has two keys, a public key and a private key. The public key
is uploaded to a *keyserver* where others can download it, while the private
key is kept secret and is only accessible by the key's owner.
* Any PGP user can use the public key to *encrypt* data. Only the key owner's
secret key can *decrypt* and read the data.
* The key owner can use their secret key to *sign* data, proving that they
claim responsibility for that data. Anyone can use the key owner's public
key to *verify* the signature.
* It is (in practice) impossible to decrypt data encrypted by the public key
without the corresponding private key. It is similarly impossible to create
a signature that can be verified with a public key, without the
corresponding private key. The reason things work this way is beyond the
scope of this guide, but basically PGP uses some clever math tricks to do
what it does. It's been proven to work over years of production use, so it's
very widely used.
Ubuntu uses PGP for several operations, including signing packages. Launchpad
requires that all packages are signed by the packager who claims
responsibility for them, before those packages can be uploaded. The signature
ensures that only authorized users can upload packages, and makes it so that
each package upload can be reliably traced back to the uploader.
Because of PGP's reliance on public keys for verification and encryption, it
is necessary to distribute the public key as widely as possible, so that
individuals can find it and use it to send you encrypted data or verify things
that you send. To facilitate this, there are several *keyservers*, which PGP
software can upload keys to and fetch keys from. PGP keyservers share public
keys with each other, so uploading a key to one keyserver is enough for users
of virtually any other server to fetch that key.
Preparing your PGP keys
^^^^^^^^^^^^^^^^^^^^^^^
.. NOTE::
Ubuntu has `PGP key recommendations
<https://documentation.ubuntu.com/project/contributors/setup/pgp-key-storage/>`__
for secure key storage. This overview is *not* fully compliant with these
recommendations, as the recommendations are non-mandatory, require special
hardware (in the form of a PGP-compatible USB hardware security key), and
are not easy to follow for first-time users. Once you have experience
generating PGP keys in general, you may choose to purchase a hardware
security key and configure it the way the Ubuntu PGP key recommendations
document.
Before you create a PGP key, there are a few recommendations you should
consider:
* If the laptop you intend to do development work on does not already use full
disk encryption, consider backing up your data and reinstalling the machine
with full disk encryption enabled. (This can be accomplished by using the
"Encrypt system" checkbox on the "Partitions" screen of Lubuntu's
installer.) This adds an extra layer of protection to the key.
* You **MUST** back up your key somewhere. If the key should become stolen or
compromised in the future, you will need a copy of it in order to revoke the
key and prevent it from being misused.
* If you are familiar with PGP key generation already, consider ignoring the
rest of this section and following the Ubuntu PGP key recommendations linked
above. These recommendations will have you generate a key in a known-good
environment and upload it to a hardware security key such as a Yubikey. This
provides much greater protection against key theft than the instructions
here.
The standard tool for PGP key management under Ubuntu is GNU Privacy Guard
(GnuPG, usually accessed using the ``gpg`` command). This tool should already
installed on your system. You can use it to generate keys, sign and encrypt
data, verify signatures, and decrypt data sent to you.
To generate a new PGP key using GPG, complete the following steps on your
physical system (do NOT do this in a packaging VM):
1. Open a terminal window (i.e. QTerminal).
2. Run ``gpg --full-generate-key``.
3. When prompted to select the kind of key you want, press ``Return`` to
accept the default of ``ECC (sign and encrypt)``.
4. When prompted to select which elliptic curve you want, press ``Return`` to
accept the default of ``Curve 25519``.
5. When prompted to specify how long the key should be valid, enter a
reasonable amount of time and press ``Return``. (The default, ``0``, will
result in the key never expiring. This is acceptable, however setting a key
expiration data will make you review your key storage practices every so
often, which you may find useful for staying secure.)
6. When asked if the provided expiration data is correct, press ``y``, then
press ``Return``.
7. When prompted for your real name, enter it and press ``Return``. (If you
have a pseudonym that is recognizable in the Ubuntu community, you may use
that instead. What's important is that the key and things you sign with
that key can be clearly traced back to you as an individual.)
8. When prompted for your email address, enter the same email address you use
for your Ubuntu One account and press ``Return``.
9. When prompted for a comment, press ``Return`` to accept the default (empty)
value. (If you intend on using this PGP key only for Ubuntu packaging, you
might consider adding a comment like "Ubuntu packaging key".)
10. When asked for confirmation of your choices, press ``o``, then press
``Return`` to accept your settings.
11. When prompted for a passphrase to protect your key, choose a strong
passphrase and enter it. Note that anyone who gains access to both your
key and its passphrase will be able to forge signatures in your name and
decrypt data sent to you, so it is of vital importance that this
passphrase be very secure. The easiest way to create a strong passphrase
is to pick six to eight random words and use those as your passphrase.
See `XKCD 936 <https://xkcd.com/936/>`__ (but note that four-word
passphrases like suggested in the comic are not very secure). After
entering the passphrase, click "OK" in the popup window.
12. After clicking "OK", wait for the key to be generated. You will see
something like this once the key has been generated::
pub ed25519 2025-11-04 [SC]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid Your Name <name@example.com>
sub cv25519 2025-11-04 [E]
Congratulations, you have now generated a PGP key! You should immediately back
this key up to some "offline" storage (i.e. a storage device that won't be
actively connected to your computer most of the time; flash drives are good
for this). GnuPG saves all of its persistent data, including generated public
and private keys, in the directory ``~/.gnupg``. You can therefore copy this
entire directory to a backup drive to back up the key. This will also back up
any other PGP-related data that GnuPG is storing, such as imported public
keys.
Now that your key is generated and backed up, it's time to upload your public
key to a keyserver. This will of course allow users to verify things you sign
and encrypt data to you. More importantly for packaging though, uploading your
public key to a keyserver will let Launchpad discover it. This will allow you
to bind your key to your account in Launchpad, which will let you use that key
for package uploads later. Uploading a key is pretty simple::
gpg --keyserver keyserver.ubuntu.com --send-key name@example.com
(Replace ``name@example.com`` with the email address you specified when
generating the key.)
Your key is now on the Ubuntu keyserver. Now that you're done with that, it's
time to add the key to Launchpad. This is a bit tricky but not too difficult:
1. In a web browser, go to your user account page on Launchpad (for instance,
``https://launchpad.net/~example``).
2. Under the "User information" section, there is a subsection called "OpenPGP
keys". Click the pen icon next to this section.
3. Launchpad will require you to reauthenticate via Ubuntu One. Provide your
Launchpad account's username and password, click "Log in", then click "Yes,
log me in".
4. Open a terminal window (i.e., QTerminal), and type the command
``gpg --fingerprint | grep -C5 name@example.com``, replacing
``name@example.com`` with your email address. This will show some info
about your PGP key, including the fingerprint. The fingerprint will look
like ``xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx``, with
hexadecimal numbers in place of the "x" characters. Copy the fingerprint
to your clipboard (select it, then press Ctrl+Shift+C).
5. Back in your browser, you should be at the "Change your OpenPGP keys"
screen. Under the "Import an OpenPGP key" section, paste your fingerprint
into the "Fingerprint" field, then click "Import Key". This will cause
Launchpad to send you an email encrypted with your PGP public key, which
will contain an activation link you can use to confirm ownership of the
key.
6. You will receive an email with some instructions, and a block of text
starting with the string ``-----BEGIN PGP MESSAGE-----`` and ending with
the string ``-----END PGP MESSAGE-----``. Copy that block of text with
Ctrl+C.
7. Open a text editor (i.e. Featherpad), and paste the text in with Ctrl+V.
Then save the file to ``~/Documents/pgp-activate.txt``.
8. In a terminal window, run ``gpg --decrypt ~/Documents/pgp-activate.txt``.
Enter your key's passphrase when prompted. This will show you the link
needed to register your key with Launchpad. Copy the link (select it, then
press Ctrl+Shift+C).
9. Open a new tab in your browser, and paste the link into the address bar.
10. Click "Confirm" in the web page that appears.
Congratulations, your PGP key is now registered with Launchpad and is ready
for development use! With that out of the way, we can get to the fun part;
setting up your packaging environment.
Preparing a Debian packaging environment
----------------------------------------
There are a lot of different ways to set up a packaging environment, using
various different tools. The way documented here is a simplified version of my
packaging setup, which essentially uses a KVM-based VM running the latest
development release of Ubuntu, with ``sbuild`` as my primary build tool. This
method works well for me because:
* It uses a full installation of Ubuntu in a VM, rather than a container,
avoiding some of the numerous pitfalls of containers when it comes to
privileges, resource sharing, etc.
* KVM is more robust than much of the other virtualization software available
for Linux (in particular I've found VirtualBox to be problematic in some
instances).
* It avoids issues that often arise when trying to package for a newer version
of Ubuntu using an older version, while not requiring one to run that newer
version as their primary OS.
* It's fairly simple to get working and fairly easy to use.
* ``sbuild`` closely mimics how packages are actually built on Launchpad,
minimizing the chances of odd things happening because of your build
environment.
* It integrates several other packaging tools you should be using, such as
Lintian.
This method is not without disadvantages however:
* If you want to keep your PGP keys out of your VM (which is recommended), it
requires signing packages manually on the host prior to upload.
* Virtualization incurs some overhead, so it can be slower than other
solutions.
The steps are, roughly:
* Install your desired flavor of Ubuntu into a virtual machine.
* Create a shared folder for working on packages on both the VM and host.
* Install and configure packaging utilities.
* Test the system by building sample source and binary packages.
KVM preparation and VM installation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The most common way to use KVM is through virt-manager, a GUI app that is
somewhat similar to VirtualBox. Under the hood, it uses libvirt, QEMU, and KVM
to run VMs.
.. NOTE::
KVM virtualization, much like the rest of Linux, has a lot of different
pieces that work together. QEMU emulates hardware and CPU instructions that
can't be run at full speed, KVM runs CPU instructions that can be run at
full speed, and libvirt makes it easier for applications to work with
QEMU/KVM virtual machines. virt-manager then provides a graphical user
interface for libvirt.
Installation is fairly simple; open QTerminal and run::
sudo apt install virt-manager libvirt-clients libvirt-daemon virtiofsd
sudo systemctl enable libvirtd.service
sudo systemctl start libvirtd.service
You should now be able to create virtual machines using virt-manager.
.. NOTE::
When talking about virtual and physical systems, the physical machine that
runs the VMs is typically called the "host", while the VMs themselves are
typically called "guests".
The next thing to do is to download the latest pre-release image of Lubuntu.
Like mentioned above, it is important to use the latest possible version of
Ubuntu to prevent issues with package builds later. The latest ISO can be
found
`<on cdimage.ubuntu.com https://cdimage.ubuntu.com/lubuntu/daily-live/pending/>`__.
It is generally a good idea to verify your ISO download using GnuPG and
sha256sum. To do this:
1. Create a directory to store the ISO at. ``$HOME/ISO/Lubuntu`` is a good
location.
2. Download the ``CODENAME-desktop-amd64.iso``, ``SHA256SUMS``, and
``SHA256SUMS.gpg`` files for Lubuntu, and move them to the newly created
directory.
3. Open QTerminal in the new directory, and import the PGP key used to sign
Ubuntu ISO images:
``gpg --keyserver keyserver.ubuntu.com --recv-keys 843938DF228D22F7B3742BC0D94AA3F0EFE21092``
4. Verify the SHA256SUMS file is unmodified using GnuPG:
``gpg --keyid-format=long --verify SHA256SUMS.gpg SHA256SUMS``. This
command should show output that looks similar to this::
gpg: Signature made Tue 26 Aug 2025 12:14:14 PM CDT
gpg: using RSA key 843938DF228D22F7B3742BC0D94AA3F0EFE21092
gpg: Good signature from "Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 8439 38DF 228D 22F7 B374 2BC0 D94A A3F0 EFE2 1092
5. Ensure you see the words "Good signature" in the output of GnuPG. If you
see "No public key" or "BAD signature", your download is corrupt. If you
see "Good signature", the SHA256SUMS file is authentic and intact.
6. Verify the ISO file is unmodified using sha256sum:
``sha256sum -c SHA256SUMS``. This command should show output that looks
like ``resolute-desktop-amd64.iso: OK``. If you see this, your ISO download
is authentic and intact.
Once you have a verified Lubuntu download, it's finally time we can create the
VM! To do this:
1. Open the application menu, and launch "Virtual Machine Manager".
2. Wait until the "Connecting" notice near the top of the window disappears.
3. Click the "Create a new virtual machine" button (it's in the very top-left
corner of the window).
4. In the "Create a new virtual machine" window, under "Choose how you would
like to install the operating system", click "Local install media (ISO
image or CDROM), then click "Forward".
5. At the top-right corner of the window, under "Choose ISO or CDROM install
media", click "Browse...".
6. In the "Locate ISO media volume" window, click "Browse Local".
7. In the file selector, navigate to the directory containing the Lubuntu ISO,
then click the ISO file and click "Open".
8. Uncheck the "Automatically detect from the installation media / source"
checkbox.
9. In the "Choose the operating system you are installing" text box, type
"Ubuntu".
10. In the popup that papears, click "ubuntu 25.10 (ubuntu25.10)", then click
"Forward".
11. Set a reasonable amount of RAM and number of CPUs for your hardware.
Package builds usually don't require that much memory or CPU power, but
sometimes they can benefit from lots of memory and CPU power, so it's a
good idea to allocate at least 8192 MB RAM and 4 CPUs if possible.
12. Set a reasonable amount of disk space for the VM. Package builds can take
a lot of disk space, so allocating at least 64 GB is highly recommended
here.
13. Set the VM name to something descriptive (i.e. ``lubuntu-dev``), then
click "Finish". We'll refer to this VM as ``lubuntu-dev`` in the rest of
this document.
The Lubuntu ISO should boot, and you can install it like you normally would.
For best performance, the ``ext4`` filesystem should be used. We won't cover
the Lubuntu installation process here, it's fairly straightforward. Once the
installed system boots up, you should check for updates and install them using
Lubuntu Update (or by running ``sudo apt update && sudo apt full-upgrade`` in
a terminal).
Once all updates are installed, click the application menu inside
``lubuntu-dev``, then hover over "Leave" and click "Shutdown". When LXQt asks
if you want to switch off your computer, click "Yes". (It is important that
you shut down the VM using LXQt's GUI buttons, do NOT run ``shutdown now`` in
a terminal! Doing the first shutdown in this manner prevents an LXQt bug that
breaks several features of Lubuntu.)
Shared folder setup
^^^^^^^^^^^^^^^^^^^
When doing Debian packaging, you will frequently have to modify packages on
both the host and guest systems. Rather than moving files between the guest
and the host all the time, it's easier to use a shared folder. This allows
both the guest and host to see and work on a set of files in the shared
directory.
.. NOTE::
KVM shared folders understand UNIX file permissions, so if a file is owned
by a particular UID on the host, it will appear as being owned by that same
UID in the guest. The default UID for the first user in Lubuntu is 1000. If
your user on the host system has UID 1000, things should work normally, but
if your UID on the host is something other than 1000, you will almost
certainly run into file ownership issues when trying to modify files in the
shared folder within the guest. If this happens, you should create a new
user in the guest with the same UID as your user account on the host, then
do your packaging work using that user account.
.. WARNING::
Do not share your entire home directory with the guest. This can expose
your PGP key to the guest, which is a security hazard.
To add a shared folder to the VM:
1. In the host OS, create a new directory to share between the host and the
guest. We'll assume the shared folder is at ``$HOME/vmshare``.
2. Create a file named ``test-marker.txt`` in ``$HOME/vmshare``. Well use this
to ensure that the shared folder actually works later.
3. Ensure the ``lubuntu-dev`` window is open but the VM itself is powered off.
(You should see the words "Guest is not running." in the middle of the
window.)
4. Click the "Show virtual hardware details" button (it's in the top toolbar,
and is the second button from the left).
5. In the left-hand sidebar, click "Memory", then check the "Enable shared
memory" checkbox and click "Apply"."
6. Underneath the left-hand sidebar, click "Add Hardware".
7. In the "Add New Virtual Hardware" window, in the left-hand sidebar, click
"Filesystem".
8. Ensure that the "Driver" is set to "virtiofs", then set the "Source path"
to ``/home/USERNAME/vmshare`` and the "Target path" to ``vmshare``.
(Replace ``USERNAME`` with your username on the host system.)
9. Click "Finish" to add the shared folder to the VM.
Next, to set up the VM to automatically mount this shared folder on startup:
1. Ensure the ``lubuntu-dev`` window is open, then click the "Power on the
virtual machine" button (it's in the top toolbar, looks like a play button,
and is the third button from the left).
2. Log in if necessary.
3. In the guest, open QTerminal, and run the following commands, replacing
``USERNAME`` with the guest's account's username. This will create a
systemd unit for mounting the shared folder, enable it so it starts on
bootup, and then start it so that the shared folder immediately starts
working::
mkdir $HOME/vmshare
cat <<'EOF' | sudo tee /etc/systemd/system/mount-vmshare.service
[Unit]
Description=Mount shared folder on startup
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=mount -t virtiofs vmshare /home/USERNAME/vmshare
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable mount-vmshare.service
sudo systemctl start mount-vmshare.service
4. The shared folder should be immediately mounted. In the guest, run
``ls $HOME/vmshare``, and verify that you can see the file
``test-marker.txt`` in the directory.
5. In the guest, run ``touch $HOME/vmshare/test-marker-guest.txt``.
6. On the host, run ``ls $HOME/vmshare``, and verify that you can see the
``test-marker-guest.txt`` file.
If both test files can be seen on both the guest and the host, the shared
folder is working. With that out of the way, we can get to the fun part;
installing tools for Debian packaging!
Installing and configuring packaging utilities
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Like mentioned earlier, we're going to be using ``sbuild`` as our primary
packaging tool. We'll go into a bit of detail about what all ``sbuild`` does
and how later. For now, we're just going to get it and the rest of the Debian
packaging tools installed and ready to work.
1. Ensure the ``lubuntu-dev`` window is open and the VM is running.
2. In the guest, open QTerminal, and run the following commands to install
``sbuild`` and several other packaging utilities::
sudo apt install ubuntu-dev-tools debhelper devscripts mmdebstrap git sbuild
3. In the guest, configure ``sbuild``. The following configuration is
relatively basic, works for almost everything, and integrates automatic
package caching. Replace ``Your Name`` and ``name@example.com`` as
appropriate. Do NOT remove the ``1;`` at the end of this config, or it will
break ``sbuild``. To create the config file::
mkdir -p $HOME/.config/sbuild
cat <<'EOF' > $HOME/.config/sbuild/config.pl
$maintainer_name = 'Your Name <name@example.com>';
$distribution = "resolute";
$build_arch_all = 1;
$purge_build_directory = "successful";
$purge_session = "successful";
$purge_build_deps = "successful";
$log_dir = $ENV{HOME}."/ubuntu/logs";
$chroot_mode = "unshare";
$unshare_mmdebstrap_keep_tarball = 1;
$unshare_mmdebstrap_extra_args = [
"*" => [ "--include=debhelper,auto-apt-proxy,ca-certificates" ],
"resolute" => [ "--include=debhelper,auto-apt-proxy,ca-certificates", "--components=main,universe,restricted,multiverse" ],
"questing" => [ "--include=debhelper,auto-apt-proxy,ca-certificates", "--components=main,universe,restricted,multiverse" ],
"plucky" => [ "--include=debhelper,auto-apt-proxy,ca-certificates", "--components=main,universe,restricted,multiverse" ],
"noble" => [ "--include=debhelper,auto-apt-proxy,ca-certificates", "--components=main,universe,restricted,multiverse" ],
];
$lintian_opts = [ '-E', '-v', '-I', '-L', '+pedantic' ];
$clean_source = 0;
1;
EOF
4. In the guest, configure ``quilt``. We'll explain more about what this tool
is and what it does later::
cat <<'EOF' > $HOME/.quiltrc
for where in ./ ../ ../../ ../../../ ../../../../ ../../../../../; do
if [ -e ${where}debian/rules -a -d ${where}debian/patches ]; then
export QUILT_PATCHES=debian/patches
break
fi
done
QUILT_PUSH_ARGS="--color=auto"
QUILT_DIFF_ARGS="--no-timestamps --no-index -p ab --color=auto"
QUILT_REFRESH_ARGS="--no-timestamps --no-index -p ab"
QUILT_DIFF_OPTS='-p'
EOF
5. In the guest, configure ``git``. You may already know what this tool does,
but we'll explain more about it later. Replace ``Your Name`` and
``name@example.com`` as appropriate::
git config --global user.name 'Your Name'
git config --global user.email 'name@example.com'
6. In the guest, configure ``dch``. We'll explain more about what this tool is
and what it does later. Replace ``Your Name`` and ``name@example.com`` as
appropriate::
cat <<'EOF' >> $HOME/.bashrc
export EMAIL='name@example.com'
export DEBEMAIL='name@example.com'
export DEBFULLNAME='Your Name'
EOF
7. In the guest, run ``source $HOME/.bashrc`` so the new settings you've
created for ``dch`` take effect in the currently running shell.
8. On the host, run the following commands to install some necessary packaging
tools there as well::
sudo apt install debhelper devscripts
There's a lot going on here, most of which won't make sense right now. We'll
go into detail about what all these options do later on in this guide.
At this point, your packaging environment is configured and ready to use. It's
time for the last step of setup; building a test package!
Testing the packaging environment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To make sure everything's working smoothly, we're going to use ``sbuild`` to
build binary packages for ``lxqt-about``, the same package we showed an
overview of at the beginning of this document. ``lxqt-about``'s packaging is
stored in the Lubuntu Git instance, so we're going to download the packaging
from there and build it.
1. Ensure the ``lubuntu-dev`` window is open and the VM is running.
2. In the guest, open QTerminal, and create a directory at
``$HOME/vmshare/pkg`` to do packaging in. Then change to the directory::
mkdir $HOME/vmshare/pkg
cd $HOME/vmshare/pkg
3. In the guest, download the Debian packaging for the ``lxqt-about`` package
from Lubuntu Git::
git clone https://git.lubuntu.me/Lubuntu/lxqt-about-packaging.git
4. In the guest, change to the new ``lxqt-about-packaging`` directory with
``cd lxqt-about-packaging``.
5. In the guest, run ``ls``, and ensure you see a single directory named
``debian``.
.. NOTE::
If you remember the overview of ``lxqt-about`` from the start of this
document, you might be confused here, since you only see a ``debian``
directory, not a full package. This is normal; Lubuntu does not duplicate
upstream source code in our packaging, since it's a waste of space and
isn't needed for package builds to still work.
6. In the guest, download the source code for ``lxqt-about`` by running
``uscan --download-current-version``. ``uscan`` is a packaging tool used
to download source code for packaged applications.
.. NOTE::
Due to a
`bug <https://bugs.launchpad.net/ubuntu/+source/devscripts/+bug/2122486>`__,
this might not work for all packages yet.
7. In the guest, build the package with the following command::
sbuild -d resolute
8. In the guest, run ``ls ..``. If all went well, you should see an
``lxqt-about`` deb file, alongside several other files.
That's it! If the above worked, you now have a working packaging environment!
We're now ready to move past system setup, and start learning how packaging
works.