polycat.spec | ||
README.md | ||
update-version.sh |
How to package RPMs
A guide by someone who doesn't know what they're doing.
We'll be using polycat as an example, a fairly simple C++ program
Setup
First off, you're gonna want to install fedora-packager
and rpmdevtools
.
sudo dnf install fedora-packager rpmdevtools
Next, set up the directory tree for RPM packaging development.
rpmdev-setuptree
This will create ~/rpmbuild/
, which will contain the following:
BUILD/ RPMS/ SOURCES/ SPECS/ SRPMS/
Then, to create a new .spec
file, use rpmdev-newspec $FILENAME
. As mentioned before, we'll be using polycat for our example.
rpmdev-newspec polycat.spec
Metadata
First off, there's the obvious metadata:
Name: polycat
Version: r93.0c836d5
Release: %autorelease
Summary: runcat module for polybar (or waybar)
License: MIT
URL: https://github.com/2IMT/polycat
%description
A runcat module for polybar (or waybar) written in C++
(note: License uses SPDX license list identifiers)
And the dependencies, also self-explanatory:
BuildRequires: cmake g++ git tar
Requires: glibc
Sources
Polycat's release could be considered out of date, as there hasn't been a commit in a bit over a year, so in my opinion packaging from the official release is not appropriate - it's also not what the official PKGBUILD for it on the AUR does. So instead, we'll be packaging it all, both polycat itself and its dependencies, via Git, rather than adding Source
(s) to our spec file.
Additionally, Polycat uses Git submodules for dependencies, which %forgemeta
doesn't support, as it doesn't clone recursively, and neither does Github's tarball, so we'll just clone it via Git directly.
%prep
git clone --recursive https://github.com/2IMT/polycat.git --depth 1 --shallow-submodules
Side note: You could use actual sources rather than git clone
-ing it by using %forgemeta
several times, or listing several Sources, but that's much more effort and is much harder to automate, for little benefit as far as I know.
Build
A few things here. First off, we'll start by declaring the %build
section. Rather than just using CMake directly, rpmbuild
has macros for it instead; pretty self-explanatory. However, cmake will instead output to ./redhat-linux-build/
if you don't specify where. Docs for all of this are here.
%build
cd ./polycat/
%cmake -DCMAKE_BUILD_TYPE=RELEASE
%cmake_build
Note that the different sections are run separately, the current directory is not preserved between them. So if we wanted to, say, apply some patches in %prep
, then we'd still have to cd ./polycat
again here
Install
As for the installation, you can use something like %make_install
if applicable, but we'll just be installing Polycat manually.
%install
cd ./polycat/
mkdir -p %{buildroot}%{_bindir}
install -Dm755 ./redhat-linux-build/polycat %{buildroot}%{_bindir}/polycat
mkdir -p %{buildroot}%{datadir}/fonts/polycat/
install -Dm644 ./res/polycat.ttf %{buildroot}%{_datadir}/fonts/polycat/polycat.ttf
Again, because different sections are run separately, we have to cd
into ./polycat/
again.
%{buildroot}
is the root of the build's output directory - it contains the files that will be put in the rpm.%{_bindir}
defaults to/usr/bin
For more details on these macros, you can see this page.
Building the RPM
See rpmbuild's man page for details, but to build a binary package, we'll do this:
rpmbuild -bb polycat.spec
More metadata (%files
)
We just finish this off by listing all the files this package provides. Not sure why rpmbuild doesn't just do this automatically, but if you don't list them, then rpmbuild will fail with Installed (but unpackaged) file(s)
.
%files
%{_bindir}/polycat
%{_datadir}/fonts/polycat/polycat.ttf
Resources
- Macros
- Build systems
- %autosetup and %autopatch (successors to %setup and %patch)
- Using forges