Build an RPM Package for Installation and Management by the System Package Manager

Published: Feb. 23, 2016, midnight

Updated: None

Many Linux users install software from source using the steps ./configure, make, make install. This method is easy but unattractive because it bypasses the system's package management tools, and any software installed using this method doesn't allow for the management of the software with the package manager. A method almost as simple that allows the package manager to track the installation is to use the rpmbuild tool to create an rpm package and install the package directly using zypper, the command line package management tool, or add it to a local repository and install it using whatever method the user normally chooses to install from remote repositories. This article gives an example of this process by packaging the xwinwrap program.

Introduction

One of the many attractive features of openSUSE is its very powerful and robust software management infrastructure. This includes the ability to easily create local repositories, add community repositories, the YaST One Click tool to install software and add the repositories that host the software, build and host packages on the openSUSE Build Service, -- even for other distributions -- and build RPM packages locally. This article shows how use this last feature to build the xwinwrap program which allows the display of screensavers, videos, and animated GIFS (when used with other programs) as desktop backgrounds.

The tool that is used to build an RPM package is rpmbuild. It is available in all of the distributions that use RPM package management like Fedora, Mageia, and others. Note that the RPM was forked recently so some distributions, like openMadriva, and ROSA use the newer fork, that is less common.

xwinwrap

Before describing the process of building xwinwrap, I'll introdce this program. xwinwrap was originally written by David Reveman of Novell and was last released in this form in 2005. It was then modified by Shantanu Goel, first in 2008, to fix, apparently, major issues, and add options, then in 2009, to fix bugs and add even more options.

This modified version is the basis of many packages in various distributions and scripts that call helper programs as arguments to xwinwrap. It's name incorporates "shantz" into the name of the package instead of simply "xwinwrap".

I tried it in the OpenBox version of Manjaro to display an animated GIF on the desktop (which worked without issues, probably due to the fact that OpenBox does not have a native component for controlling the desktop). However, on openSUSE, the the latest available package of xwinwrap is for 12.3 on an openSUSE Build Service repository, which is bundled with a script for using xwinwrap with MPlayer to provide a video background. I decided to create a package that removes the script, because it might be better to build seperate add on packages for scripts that interact with xwinwrap, and to package it so that the package neme reflects the modified version. (After this, I will make add on packages to xwinwrap for the script I unbundled and for the script I used to make provide the animated GIF background. Look for more pages on this site in the near future on how to use xwinwrap with the helper programs, MPlayer and gifview, as well as some example scripts.)

Default rpmbuild Use Overview

The required tool to build packages locally is rpmbuild which, in openSUSE is part of the package rpm-build, available from the main repository. Install this and its three dependencies, which get pulled in automatically, with

zypper install rpm-build
. You probably should also have other common developement tools like gcc and make already installed on the system, if not you will be informed to install them and whatever else is necessary in a particular case by rpmbuild. When installing rpmbuild the default build directories will be created in your home directory. After installing the required package, as indicated above, you will have in your /home/username directory, a folder named rpmbuild. This will in turn have the following directories:

  • BUILD
  • BUILDROOT
  • SOURCES
  • SPECS
  • RPMS
  • SRPMS

Note that not all of the documentation you may find on rpmbuild will mention BUILDROOT, but apparently, the version of rpmbuild found on openSUSE 13.2 will create this directory also.

It is possible to use a different folder heirarchy for rpmbuild's use but using the default setup will keep things simple, especially when considering the purpose of these directories and the rpmbuild macros they are associated with. The source files or tarball should be placed in the SOURCES directory and the .spec file, described below should be placed in the SPECS directory.

rpmbuild takes as an argument a .spec file, which is in essence a bash script that takes the place of the series of commands ./configure, make, and make install, controlling the compilation of source, if necessary, and providing instructions for the build process and the writing of files when the RPM is installed on the target system. It also sets the metadata of the package. It is executed, generally, as

rpmbuild -bb name-of-package.spec

In addition to the concepts associated with rpmbuild, of the build directory structure and the specfile, are the macros in the specfile that expand into shell script commands and the aliases for various directories and filenames. The macros begin with % and aliases are enclosed in braces, such as %{buildroot} when being defined and{buildroot}when being invoked. Certain macros in the specfile define the stages of the build; these are the %prep, %build, %install, and %files (writing of files during installation) steps. The process will go through these steps reading and writing to the build directories defined for rpmbuild through the use of the aliases. By default these aliases will map to the directories in ~/rpmbuild. When the default values of the aliases are used as defined internally by rpmbuild without modification, they do not need to be specified in the specfile.

  1. The %prep step will read the sources or tarballs from the SOURCES directory, defined by {_sourcedir} and write the extracted files to the BUILD directory {_builddir}
  2. The %build step will read the extracted source files from the BUILD directory, compile the sources and write intermediate results to the same directory
  3. The %install step will read from the BUILD directory and write the files to be installed in the target system to the BUILDROOT directory, defined by {_buildrootdir}. After this step BUILDROOT will contain the files that will be installed on the target system grouped into folders for each architecture for which the package is being built.
  4. The %files will create the package specifying all of the actual files being written in the target installation, including the ancilliary files such as configuration files and documentation files.

The.specFile

The spec file I used for building shantz-xwinwrap is presented in the following code block.


#
# spec file for package xwinwrap
#
# Copyright (c) 2012 Malcolm J Lewis <malcolmlewis@opensuse.org>
# Copyright (c) 2014 <brook@ordinatechnic.com>
# Modified from openSUSE version for personal use.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via http://bugs.opensuse.org/
#


