The rpmdev-newspec
tool will create a base spec
file. You’ll have to customize this with your package name and version, license, files included in the package, et al., but it does give you a template you can work with:
$ rpmdev-newspec asbits
asbits.spec created; type minimal, rpm version >= 4.11.
The rpmdev-setuptree
utility will create an RPM
build tree within a user’s home directory. Its subdirectories such as RPMS
and SRPMS
will eventually contain the binary and source packages, respectively:
$ rpmdev-setuptree
$ tree rpmbuild/
rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
5 directories, 0 files
What does a complete SPEC
file look like? Well, it depends on the project. My wee little project asbits
has a very simple SPEC
file that looks like this:
$ cat asbits.spec
Name: asbits
Version: 1.0.0
Release: 1%{?dist}
Summary: Displays hexadecimal, decimal and octal numbers in binary
License: GPLv3+
URL: https://benjamintoll.com/
Source0: https://github.com/btoll/tools/blob/master/c/%{name}/%{name}-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
%description
Displays hexadecimal, decimal and octal numbers in binary
%prep
%setup -q
%build
make %{?_smp_mflags}
%install
%make_install
%files
%license LICENSE
%{_bindir}/%{name}
%doc
%changelog
* Tue May 30 2023 Benjamin Toll <ben@benjamintoll.com> - 1.0.0-1
- First asbits package
The tarball that you create that holds the source code must have a
LICENSE
file or the package devtools will complain and fail to build.
$ mkdir /tmp/asbits-1.0.0
$ find -maxdepth 1 -type f -not -name ".*" -exec cp {} /tmp/asbits-1.0.0/ \;
$ cd /tmp
$ tar -cvzf asbits-1.0.0.tar.gz asbits-1.0.0/
asbits-1.0.0/
asbits-1.0.0/asbits.c
asbits-1.0.0/asbits.h
asbits-1.0.0/Makefile
asbits-1.0.0/LICENSE
$ mv asbits-1.0.0.tar.gz ~/rpmbuild/SOURCES/
$ cd
$ mv asbits.spec rpmbuild/SPECS/
$ tree rpmbuild/
rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
│ └── asbits-1.0.0.tar.gz
├── SPECS
│ └── asbits.spec
└── SRPMS
5 directories, 2 files
Let’s build both the SRPM (source RPM) and the binary RPM:
$ rpmbuild -bs rpmbuild/SPECS/asbits.spec
Wrote: /home/vagrant/rpmbuild/SRPMS/asbits-1.0.0-1.el7.src.rpm
tree rpmbuild/
rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
│ └── asbits-1.0.0.tar.gz
├── SPECS
│ └── asbits.spec
└── SRPMS
└── asbits-1.0.0-1.el7.src.rpm
6 directories, 3 files
$
$ rpmbuild --rebuild rpmbuild/SRPMS/asbits-1.0.0-1.el7.src.rpm
tree rpmbuild/
rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
│ └── x86_64
│ ├── asbits-1.0.0-1.el7.x86_64.rpm
│ └── asbits-debuginfo-1.0.0-1.el7.x86_64.rpm
├── SOURCES
├── SPECS
└── SRPMS
└── asbits-1.0.0-1.el7.src.rpm
7 directories, 3 files
This removed the SPEC
file. Invoking rpmbuild --rebuild
involves:
- Installing the contents of the
SRPM
- theSPEC
file and the source code - into the~/rpmbuild/
directory. - Building using the installed contents.
- Removing the
SPEC
file and the source code.
You can retain the SPEC file and the source code after building. For this, you have two options:
- When building, use the
--recompile
option instead of--rebuild
. - Install the
SRPM
using this command:$ rpm -Uvh ~/rpmbuild/SRPMS/asbits-1.0.0-1.el7.src.rpm
Specifying the --recompile
flag created this directory tree:
$ tree rpmbuild
rpmbuild/
├── BUILD│ └── asbits-1.0.0
│ ├── asbits
│ ├── asbits.c
│ ├── asbits.h
│ ├── debugfiles.list
│ ├── debuglinks.list
│ ├── debugsources.list
│ ├── elfbins.list
│ ├── LICENSE
│ └── Makefile
├── BUILDROOT
│ └── asbits-1.0.0-1.el7.x86_64
│ └── usr
│ ├── bin
│ │ └── asbits
│ ├── lib
│ │ └── debug
│ │ └── usr
│ │ └── bin
│ │ └── asbits.debug
│ ├── share
│ │ └── licenses
│ │ └── asbits-1.0.0
│ │ └── LICENSE
│ └── src
│ └── debug
│ └── asbits-1.0.0
│ ├── asbits.c
│ └── asbits.h
├── RPMS
│ └── x86_64
│ ├── asbits-1.0.0-1.el7.x86_64.rpm
│ └── asbits-debuginfo-1.0.0-1.el7.x86_64.rpm
├── SOURCES
│ └── asbits-1.0.0.tar.gz
├── SPECS
│ └── asbits.spec
└── SRPMS
└── asbits-1.0.0-1.el7.src.rpm
21 directories, 19 files
You can also build the binary RPM using the -bb
flag (build binary), which doesn’t do the steps above that are initiated by doing --rebuild
, that is, it won’t remove the SPEC
file and the tarball in rpmbuild/SOURCES
:
$ rpmbuild -bb rpmbuild/SPECS/asbits.spec
$ tree rpmbuild/
rpmbuild/
├── BUILD
│ └── asbits-1.0.0
│ ├── asbits
│ ├── asbits.c
│ ├── asbits.h
│ ├── debugfiles.list
│ ├── debuglinks.list
│ ├── debugsources.list
│ ├── elfbins.list
│ ├── LICENSE
│ └── Makefile
├── BUILDROOT
├── RPMS
│ └── x86_64
│ ├── asbits-1.0.0-1.el7.x86_64.rpm
│ └── asbits-debuginfo-1.0.0-1.el7.x86_64.rpm
├── SOURCES
│ └── asbits-1.0.0.tar.gz
├── SPECS
│ └── asbits.spec
└── SRPMS
└── asbits-1.0.0-1.el7.src.rpm
8 directories, 14 files
Here is the new package:
asbits-1.0.0-1.el7.x86_64.rpm
$ rpm -qlp rpmbuild/RPMS/x86_64/asbits-1.0.0-1.el7.x86_64.rpm
/usr/bin/asbits
/usr/share/licenses/asbits-1.0.0
/usr/share/licenses/asbits-1.0.0/LICENSE
weeeeeeeeeeeeeeeeeeeeeeeee
Let’s verify it!
$ rpmlint rpmbuild/SPECS/asbits.spec
0 packages and 1 specfiles checked; 0 errors, 0 warnings.
$ rpmlint rpmbuild/RPMS/x86_64/asbits-1.0.0-1.el7.x86_64.rpm
asbits.x86_64: W: no-documentation
asbits.x86_64: W: no-manual-page-for-binary asbits
1 packages and 0 specfiles checked; 0 errors, 2 warnings.
When binary RPMs are checked rpmlint
will check for:
- documentation
- manual pages
- consistent use of the Filesystem Hierarchy Standard
Let’s install it!
$ asbits
-bash: asbits: command not found
$ sudo rpm -i rpmbuild/RPMS/x86_64/asbits-1.0.0-1.el7.x86_64.rpm
[vagrant@localhost ~]$ asbits 255
0000 0000 1111 1111
$
How to expand the macros?
$ rpmspec -P rpmbuild/SPECS/asbits.spec
Name: asbits
Version: 1.0.0
Release: 1.el7
Summary: Displays hexadecimal, decimal and octal numbers in binary
License: GPLv3+
URL: https://benjamintoll.com/
Source0: https://github.com/btoll/tools/blob/master/c/asbits/asbits-1.0.0.tar.gz
BuildRequires: gcc
BuildRequires: make
%description
Displays hexadecimal, decimal and octal numbers in binary
%prep
%setup -q
%build
make -j3
%package debuginfo
Summary: Debug information for package asbits
Group: Development/Debug
AutoReqProv: 0
%description debuginfo
This package provides debug information for package asbits.
Debug information is useful when developing applications that use this
package or when debugging this package.
%files debuginfo -f debugfiles.list
%defattr(-,root,root)
%install
rm -rf $RPM_BUILD_ROOT
/usr/bin/make install DESTDIR=/home/vagrant/rpmbuild/BUILDROOT/asbits-1.0.0-1.el7.x86_64
%files
%license LICENSE
/usr/bin/asbits
%doc
%changelog
* Mon May 29 2023 Benjamin Toll <ben@benjamintoll.com> - 1.0.0-1
- First asbits package
Print a list of all of the tags rpm
knows about:
$ rpm --querytags
- new edits
%install
mkdir -p %{buildroot}/%{_bindir}
install -m 0755 %{name} %{buildroot}%{_bindir}/%{name}
Name: simple-chat
Version: 1.0.0
Release: 1%{?dist}
Summary: Here be a simple chat server!
License: GPLv3+
URL: https://benjamintoll.com/
Source0: https://github.com/btoll/simple-chat/releases/download/1.0.0/%{name}-%{version}.tar.gz
BuildRequires: gcc
Requires: make
%description
Here be a simple chat server!
%prep
%setup -q
%build
make %{?_smp_mflags}
%install
%make_install
%files
%license LICENSE
%{_bindir}/%{name}
%doc
%changelog
* Mon May 29 2023 Benjamin Toll <ben@benjamintoll.com> - 1.0.0-1
- First simple-chat package