RPM Packaging Guide Red Hat Enterprise Linux 7 Basic and advanced software packaging scenarios using the RPM package manager Customer Content Services rhel-notes@redhat.com Marie Dolezelova Red Hat Customer Content Services mdolezel@redhat.com Maxim Svistunov Red Hat Customer Content Services Adam Miller Red Hat Adam Kvitek Red Hat Customer Content Services Petr Kovar Red Hat Customer Content Services Miroslav Suchy Red Hat

Commands:
Name: hello-world Version: 1 Release: 1 Summary: Most simple RPM package License: FIXME %description This is my first RPM package, which does nothing. %prep we have no source, so nothing here %build cat > hello-world.sh <<EOF #!/usr/bin/bash echo Hello world EOF %install mkdir -p %{buildroot}/usr/bin/ install -m 755 hello-world.sh %{buildroot}/usr/bin/hello-world.sh %files /usr/bin/hello-world.sh %changelog let's skip this for now
rpmdev-setuptree rpmbuild -ba hello-world.spec
... [SNIP] Wrote: /home/<username>/rpmbuild/SRPMS/hello-world-1-1.src.rpm Wrote: /home/<username>/rpmbuild/RPMS/x86_64/hello-world-1-1.x86_64.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.wgaJzv + umask 022 + cd /home/<username>/rpmbuild/BUILD + /usr/bin/rm -rf /home/<username>/rpmbuild/BUILDROOT/hello-world-1-1.x86_64 + exit 0
#!/bin/bash printf "Hello World\n"
#!/usr/bin/python3 print("Hello World")
#include <stdio.h> int main(void) { printf("Hello World\n"); return 0; }
#include <stdio.h> int main(void) { printf("Hello World\n"); return 0; }
gcc -g -o cello cello.c
./cello Hello World
cello: gcc -g -o cello cello.c clean: rm cello
make make: 'cello' is up to date.
make clean rm cello make gcc -g -o cello cello.c
make make: 'cello' is up to date.
./cello Hello World
#!/usr/bin/python3 print("Hello World")
python -m compileall pello.py file pello.pyc pello.pyc: python 2.7 byte-compiled
python pello.pyc Hello World
#!/bin/bash printf "Hello World\n"
chmod +x bello ./bello Hello World
cp -p cello.c cello.c.orig
#include <stdio.h> int main(void) { printf("Hello World from my very first patch!\n"); return 0; }
diff -Naur cello.c.orig cello.c --- cello.c.orig 2016-05-26 17:21:30.478523360 -0500 + cello.c 2016-05-27 14:53:20.668588245 -0500 @@ -1,6 +1,6 @@ #include<stdio.h> int main(void){ - printf("Hello World!\n"); + printf("Hello World from my very first patch!\n"); return 0; } \ No newline at end of file
diff -Naur cello.c.orig cello.c > cello-output-first-patch.patch
cp cello.c.orig cello.c
patch < cello-output-first-patch.patch patching file cello.c
cat cello.c #include<stdio.h> int main(void){ printf("Hello World from my very first patch!\n"); return 1; }
make clean rm cello make gcc -g -o cello cello.c ./cello Hello World from my very first patch!
sudo install -m 0755 bello /usr/bin/bello
cd ~ bello Hello World
cello: gcc -g -o cello cello.c clean: rm cello install: mkdir -p USD(DESTDIR)/usr/bin install -m 0755 cello USD(DESTDIR)/usr/bin/cello
make gcc -g -o cello cello.c sudo make install install -m 0755 cello /usr/bin/cello
cd ~ cello Hello World
cat /tmp/LICENSE This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ .
mkdir /tmp/bello-0.1 mv ~/bello /tmp/bello-0.1/ cp /tmp/LICENSE /tmp/bello-0.1/
cd /tmp/ tar -cvzf bello-0.1.tar.gz bello-0.1 bello-0.1/ bello-0.1/LICENSE bello-0.1/bello mv /tmp/bello-0.1.tar.gz ~/rpmbuild/SOURCES/
mkdir /tmp/pello-0.1.2 mv ~/pello.py /tmp/pello-0.1.2/ cp /tmp/LICENSE /tmp/pello-0.1.2/
cd /tmp/ tar -cvzf pello-0.1.2.tar.gz pello-0.1.2 pello-0.1.2/ pello-0.1.2/LICENSE pello-0.1.2/pello.py mv /tmp/pello-0.1.2.tar.gz ~/rpmbuild/SOURCES/
mkdir /tmp/cello-1.0 mv ~/cello.c /tmp/cello-1.0/ mv ~/Makefile /tmp/cello-1.0/ cp /tmp/LICENSE /tmp/cello-1.0/
cd /tmp/ tar -cvzf cello-1.0.tar.gz cello-1.0 cello-1.0/ cello-1.0/Makefile cello-1.0/cello.c cello-1.0/LICENSE mv /tmp/cello-1.0.tar.gz ~/rpmbuild/SOURCES/
mv ~/cello-output-first-patch.patch ~/rpmbuild/SOURCES/
yum install rpmdevtools
rpm -ql rpmdevtools | grep bin
yum install rpmdevtools
rpmdev-setuptree tree ~/rpmbuild/ /home/<username>/rpmbuild/ |-- BUILD |-- RPMS |-- SOURCES |-- SPECS `-- SRPMS 5 directories, 0 files
rpm -q bash bash-4.2.46-34.el7.x86_64
rpm --eval %{_MACRO}
rpm --eval %{_bindir} /usr/bin rpm --eval %{_libexecdir} /usr/libexec
On a RHEL 8.x machine rpm --eval %{?dist} .el8
cd ~/rpmbuild/SPECS rpmdev-newspec bello bello.spec created; type minimal, rpm version >= 4.11. rpmdev-newspec cello cello.spec created; type minimal, rpm version >= 4.11. rpmdev-newspec pello pello.spec created; type minimal, rpm version >= 4.11.
Name: bello Version: 0.1 Release: 1%{?dist} Summary: Hello World example implemented in bash script License: GPLv3+ URL: https://www.example.com/%{name} Source0: https://www.example.com/%{name}/releases/%{name}-%{version}.tar.gz Requires: bash BuildArch: noarch %description The long-tail description for our Hello World Example implemented in bash script. %prep %setup -q %build %install mkdir -p %{buildroot}/%{_bindir} install -m 0755 %{name} %{buildroot}/%{_bindir}/%{name} %files %license LICENSE %{_bindir}/%{name} %changelog * Tue May 31 2016 Adam Miller < maxamillion@fedoraproject.org > - 0.1-1 - First bello package - Example second item in the changelog for version-release 0.1-1
Name: pello Version: 0.1.1 Release: 1%{?dist} Summary: Hello World example implemented in Python License: GPLv3+ URL: https://www.example.com/%{name} Source0: https://www.example.com/%{name}/releases/%{name}-%{version}.tar.gz BuildRequires: python Requires: python Requires: bash BuildArch: noarch %description The long-tail description for our Hello World Example implemented in Python. %prep %setup -q %build python -m compileall %{name}.py %install mkdir -p %{buildroot}/%{_bindir} mkdir -p %{buildroot}/usr/lib/%{name} cat > %{buildroot}/%{_bindir}/%{name} <<-EOF #!/bin/bash /usr/bin/python /usr/lib/%{name}/%{name}.pyc EOF chmod 0755 %{buildroot}/%{_bindir}/%{name} install -m 0644 %{name}.py* %{buildroot}/usr/lib/%{name}/ %files %license LICENSE %dir /usr/lib/%{name}/ %{_bindir}/%{name} /usr/lib/%{name}/%{name}.py* %changelog * Tue May 31 2016 Adam Miller < maxamillion@fedoraproject.org > - 0.1.1-1 - First pello package
Name: cello Version: 1.0 Release: 1%{?dist} Summary: Hello World example implemented in C License: GPLv3+ URL: https://www.example.com/%{name} Source0: https://www.example.com/%{name}/releases/%{name}-%{version}.tar.gz Patch0: cello-output-first-patch.patch BuildRequires: gcc BuildRequires: make %description The long-tail description for our Hello World Example implemented in C. %prep %setup -q %patch0 %build make %{?_smp_mflags} %install %make_install %files %license LICENSE %{_bindir}/%{name} %changelog * Tue May 31 2016 Adam Miller < maxamillion@fedoraproject.org > - 1.0-1 - First cello package
rpmbuild -bs SPECFILE
cd ~/rpmbuild/SPECS/ 8USD rpmbuild -bs bello.spec Wrote: /home/<username>/rpmbuild/SRPMS/bello-0.1-1.el8.src.rpm rpmbuild -bs pello.spec Wrote: /home/<username>/rpmbuild/SRPMS/pello-0.1.2-1.el8.src.rpm rpmbuild -bs cello.spec Wrote: /home/<username>/rpmbuild/SRPMS/cello-1.0-1.el8.src.rpm
rpmbuild --rebuild ~/rpmbuild/SRPMS/bello-0.1-1.el8.src.rpm [output truncated] rpmbuild --rebuild ~/rpmbuild/SRPMS/pello-0.1.2-1.el8.src.rpm [output truncated] rpmbuild --rebuild ~/rpmbuild/SRPMS/cello-1.0-1.el8.src.rpm [output truncated]
rpm -Uvh ~/rpmbuild/SRPMS/bello-0.1-1.el8.src.rpm Updating / installing... 1:bello-0.1-1.el8 [100%] rpm -Uvh ~/rpmbuild/SRPMS/pello-0.1.2-1.el8.src.rpm Updating / installing... ... 1:pello-0.1.2-1.el8 [100%] rpm -Uvh ~/rpmbuild/SRPMS/cello-1.0-1.el8.src.rpm Updating / installing... ... 1:cello-1.0-1.el8 [100%]
rpmbuild -bb ~/rpmbuild/SPECS/bello.spec rpmbuild -bb ~/rpmbuild/SPECS/pello.spec rpmbuild -bb ~/rpmbuild/SPECS/cello.spec
rpmbuild {-ra|-rb|-rp|-rc|-ri|-rl|-rs} [rpmbuild-options] SOURCEPACKAGE
rpmlint bello.spec bello.spec: W: invalid-url Source0: https://www.example.com/bello/releases/bello-0.1.tar.gz HTTP Error 404: Not Found 0 packages and 1 specfiles checked; 0 errors, 1 warnings.
rpmlint ~/rpmbuild/SRPMS/bello-0.1-1.el8.src.rpm bello.src: W: invalid-url URL: https://www.example.com/bello HTTP Error 404: Not Found bello.src: W: invalid-url Source0: https://www.example.com/bello/releases/bello-0.1.tar.gz HTTP Error 404: Not Found 1 packages and 0 specfiles checked; 0 errors, 2 warnings.
rpmlint ~/rpmbuild/RPMS/noarch/bello-0.1-1.el8.noarch.rpm bello.noarch: W: invalid-url URL: https://www.example.com/bello HTTP Error 404: Not Found bello.noarch: W: no-documentation bello.noarch: W: no-manual-page-for-binary bello 1 packages and 0 specfiles checked; 0 errors, 3 warnings.
rpmlint pello.spec pello.spec:30: E: hardcoded-library-path in %{buildroot}/usr/lib/%{name} pello.spec:34: E: hardcoded-library-path in /usr/lib/%{name}/%{name}.pyc pello.spec:39: E: hardcoded-library-path in %{buildroot}/usr/lib/%{name}/ pello.spec:43: E: hardcoded-library-path in /usr/lib/%{name}/ pello.spec:45: E: hardcoded-library-path in /usr/lib/%{name}/%{name}.py* pello.spec: W: invalid-url Source0: https://www.example.com/pello/releases/pello-0.1.2.tar.gz HTTP Error 404: Not Found 0 packages and 1 specfiles checked; 5 errors, 1 warnings.
rpmlint ~/rpmbuild/SRPMS/pello-0.1.2-1.el8.src.rpm pello.src: W: invalid-url URL: https://www.example.com/pello HTTP Error 404: Not Found pello.src:30: E: hardcoded-library-path in %{buildroot}/usr/lib/%{name} pello.src:34: E: hardcoded-library-path in /usr/lib/%{name}/%{name}.pyc pello.src:39: E: hardcoded-library-path in %{buildroot}/usr/lib/%{name}/ pello.src:43: E: hardcoded-library-path in /usr/lib/%{name}/ pello.src:45: E: hardcoded-library-path in /usr/lib/%{name}/%{name}.py* pello.src: W: invalid-url Source0: https://www.example.com/pello/releases/pello-0.1.2.tar.gz HTTP Error 404: Not Found 1 packages and 0 specfiles checked; 5 errors, 2 warnings.
rpmlint ~/rpmbuild/RPMS/noarch/pello-0.1.2-1.el8.noarch.rpm pello.noarch: W: invalid-url URL: https://www.example.com/pello HTTP Error 404: Not Found pello.noarch: W: only-non-binary-in-usr-lib pello.noarch: W: no-documentation pello.noarch: E: non-executable-script /usr/lib/pello/pello.py 0644L /usr/bin/env pello.noarch: W: no-manual-page-for-binary pello 1 packages and 0 specfiles checked; 1 errors, 4 warnings.
rpmlint ~/rpmbuild/SPECS/cello.spec /home/<username>/rpmbuild/SPECS/cello.spec: W: invalid-url Source0: https://www.example.com/cello/releases/cello-1.0.tar.gz HTTP Error 404: Not Found 0 packages and 1 specfiles checked; 0 errors, 1 warnings.
rpmlint ~/rpmbuild/SRPMS/cello-1.0-1.el8.src.rpm cello.src: W: invalid-url URL: https://www.example.com/cello HTTP Error 404: Not Found cello.src: W: invalid-url Source0: https://www.example.com/cello/releases/cello-1.0.tar.gz HTTP Error 404: Not Found 1 packages and 0 specfiles checked; 0 errors, 2 warnings.
rpmlint ~/rpmbuild/RPMS/x86_64/cello-1.0-1.el8.x86_64.rpm cello.x86_64: W: invalid-url URL: https://www.example.com/cello HTTP Error 404: Not Found cello.x86_64: W: no-documentation cello.x86_64: W: no-manual-page-for-binary cello 1 packages and 0 specfiles checked; 0 errors, 3 warnings.
# gpg --gen-key
# gpg --list-keys
# gpg --export -a '<Key_name>' > RPM-GPG-KEY-pmanager
# rpm --import RPM-GPG-KEY-pmanager
rpm --addsign blather-7.9-1.x86_64.rpm
rpm --checksig blather-7.9-1.x86_64.rpm blather-7.9-1.x86_64.rpm: size pgp pgp md5 OK
rpm --resign blather-7.9-1.x86_64.rpm
rpm --resign b*.rpm
rpmbuild blather-7.9.spec
rpmsign --addsign blather-7.9-1.x86_64.rpm
rpm --checksig blather-7.9-1.x86_64.rpm blather-7.9-1.x86_64.rpm: size pgp md5 OK
rpmbuild -ba --sign b*.spec
%global <name>[(opts)] <body>
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.DhddsG
cd '/builddir/build/BUILD' rm -rf 'cello-1.0' /usr/bin/gzip -dc '/builddir/build/SOURCES/cello-1.0.tar.gz' | /usr/bin/tar -xof - STATUS=USD? if [ USDSTATUS -ne 0 ]; then exit USDSTATUS fi cd 'cello-1.0' /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
Name: cello Source0: https://example.com/%{name}/release/hello-%{version}.tar.gz ... %prep %setup -n hello
/usr/bin/mkdir -p cello-1.0 cd 'cello-1.0'
rm -rf 'cello-1.0'
/usr/bin/gzip -dc '/builddir/build/SOURCES/cello-1.0.tar.gz' | /usr/bin/tar -xvvof -
Source0: https://example.com/%{name}/release/%{name}-%{version}.tar.gz Source1: examples.tar.gz ... %prep %setup -a 1
Source0: https://example.com/%{name}/release/%{name}-%{version}.tar.gz Source1: %{name}-%{version}-examples.tar.gz ... %prep %setup -b 1
--showrc
-ql rpm
--showrc
--eval %{_MACRO}
%_topdir /opt/some/working/directory/rpmbuild
%_smp_mflags -l3
rpm --nopretrans
rpm --showrc | grep systemd -14: transaction_systemd_inhibit %{ plugindir}/systemd_inhibit.so -14: _journalcatalogdir /usr/lib/systemd/catalog -14: _presetdir /usr/lib/systemd/system-preset -14: _unitdir /usr/lib/systemd/system -14: _userunitdir /usr/lib/systemd/user /usr/lib/systemd/systemd-binfmt %{? } >/dev/null 2>&1 || : /usr/lib/systemd/systemd-sysctl %{? } >/dev/null 2>&1 || : -14: systemd_post -14: systemd_postun -14: systemd_postun_with_restart -14: systemd_preun -14: systemd_requires Requires(post): systemd Requires(preun): systemd Requires(postun): systemd -14: systemd_user_post %systemd_post --user --global %{? } -14: systemd_user_postun %{nil} -14: systemd_user_postun_with_restart %{nil} -14: systemd_user_preun systemd-sysusers %{? } >/dev/null 2>&1 || : echo %{? } | systemd-sysusers - >/dev/null 2>&1 || : systemd-tmpfiles --create %{? } >/dev/null 2>&1 || : rpm --eval %{systemd_post} if [ USD1 -eq 1 ] ; then # Initial installation systemctl preset >/dev/null 2>&1 || : fi rpm --eval %{systemd_postun} systemctl daemon-reload >/dev/null 2>&1 || : rpm --eval %{systemd_preun} if [ USD1 -eq 0 ] ; then # Package removal, not upgrade systemctl --no-reload disable > /dev/null 2>&1 || : systemctl stop > /dev/null 2>&1 || : fi
all-%pretrans ... any-%triggerprein (%triggerprein from other packages set off by new install) new-%triggerprein new-%pre for new version of package being installed ... (all new files are installed) new-%post for new version of package being installed any-%triggerin (%triggerin from other packages set off by new install) new-%triggerin old-%triggerun any-%triggerun (%triggerun from other packages set off by old uninstall) old-%preun for old version of package being removed ... (all old files are removed) old-%postun for old version of package being removed old-%triggerpostun any-%triggerpostun (%triggerpostun from other packages set off by old un install) ... all-%posttrans
install -m 0644 %{name}.py* %{buildroot}/usr/lib/%{name}/
%post -p /usr/bin/python3 print("This is {} code".format("python"))
yum install /home/<username>/rpmbuild/RPMS/noarch/pello-0.1.2-1.el8.noarch.rpm
Installing : pello-0.1.2-1.el8.noarch 1/1 Running scriptlet: pello-0.1.2-1.el8.noarch 1/1 This is python code
%post -p /usr/bin/python3
%post -p <lua>
%if expression ... %endif
%if expression ... %else ... %endif
%if 0%{?rhel} == 8 sed -i '/AS_FUNCTION_DESCRIBE/ s/^/ /' configure.in sed -i '/AS_FUNCTION_DESCRIBE/ s/^/ /' acinclude.m4 %endif
%define ruby_archive %{name}-%{ruby_version} %if 0%{?milestone:1}%{?revision:1} != 0 %define ruby_archive %{ruby_archive}-%{?milestone}%{?!milestone:%{?revision:r%{revision}}} %endif
%ifarch i386 sparc ... %endif
%ifnarch alpha ... %endif
%ifos linux ... %endif