RPM Notes - Building RPMs the easy way

Building RPMs

hello.sh:
#!/bin/bash
 
echo "Hello, world!"
hello.spec:
%define _build_arch noarch

Summary: This prints hello world
Name: hello
Version:1.0
Release:1
Group: system
License: GPL
AutoReqProv: no

BuildArch: %{_build_arch}
BuildRoot: %{_builddir}/%{name}

%description
This package prints hello world when executed
 
%prep
rm -rfv %{buildroot} %{_rpmdir}/*
mkdir -vp %{buildroot}/usr/local/bin
 
%install
cp -fv $OLDPWD/hello.sh %{buildroot}/usr/local/bin/
 
%files
%defattr(755, -, -, 755) 
/usr/local/bin/hello.sh
 
%clean
cp -vf %{_rpmdir}/%{_build_arch}/%{name}-%{version}-%{release}.%{_build_arch}.rpm $OLDPWD/
rm -vfr %{buildroot} %{_rpmdir}/*

To build the RPM package:
$ rpmbuild -bb hello.spec

This will take your hello.sh from your current folder and builds a hello*.rpm and leaves the RPM package in the current folder.
You can then install the package.
$ sudo rpm -ivh hello-1.0-1.i386.rpm
This puts the payload script into /usr/local/bin/ as defined in the hello.spec file.

Explanation:

The 6 sections do this:
  1. Variables at the top: set up some variables used in the build.
  2. Header (next section under variables): Describes the package to RPM.
    NOTE: This has the location of the package build area in BuildRoot and the target architecture BuildArch.
  3. %description: Describes the package to humans.
    NOTE: Make sure the description starts on the next line to "%description" also there is no colon (:).
  4. %prep: prepares the build area for a package.
    NOTE: This is not to prepare the OS for an install.
    In this case it clears the build area and creates the temporary target folder.
  5. %install: executes stuff to create the package files in the build area.
    NOTE: This is not to install the package to the OS.
    In this case it copies the file to the relative location for install.
  6. %files: the list of files which are to be copied during the package install.
    NOTE: This should not list any files which you are going to create as part of the package installation process.
    Path to the file location and attributes for that file.
  7. %clean: commands to be run to clean up the package creation area.
    Here I use this to copy the package.rpm file to the folder from which you ran the build then clear the build area.

If you wish to execute extra steps to create files and folders when the package is installed these go in the %post: section
See the reference below for the complete list of tags.

If that doesn't work

If that errors here is an alternate hello.spec:
Summary: This prints hello world
Name: hello
Version:1.0
Release:1
Group: system
License: GPL
AutoReqProv: no
 
%description
This package prints hello world when executed
 
%prep
 
%install
cp -fv $OLDPWD/hello.sh /tmp/
 
%files
%defattr(755, -, -, 755) 
/tmp/hello.sh
 
%clean
cp -vf %{_rpmdir}/%{_arch}/%{name}-%{version}-%{release}.%{_arch}.rpm $OLDPWD/
rm -vf /tmp/hello.sh

%post
mv /tmp/hello.sh /usr/local/bin/

%preun
mv /usr/local/bin/hello.sh /tmp/

%postun
rm -f /tmp/hello.sh
This one fakes an install into /tmp/ then moves the file to the real location.
The reason for this is that RPM may require the files to be in the actual location when building the RPM.
This way we "pretend" to RPM that the actual location is /tmp/.

So why do this anyway?
Well to just build the RPM we might not want the files installed into the OS.
So now it doesn't.

Links:

RPM Building Notes | RPM HOWTO (TLDP)
Packaging software with RPM (IBM) | RPM.org
Maximum RPM | RPM Building Crash Course
how to build a noarch RPM

Spec File Reference

Tags

Scripts

Macros

File-related Directives

Conditionals