In-Depth Packaging¶
This tutorial assumes that you’ve completed the get started tutorial and have a working specfile that you have built. If you have not done that, please complete that tutorial and come back later. Your specfile shoud look like this:
Name: hello
Version: 2.10
Release: 1
License: GPLv3+
URL: https://www.gnu.org/software/hello/
Summary: GNU's Hello World Program
Source0: https://ftp.gnu.org/gnu/hello/hello-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
BuildRequires: gettext
%description
The "Hello World" program, done with all bells and whistles of a proper FOSS
project, including configuration, build, internationalization, help files, etc.
%prep
%autosetup
%build
%configure
%make_build
%install
%make_install
%files
%{_bindir}/hello
%{_datadir}/info/hello.info.gz
%{_datadir}/man/man1/hello.1.gz
%{_datadir}/locale/*/LC_MESSAGES/hello.mo
%changelog
* Wed Dec 18 2019 Firstname Lastname <email.com> 2.10-1
- Initial packaging for distro
Subpackages¶
The core aspect of this tutorial is the subpackage. A specfile is able to create multiple packages from one larger package, and this is called subpackaging. This is often done for development files, debugging files, translations, etc.
Unlike a full package, subpackages cannot live without a parent package. Instead, they’re simply a separated listing of files shipped as its own package.
%find_lang
¶
The %find_lang
macro is what will do most of the heavy lifting for us when it
comes to translations. You want to give it your package’s name as an argument,
which can be done with the %{name}
macro. Add this to the end of your %install
section:
%find_lang %{name}
This will create an internal list of files corresponding to all translations.
You will want to remove the %{_datadir}/locale/*/LC_MESSAGES/hello.mo
entry
in %files
, as we will be putting this in a separate %files
section later.
Declaring the Subpackage¶
At the end of the body but before the changelog, we want to declare a new %package
.
When you declare a new %package
, you need to give it a subpackage name as an argument.
This subpackage name will become appended to the parent package’s name, generating the
package name that the end user will see. If a specfile has a Name: hello
and a %package world
,
the specfile will produce two packages: hello
and hello-world
.
Since we’re creating a subpackage to hold translations, our subpackage should be named
lang
. Declare that like so:
%package lang
Just like a regular package, a subpackage will need a Summary:
and a %description
.
The %{name}
macro can be used to use the name of the parent package.
Go ahead and add those under the %package
directive like so:
%package lang
Summary: Translations for %{name}
%description lang
This package provides translation files for %{name}.
This is a basic subpackage, but we need to do two things: Add a Requires:
tag
and a Supplements:
tag.
Requires¶
There’s no reason to install translations for a program you don’t have, right?
This is what the Requires:
tag is used for. It allows you to mandate that
another package be installed in order for a package to be installed.
Add a Requires:
tag to your subpackage like so:
%package lang
Requires: %{name}
Wouldn’t it be nice if you could make sure the correct translation versions were always
paired up with the correct program version? You can do this by adding = %{version}-%{release}
to the end of the Requires:
tag. Add them like so:
%package lang
Requires: %{name} = %{version}-%{release}
This means that translation and program packages produced by the same specfile will always want to be the same version.
Supplements¶
We have our package split, but we don’t actually suggest to the package manager that
we install translations. This is where the Supplements:
tag comes in. It tells
the package manager that our subpackage supplements the parent package.
Just like the requires tag wanting to always be with the same version of the parent package, we should only want to suggest that this package be installed for the same version of the parent package.
Add this to your %package lang
section:
Supplements: %{name} = %{version}-%{release}
Your subpackage declaration should look like this:
%package lang
Requires: %{name} = %{version}-%{release}
Supplements: %{name} = %{version}-%{release}
Summary: Translations for %{name}
%description lang
This package provides translation files for %{name}.
Putting Something in the Subpackage¶
We have our subpackage, and we have our language files list, but how do we put them
together? We add another %files
section for the subpackage.
Just like %package
and %description
, we add the name of the subpackage
to %files
. However, since we already have an internal files list, we’ll
be doing something new.
We want to tell the %files lang
section to use the list of files made by
the %find_lang
macro we used earlier. We add the -f
flag to %files
,
followed by the name of the list %find_lang
generated. For our package, this
is called %{name}.lang
Assembling all the pieces together, that results in this:
%files lang -f %{name}.lang
Your subpackage should now look like this:
%package lang
Requires: %{name} = %{version}-%{release}
Supplements: %{name} = %{version}-%{release}
Summary: Translations for %{name}
%description lang
This package provides translation files for %{name}.
%files lang -f %{name}.lang
Finishing Touches¶
Now that we’ve split our language files into a subpackage, we should add a new
entry to our changelog and increment our release version. Change Release: 1
to Release: 2
, as this is how we tell the package manager that something changed
in the package that wasn’t the package’s program itself.
Changelog entries are newer at the top and older at the bottom, so put the new entry at the top of the section. It should look something like this:
%changelog
* Fri Dec 20 2019 Firstname Lastname <email.com> 2.10-2
- Split language files into subpackage
* Wed Dec 18 2019 Firstname Lastname <email.com> 2.10-1
- Initial packaging for distro
Our specfile should now look like this:
Name: hello
Version: 2.10
Release: 2
License: GPLv3+
URL: https://www.gnu.org/software/hello/
Summary: GNU's Hello World Program
Source0: https://ftp.gnu.org/gnu/hello/hello-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
BuildRequires: gettext
%description
The "Hello World" program, done with all bells and whistles of a proper FOSS
project, including configuration, build, internationalization, help files, etc.
%prep
%autosetup
%build
%configure
%make_build
%install
%make_install
%find_lang %{name}
%files
%{_bindir}/hello
%{_datadir}/info/hello.info.gz
%{_datadir}/man/man1/hello.1.gz
%package lang
Requires: %{name} = %{version}-%{release}
Supplements: %{name} = %{version}-%{release}
Summary: Translations for %{name}
%description lang
This package provides translation files for %{name}.
%files lang -f %{name}.lang
%changelog
* Fri Dec 20 2019 Firstname Lastname <email.com> 2.10-2
- Split language files into subpackage
* Wed Dec 18 2019 Firstname Lastname <email.com> 2.10-1
- Initial packaging for distro