#%define _bindir /usr/bin
Name:           shantz-xwinwrap
Version:        090215
Release:        1.0
License:        GPL-2.0
Summary:        Animated desktop background
Url:            https://launchpad.net/xwinwrap
Group:          System/GUI/Other
Source0:        shantz-xwinwrap-090215.tgz
#Source0:		http://bazaar.launchpad.net/~shantanu-goel/xwinwrap/devel/files/
BuildRequires:  gcc-c++
BuildRequires:  xorg-x11-devel

%description
Desktop utility, written by David Reveman/Novell, that will make
cool things happen on your desktop. You can run your screensavers, play
movies, animated GIFs, etc. and it will look as if they are part of your
background.

Modified by: Shantanu Goel
Tech Blog: http://tech.shantanugoel.com
Blog: http://blog.shantanugoel.com

%prep
%setup

%build
export SUSE_ASNEEDED=0
%ifarch x86_64
/usr/bin/gcc -fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
\
             -funwind-tables -fasynchronous-unwind-tables -Wstrict-prototypes \
             -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls \
             -lX11 -lXext -lXrender xwinwrap.c -o xwinwrap
%endif

%ifarch %ix86
/usr/bin/gcc -m32 -fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2
-fstack-protector \
             -funwind-tables -fasynchronous-unwind-tables -Wstrict-prototypes \
             -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls \
             -lX11 -lXext -lXrender xwinwrap.c -o xwinwrap
%endif

%install
mkdir -p %{buildroot}%{_bindir}
install -m 0755 xwinwrap %{buildroot}%{_bindir}

%files
%defattr(-, root, root)
%doc README LICENSE AUTHORS
%{_bindir}/*

%changelog
* Fri Dec 26 2014 brook@ordinatechnic.com
- Using/modifying xwinwrap.spec from
https://build.opensuse.org/package/show/home:malcolmlewis:Miscellanous/shantz-xw
inwrap and
http://rpm.pbone.net/index.php3/stat/26/dist/81/size/10156/name/xwinwrap-090215-
3.1.src.rpm
- Removed coolbg script from package as it may be too outdated to be reliable.
May include it and an animated GIF script as add ons in the future.
- Changed release number to 1.0 from 0 in first original spec/3.1 in second
original spec.
- Updated project URL to https://launchpad.net/xwinwrap from
http://tech.shantanugoel.com/projects/linux/shantz-xwinwrap.
- Renamed source tarball to shantz-xwinwrap-devel-r4-1.0.tgz to match project
name on launchpad.
* Wed Jan 18 2012 malcolmlewis@opensuse.org
- Spec file clean up.
- Add optflags to build.
* Fri Mar  5 2010 coyoteuser@gmail.com
- Initial build of shantz-xwinwrap version

For details on the construction of a specfile, see the references listed in the References section, but the the relevant details for this specific specfle are as follows:

Name, Version, and Release
These parameters are important in that they ultimately determine the name of the rpm package. It will be named using these parameters asName-Version-Release-Architecture.rpm. They also determine the naming of intermediate files and directories created by rpmbuild
Source0
This parameter specifies the name of the source tarball in the SOURCE directory. This could also be a full URL. There could also be multiple sources each one with a different number X, in SourceX
%prep
The %prep section does not have any additional script besides the default %prep macro. This by itself will, by default, just extract the source tgz archive and extract it into the BUILD directory.
%setup
%build
The %buld section has commands to actually compile the source and build the executable. In this case this is done by calling gcc with options as found in the original shantz-xwinwrap developer. The author of the original specfile also, apparently added some optimization or customization for openSUSE in the export SUSE_ASNEEDED. The build is executed conditionally by the architecture of the computer on which the rpmbuild is run.
%install
The %install section writes the files that will be created when the package is installed. First the necessary directory is created in the BUILDROOT directory. In this case, because the default values for the parameters are used:
  • %buildroot = ~/rpmbuild/BUILDROO
  • {%_bindir} = /usr/bin
mkdir -p %{buildroot}%{_bindir}
expands to
mkdir -p ~/rpmbuild/BUILDROOT/usr/bin
The next line writes the executable created by rpmbuild, xwinwrap -- named so because the actual c source file is named xwinwrap, wheras the package is named shantz-xwinwrap -- into ~/rpmbuild/BUILDROOT/usr/bin
%files
The line %defattr(-, root, root) sets the permissions of the files created for installation by rpmbuild. %doc README LICENSE AUTHORS, will write these files in the appropriate locations during installation of the rpm. %{_bindir}/* will write the other files created by rpmbuild to their appropriate locations during installation, in this case the application xwinwrap will be written to/usr/binwhen the rpm is installed.

References

Fedora wiki page on how to build an RPM
This is a very detailed yet compact reference on using rpmbuild, but be careful of Fedora specific information.
Mageia wiki page for packagers
This is an almost as detailed yet compact reference on RPM packages and rpmbuild, but be careful of Mageia specific information.
IBM developerWorks tutorial on building RPM packages
This is very concise tutorial on using rpmbuild, but be careful of information that is not compatible with openSUSE default setup of rpmbuild

Conclusion

The RPM package format, with its very straightforward .spec file, and the rpmbuild allows users of distributions that use it to easily create packages of software unavailable in the distributions' official and unofficial repositories. One .spec file specifies the entire package build and incorporates package metadata, unlike the .deb format which has many more component files and a more complicated process. It also allows users to avoid the ./configure, make, make install process which, while maybe easier, doesn't allow the system package manager to manage software installed in this way.