If you use RedHat or Fedora you will quickly find out yourself using ‘dnf’ (or yum) to install software packages. RPM is the most important software management tool on this Linux distributions and you will see shortly how you can take advantage of this framework to distribute your own software.
Hopefully you got a chance to read a previously written article on the same subject by Valentin Bajrami. I will repeat some of the same concepts here but will ilustrate a few issues you may find on the way when you package. Also will use a 2 more complex examples and a few issues you may find when packaging native applications.
By the end of this article you will be able to do:
I assume the following:
sudo dnf install -y make gcc-10 java-11-openjdk-headless git
This will install make, gcc, java 11 and git using dnf package manager.
For this will use a small Open Source project called jdumpertools.
On your Linux terminal, clone it and then compile it (you have installed Make and the gcc compiler, right? :-D)
git clone git@github.com:josevnz/jdumpertools.git
cd jdumpertools
make all
josevnz@dmaf5 jdumpertools]$ ls -l jdu jutmp *.so
-rwxrwxr-x 1 josevnz josevnz 32728 Oct 3 16:40 jdu
-rwxrwxr-x 1 josevnz josevnz 32752 Oct 3 16:40 jutmp
-rwxrwxr-x 1 josevnz josevnz 29024 Oct 3 16:40 libjdumpertools.so
Then you can run any of the generated programs, for example JDU (a simpler version of the du command that prints the results in JSON format):
[josevnz@dmaf5 jdumpertools]$ LD_LIBRARY_PATH=$PWD $PWD/jdu /
[{"partition": "/", "free_space": 462140129280.000000, "total_space": 510405902336.000000}]
So far so good.
You will notice there is a file called jdumpertools.spec on this directory. This is the RPM specification file that controls how to compile and package jdumpertools using RPM.
But before we move into building our RPM lets install a few supporting tools.
You will need the following
sudo dnf install -y rpm-build rpmdevtools
Then we will prepare the sandbox to build your RPMS using our newly installed ‘rpmdevtools’. You will never use root for that but your personal or developer Linux account (we will pass the -d debug flag):
[josevnz@dmaf5 jdumpertools]$ /usr/bin/rpmdev-setuptree -d
josevnz /home/josevnz /home/josevnz/.rpmmacros
/home/josevnz/rpmbuild/RPMS /home/josevnz/rpmbuild/SOURCES /home/josevnz/rpmbuild/SPECS
/home/josevnz/rpmbuild/SRPMS /home/josevnz/rpmbuild/BUILD
# A nicer view:
[josevnz@dmaf5 jdumpertools]$ tree ~/rpmbuild
/home/josevnz/rpmbuild
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
5 directories, 0 files
Right now we only care about 2 directoties: SOURCES and SPECS. We will see the purpose of the rest in a bit.
Also a file called ~/.rpmmacros was created. You can put/ override some special macros there to avoid repetitive tasks while buidilding your RPMS. This file is important because it ‘anchors’ your rpmbuild environment with your home directory.
We first will create a tar file of our source code in the ~/rpmbuild/SOURCES directory:
VERSION=v0.1
NAME=jdumpertools
TARFILE=$(NAME)-$(VERSION).tar.gz
/usr/bin/tar --exclude-vcs --directory ../ --create --verbose --gzip --file $(HOME)/rpmbuild/SOURCES/$(TARFILE) $(NAME)
Normally the tar file contains scripts and source code we will compile as part of the packaging process.
Then we create a RPM spec file.
Again, rpmdevtools gives you a head start like following:
[josevnz@dmaf5 jdumpertools]$ rpmdev-newspec ~/rpmbuild/jose-package.spec
/home/josevnz/rpmbuild/jose-package.spec created; type minimal, rpm version >= 4.16.
[josevnz@dmaf5 jdumpertools]$ /bin/cat ~/rpmbuild/jose-package.spec
Name: jose-package
Version:
Release: 1%{?dist}
Summary:
License:
URL:
Source0:
BuildRequires:
Requires:
%description
%prep
%autosetup
%build
%configure
%make_build
%install
rm -rf $RPM_BUILD_ROOT
%make_install
%files
%license add-license-file-here
%doc add-docs-here
%changelog
* Sun Oct 03 2021 Jose Vicente Nunez <josevnz@kodegeek.com>
-
Don’t worry if you cannot make sense of this file now, let’s copy our jdumpertools.spec file to the ~/rpmbuild/SPECS directory:
cp -p -v jdumpertools.spec ~/rpmbuild/SPECS
And create both a source and binary RPM:
[josevnz@dmaf5 ~]$ rpmbuild -ba rpmbuild/SPECS/jdumpertools.spec
setting SOURCE_DATE_EPOCH=1609718400
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.kBlIwO
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd /home/josevnz/rpmbuild/BUILD
+ rm -rf jdumpertools
+ /usr/bin/gzip -dc /home/josevnz/rpmbuild/SOURCES/jdumpertools-v0.1.tar.gz
+ /usr/bin/tar -xof -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd jdumpertools
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.7qielL
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd jdumpertools
+ make all
make: Nothing to be done for 'all'.
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.F6BrgN
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ '[' /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64 '!=' / ']'
+ rm -rf /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
++ dirname /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
+ mkdir -p /home/josevnz/rpmbuild/BUILDROOT
+ mkdir /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
+ cd jdumpertools
+ rm -rf /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
+ /usr/bin/mkdir -p /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/bin
+ /usr/bin/cp -v -p jdu jutmp /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/bin
'jdu' -> '/home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/bin/jdu'
'jutmp' -> '/home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/bin/jutmp'
+ /usr/bin/mkdir -p /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/lib64
+ /usr/bin/cp -v -p libjdumpertools.so /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/lib64
'libjdumpertools.so' -> '/home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64//usr/lib64/libjdumpertools.so'
+ '[' '%{buildarch}' = noarch ']'
+ QA_CHECK_RPATHS=1
+ case "${QA_CHECK_RPATHS:-}" in
+ /usr/lib/rpm/check-rpaths
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip /usr/bin/strip
+ /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0
+ /usr/lib/rpm/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
Processing files: jdumpertools-v0.1-1.fc33.x86_64
Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.ToAGHO
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd jdumpertools
+ DOCDIR=/home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64/usr/share/doc/jdumpertools
+ export LC_ALL=C
+ LC_ALL=C
+ export DOCDIR
+ /usr/bin/mkdir -p /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64/usr/share/doc/jdumpertools
+ cp -pr README.md /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64/usr/share/doc/jdumpertools
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(%license): /bin/sh -e /var/tmp/rpm-tmp.swoM9N
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd jdumpertools
+ LICENSEDIR=/home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64/usr/share/licenses/jdumpertools
+ export LC_ALL=C
+ LC_ALL=C
+ export LICENSEDIR
+ /usr/bin/mkdir -p /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64/usr/share/licenses/jdumpertools
+ cp -pr LICENSE /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64/usr/share/licenses/jdumpertools
+ RPM_EC=0
++ jobs -p
+ exit 0
Provides: jdumpertools = v0.1-1.fc33 jdumpertools(x86-64) = v0.1-1.fc33 libjdumpertools.so()(64bit)
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libjdumpertools.so()(64bit) rtld(GNU_HASH)
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
Wrote: /home/josevnz/rpmbuild/SRPMS/jdumpertools-v0.1-1.fc33.src.rpm
Wrote: /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.1-1.fc33.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.uEyCyL
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd jdumpertools
+ rm -rf /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
+ RPM_EC=0
++ jobs -p
+ exit 0
The end result is 2 files, a source RPM and a binary RPM.
Wrote: /home/josevnz/rpmbuild/SRPMS/jdumpertools-v0.1-1.fc33.src.rpm
Wrote: /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.1-1.fc33.x86_64.rpm
So what happens when you install each one of these RPMS?
rpmbuild/SPECS: jdumpertools.spec
2. If you install the binary RPM then you are doing the real thing: Installing the application:
```shell=
[josevnz@dmaf5 ~]$ sudo rpm -ihv /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.1-1.fc33.x86_64.rpm
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:jdumpertools-v0.1-1.fc33 ################################# [100%]
Quickly let’s confirm installed RPMS is there:
[josevnz@dmaf5 ~]$ rpm -qi jdumpertools
Name : jdumpertools
Version : v0.1
Release : 1.fc33
Architecture: x86_64
Install Date: Sun 03 Oct 2021 06:32:50 PM EDT
Group : Unspecified
Size : 95002
License : Apache License 2.0
Signature : (none)
Source RPM : jdumpertools-v0.1-1.fc33.src.rpm
Build Date : Sun 03 Oct 2021 06:27:11 PM EDT
Build Host : dmaf5.home
URL : https://github.com/josevnz/jdumpertools
Summary : Programs that can be used to dump Linux usage data in JSON format.
Description :
Jdumpertools is a collection of programs that can be used to dump linux usage data in JSON format, so it can be ingested by other tools.
* jdu: Similar to UNIX 'du' command.
* jutmp: UTMP database dumper
Note: Curious readers probably opened the Makefile and saw a target called ‘rpm’:
rpm: all
test -x /usr/bin/rpmdev-setuptree && /usr/bin/rpmdev-setuptree|| /bin/mkdir -p -v ${HOME}/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
/usr/bin/tar --exclude-vcs --directory ../ --create --verbose --gzip --file $(HOME)/rpmbuild/SOURCES/$(TARFILE) $(NAME)
/usr/bin/rpmbuild -ba jdumpertools.spec
This is a convenient shorcut to prepare your rpmbuild sandbox, tar your files after they got compiled with make and then package them using ‘rpmbuild’ command. Freel free to call and see what it happens. (make rpm
)
I showed you first what commands and tools can be used to generate the RPM files but now is time to show you how to write the RPM spec file…
Working with spec files requires filling several metatada tags as well describing how you are going to compile/ package your application. Jdumpertools is a plain Ansi C application, so we unpack the sources, compile them, copy them into intermediate area (~/rpmbuild/BUILDROOT) and then package them for distribution.
Let’s take a look at the RPM spec file:
Name: jdumpertools
# TODO: Figure out a better way to update version here and on Makefile
Version: v0.1
Release: 1%{?dist}
Summary: Programs that can be used to dump Linux usage data in JSON format.
License: Apache License 2.0
URL: https://github.com/josevnz/jdumpertools
Source0: %{name}-%{version}.tar.gz
BuildRequires: bash,tar,gzip,rpmdevtools,rpmlint,make,gcc >= 10.2.1
Requires: bash
%global debug_package %{nil}
%description
Jdumpertools is a collection of programs that can be used to dump linux usage data in JSON format, so it can be ingested by other tools.
* jdu: Similar to UNIX 'du' command.
* jutmp: UTMP database dumper
%prep
%setup -q -n jdumpertools
%build
make all
%install
rm -rf %{buildroot}
/usr/bin/mkdir -p %{buildroot}/%{_bindir}
/usr/bin/cp -v -p jdu jutmp %{buildroot}/%{_bindir}
/usr/bin/mkdir -p %{buildroot}/%{_libdir}
/usr/bin/cp -v -p libjdumpertools.so %{buildroot}/%{_libdir}
%clean
rm -rf %{buildroot}
%files
%{_bindir}/jdu
%{_bindir}/jutmp
%{_libdir}/libjdumpertools.so
%license LICENSE
%doc README.md
%changelog
* Mon Jan 4 2021 Jose Vicente Nunez <kodegeek.com@protonmail.com> - 0.1
- First version being packaged
So what is important here:
Also important:
%global debug_package %{nil}
It is always nice to check for obvious errors or ways to improve our RPMS:
josevnz@dmaf5 jdumpertools]$ sudo dnf install -y rpmlint
So now let’s check the RPM spec file:
[josevnz@dmaf5 jdumpertools]$ rpmlint /home/josevnz/rpmbuild/SPECS/jdumpertools.spec
/home/josevnz/rpmbuild/SPECS/jdumpertools.spec: W: invalid-url Source0: jdumpertools-v0.1.tar.gz
0 packages and 1 specfiles checked; 0 errors, 1 warnings.
The rpmlint documentation says than the Source0 must be a well define URL (The value should be a valid, public HTTP, HTTPS, or FTP URL.). So will not worry about this warning:
What about the RPM itself?
[josevnz@dmaf5 jdumpertools]$ make rpm
...
[josevnz@dmaf5 jdumpertools]$ rpmlint --info ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
jdumpertools.x86_64: W: summary-ended-with-dot C Programs that can be used to dump Linux usage data in JSON format.
jdumpertools.x86_64: W: spelling-error %description -l en_US du -> dew, doe, Du
jdumpertools.x86_64: E: description-line-too-long C Jdumpertools is a collection of programs that can be used to dump linux usage data in JSON format, so it can be ingested by other tools.
jdumpertools.x86_64: W: incoherent-version-in-changelog 0.1 ['v0.1-1.fc33', 'v0.1-1']
jdumpertools.x86_64: W: invalid-license Apache License 2.0
jdumpertools.x86_64: W: unstripped-binary-or-object /usr/bin/jdu
jdumpertools.x86_64: W: unstripped-binary-or-object /usr/bin/jutmp
jdumpertools.x86_64: W: unstripped-binary-or-object /usr/lib64/libjdumpertools.so
jdumpertools.x86_64: W: no-soname /usr/lib64/libjdumpertools.so
jdumpertools.x86_64: W: no-manual-page-for-binary jdu
jdumpertools.x86_64: W: no-manual-page-for-binary jutmp
1 packages and 0 specfiles checked; 1 errors, 10 warnings.
10 warnings and one error. Some are easy to fix:
After the fixes only 1 warning remains:
[josevnz@dmaf5 jdumpertools]$ make rpm
...
[josevnz@dmaf5 jdumpertools]$ rpmlint --info ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
jdumpertools.x86_64: W: spelling-error %description -l en_US du -> dew, doe, Du
The value of this tag appears to be misspelled. Please double-check.
We can ignore that one too.
Now we can upgrade our RPM with the improved version:
sudo rpm -Uhv ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
Another very common scenario is the following: You found a piece of sfotware you want to use but there is no RPM for it.
For this example, I’m going to use a Java benchmark I like from NASA: NAS Parallel Benchmarks (NPB3.0). I took their code and made a fork, adding only an improved build using Gradle.
[josevnz@dmaf5 NPB3.0-JAV-FORK]$ /usr/bin/rpmdev-newspec --output ~/rpmbuild/SPECS/NPB.spec --type minimal
/home/josevnz/rpmbuild/SPECS/npb.spec created; type minimal, rpm version >= 4.16.
The resulting file looks like this:
Name: npb
Version:
Release: 1%{?dist}
Summary:
License:
URL:
Source0:
BuildRequires:
Requires:
%description
%prep
%autosetup
%build
%configure
%make_build
%install
rm -rf $RPM_BUILD_ROOT
%make_install
%files
%license add-license-file-here
%doc add-docs-here
%changelog
* Tue Oct 05 2021 Jose Vicente Nunez <kodegeek.com@protonmail.com>
-
Will remove the following tags from this skeleton file as they are not applicable to our task:
And will add a few other commands.
Finally let’s install the pre-requisites (Java and Gradle itself):
sudo dnf install -y java-11-openjdk
sudo -i /bin/mkdir -p /opt/gradle
sudo -i /bin/curl --silent --location --fail --output /opt/gradle/gradle.zip https://services.gradle.org/distributions/gradle-7.2-bin.zip
cd /opt/gradle && sudo /usr/bin/unzip gradle.zip && sudo /bin/rm -f /opt/gradle/gradle.zip
Now we are ready to change the SPEC file
After several changes, like adding Gradle as part of the build we have the following:
Name: NPB
Version: 3.0
Release: 1%{?dist}
Summary: Small set of programs designed to help evaluate the performance of parallel supercomputers
License: NOSA
URL: https://www.nas.nasa.gov/software/npb.html
Source0: https://www.nas.nasa.gov/assets/npb/%{name}%{version}.tar.gz
BuildRequires: java-11-openjdk-headless,tar,gzip,rpmdevtools,rpmlint
Requires: java-11-openjdk-headless
# Custom macros (https://rpm-software-management.github.io/rpm/manual/macros.html)
# If you want to see the value of many of these macros, just run this: /usr/bin/rpm --showrc
%global debug_package %{nil}
%global gradle /opt/gradle/gradle-7.2/bin/gradle
%global curl /bin/curl --location --fail --silent --output
%global JAVA_DIR NPB3_0_JAV
%description
The NAS Parallel Benchmarks (NPB) are a small set of programs designed to help evaluate the performance
of parallel supercomputers. The benchmarks are derived from computational fluid dynamics (CFD)
applications and consist of five kernels and three pseudo-applications in the original "pencil-and-paper"
specification (NPB 1). The benchmark suite has been extended to include new benchmarks for unstructured
adaptive meshes, parallel I/O, multi-zone applications, and computational grids. Problem sizes in NPB are
predefined and indicated as different classes. Reference implementations of NPB are available in
commonly-used programming models like MPI and OpenMP (NPB 2 and NPB 3).
%prep
test ! -x %{gradle} && echo "ERROR: Gradle not installed!" && exit 100
# On a production environment you MOST LIKELY point to your private copy of the build artifacts
/bin/curl --location --fail --silent --output %{_sourcedir}/%{name}%{version}.tar.gz https://www.nas.nasa.gov/assets/npb/%{name}%{version}.tar.gz
%setup -q -n %{name}%{version}
%build
cd %{name}%{version}-JAV
# If you are not familiar with Gradle, you should read the following:
# https://docs.gradle.org/current/userguide/building_java_projects.html#sec:custom_java_source_set_paths
/bin/cat<<GRADLE>build.gradle.kts
// Gradle build file dynamically created for %{name}%{version}
plugins {
\`java-library\`
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
sourceSets {
main {
java {
setSrcDirs(listOf("%{JAVA_DIR}"))
}
}
test {
java {
setSrcDirs(listOf("test"))
}
}
}
GRADLE
%{gradle} clean java jar
%install
/bin/rm -rf %{buildroot}
/bin/mkdir -v -p %{buildroot}/%{_bindir}
/bin/mkdir -v -p %{buildroot}/%{_libdir}
/bin/mkdir -v -p %{buildroot}/%{_pkgdocdir}
/bin/cp -p -v %{_builddir}/%{name}%{version}/%{name}%{version}-JAV/build/libs/%{name}%{version}-JAV.jar %{buildroot}/%{_libdir}
# On a production environment you MOST LIKELY point to your private copy of the build artifacts
%{curl} %{buildroot}/%{_pkgdocdir}/LICENSE https://raw.githubusercontent.com/josevnz/%{name}%{version}-JAV-FORK/main/LICENSE
%{curl} %{buildroot}/%{_pkgdocdir}/README.md https://github.com/josevnz/%{name}%{version}-JAV-FORK/blob/main/%{name}%{version}-JAV/README.md
%{curl} %{buildroot}/%{_bindir}/testAllS https://raw.githubusercontent.com/josevnz/tutorials/main/testAllS
%{curl} %{buildroot}/%{_bindir}/testAllW https://raw.githubusercontent.com/josevnz/tutorials/main/testAllW
/bin/chmod a+xr %{buildroot}/%{_bindir}/{testAllS,testAllW}
%clean
/bin/rm -rf %{buildroot}
%files
%license %{_pkgdocdir}/LICENSE
%doc %{_pkgdocdir}/README.md
%{_libdir}/%{name}%{version}-JAV.jar
%{_bindir}/testAllS
%{_bindir}/testAllW
%changelog
* Tue Oct 05 2021 Jose Vicente Nunez <kodegeek.com@protonmail.com>
- First RPM
The SPEC file is heavily commented and you can see how I used the original tar.gz file without any changes and added a new build system on top of that, plus two (1, 2) wrapper scripts to run the Java code after is installed.
Let’s create the new RPM:
[josevnz@dmaf5 ~]$ rpmbuild -ba ~/rpmbuild/SPECS/npb.spec
Requires: /usr/bin/bash
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/josevnz/rpmbuild/BUILDROOT/NPB-3.0-1.fc33.x86_64
Wrote: /home/josevnz/rpmbuild/SRPMS/NPB-3.0-1.fc33.src.rpm
Wrote: /home/josevnz/rpmbuild/RPMS/x86_64/NPB-3.0-1.fc33.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.JGJ4Ky
Then install it:
[josevnz@dmaf5 ~]$ sudo rpm -ihv /home/josevnz/rpmbuild/RPMS/x86_64/NPB-3.0-1.fc33.x86_64.rpm
[sudo] password for josevnz:
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:NPB-3.0-1.fc33 ################################# [100%]
/usr/bin/testAllS
+ /usr/lib/jvm/java-11-openjdk-11.0.12.0.7-4.fc33.x86_64/bin/java -classpath /home/josevnz/rpmbuild/BUILD/NPB3.0/NPB3.0-JAV/build/libs/NPB3.0-JAV.jar NPB3_0_JAV.BT -np2 CLASS=S
NAS Parallel Benchmarks Java version (NPB3_0_JAV)
Multithreaded Version BT.S np=2
No input file inputbt.data, Using compiled defaults
Size: 12 X 12 X 12
Iterations: 60 dt: 0.01
Time step 1
Time step 20
Time step 40
Time step 60
Verification being performed for class S
accuracy setting for epsilon = 1.0000000000000005E-8
Comparison of RMS-norms of residual
0. 0.1703428370954122 0.17034283709541312 5.377003288977261E-15
1. 0.012975252070034126 0.012975252070034096 2.2728112665889987E-15
2. 0.032527926989483404 0.032527926989486054 8.148866886442929E-14
3. 0.026436421275142053 0.0264364212751668 9.361163090380881E-13
4. 0.1921178413174506 0.1921178413174443 3.279505756228626E-14
Comparison of RMS-norms of solution error
0. 4.997691334580433E-4 4.997691334581158E-4 1.4513326350787734E-13
1. 4.519566678297316E-5 4.519566678296193E-5 2.484368424681786E-13
2. 7.397376517295259E-5 7.397376517292135E-5 4.222926198459033E-13
3. 7.382123863238472E-5 7.382123863243973E-5 7.451745425239995E-13
4. 8.926963098749218E-4 8.926963098749145E-4 8.258771422427503E-15
BT.S: Verification Successful
Packaging software with RPM looks intimidating at first, but with a little bit of pacience you will get there in no time. As you encounter issue you will also find proper ways to improve your code. Below are some resources and final recommendations: