Recently, I wrote about packaging your own software with Red Hat Package Manager (RPM). Another common scenario is that you find a piece of software you want to use, but there is no RPM for it. This article shows you how to create RPMs for third-party applications.
Prerequisites include:
- You have basic knowledge of how to use RPM to query packages and install or delete packages. If not, get familiar with these concepts first and then come back here for some fun.
- You have Make, Git, GCC, and Java installed, as you'll need them to complete the exercises included here. It's not required, but it would be nice if you practice as I move along.
To install Make, GCC, Java 11, and Git using the DNF package manager, run:
$ sudo dnf install \
make git gcc-10 \
java-11-openjdk-headless
For this example, I'll use a Java benchmark I like from NASA: NAS Parallel Benchmarks (NPB3.0). I took this code and made a fork, adding only an improved build using Gradle. Here are the steps.
Step 1: Write a skeleton spec file
$ 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>
-
Next, remove the following tags from this skeleton file, as they do not apply to this task:
- %autosetup: You will unpack the software yourself without patches
- %configure and %make_build: You will use Gradle instead
Install the prerequisites, Java and Gradle:
$ sudo dnf install java-11-openjdk
$ sudo -i mkdir -p /opt/gradle
$ sudo -i curl --silent --location --fail \
--output /opt/gradle/gradle.zip \
https://services.gradle.org/distributions/gradle-7.2-bin.zip
$ cd /opt/gradle
$ sudo unzip gradle.zip
$ sudo /bin/rm -f /opt/gradle/gradle.zip
Now you are ready to change the spec
file.
[ Get more tips by downloading the Bash shell scripting cheat sheet. ]
Step 2: Fill in the building blocks for the Java RPM
After several changes, like adding Gradle as part of the build, you have:
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 wrapper scripts (testAIIS and testAIIW) to run the Java code after it is installed.
Next, create the new RPM:
$ 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
Step 3: Install your custom RPM
With your RPM built, you can now install it:
$ sudo rpm -ihv ~/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%]
The output indicates success:
/usr/bin/testAllS
+ /usr/lib/jvm/java-11-openjdk-11.0.12.0.7-4.fc33.x86_64/bin/java -classpath
[...]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
[...]
BT.S: Verification Successful
Learn more
Packaging software with RPM—whether it's your own or someone else's open source application—may look intimidating at first, but with a little bit of patience, you will get there in no time. As you encounter issues, you will also find proper ways to improve your code. Below are some resources and final recommendations:
- Do yourself a big favor and get a copy of the RPM Packaging Guide written by Adam Miller, Maxim Svistunov, and Marie Doleželová. It is very complete and well organized. Seriously, do it now; it is that good.
- The official RPM Packaging Guide and the Fedora RPM guide are also full of details; keep them a bookmark away.
- Use rpmlint. You will be surprised how many little things you can catch and fix before shipping your RPM packages.
- Not enough? Fedora has a list of tricks you can use when packaging software.
- Thirsty for more? You should definitely take a look at RPM Packaging guidelines.
저자 소개
Proud dad and husband, software developer and sysadmin. Recreational runner and geek.
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.