Linux RPM
How to make good RPM packages - too technical for beginner

rpm -Uvh$(rpm -E %fedora).noarch.rpm
rpm -Uvh$(rpm -E %fedora).noarch.rpm

yum install broadcom-wl
yum -y install broadcom-wlz
/sbin/lsmod | grep b43

How to determine which package contains a file?

rpm -qf /path/to/file

How to list files that are part of an RPM?

rpm -ql packageName // the lowercase letter L
rpm -ql java-1.6.0-openjdk-

How to search for matching installed RPMs?

rpm -qa | grep java

How to install a package?

rpm -ivh filename.rpm
// i for install, v for verbose, and h to process hash

How to remove a package?

rpm -e packageName
// e for erase

How to uninstall RPM packages with the same version?

Sometimes, by mistake, we install two versions of the same RPM, one for 32-bit and one for 64-bit. To uninstall these packages:

rpm -e --allmatches package_name

After you install a source RPM package, does it go into the RPM database?

No. SRPMs do not go into the RPM database. Source packages just install the source into the defined source directory. For RedHat, the default source directory: /usr/src/redhat/SOURCES

How to remove installed SRPM with spec file name?

rpmbuild --resource --rmspec goldfish.spec

How to make a binary rpm from SRPM?

rpmbuild --rebuild goldfish-1.0.0-1.src.rpm

How to make a binary rpm from the spec file?

rpmbuild -ba goldfish.spec
// -b for build, -a for all packages (src and bin)

How to make a patched source tree from spec file?

rpmbuild -bp goldfish.spec
// -b for build, -p for patch only

What is the patched source tree and why should we use a patch source tree?

Not sure.

Where is the patched source tree?

For RedHat, the default is /usr/src/redhat/BUILD

How to rebuild for a different architecture?

rpmbuild --target spark --rebuild goldfish-1.0.0-1.src.rpm

Be careful. Many software programs detect the system type in configure and ignore what rpm told it.

What is RPM Macro?

Just like variable in shell scripting. They can act as integers or strings, but it is easier to always treat them as string. Many common macros come predefined.

How to show all the pre-defined macros?

rpm --showrc

How to show you what a specific macro evaluate to?

rpm --eval %{macroname}

What are the two macro formats?

%{foo} vs $foo

They are the same macro, but for your sanity, you should consistently use one type of macro in a spec file. It is recommended that we use %{foo}.

What is the meaning of %{?foo} ?

If foo is defined, use it, otherwise it does not get used.

How to make an rpm build tree in your home directory?

mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
mkdir -p ~/rpmbuild/RPMS/{noarch,i386,i686}

How to make an ~/.rpmmacros file?

%_topdir    %(echo $HOME)/rpmbuild

You can make your own macros here, but be careful. Custom macros will almost certainly not be on the system where you install your built packages. Accordingly, don’t use them in %pre/%post

Other useful items for your ~/.rpmmacros:

%_smp_mflags -j3

If your package SPEC has “make %{?_smp_mflags}, then this will tell it to try to build across three CPUs.

Why three? Three is a nice odd number that isn’t too harsh for uniprocessor systems but enough to expose code that doesn’t build well in SMP environments.

What is the purpose of the spec file?

The spec file is a recipe. It lists the contents of the RPMS. It describes the process to build, install the sources. It is required to make packages. It is very similar to a shell script. It contains the following stages:

  • Preamble
  • Setup
  • Build
  • Install
  • Clean
  • Files
  • Changelog

What is the purpose of the Preamble section of the spec file?

Initial section
Defines package characteristics
Release track build changes
Build & Install
Summary / Description
Custom macro definitions

How to build binary bits in the sourced (no binary rpm)?

rpmbuild -bc helloworld.spec 
-b for build, -c for compile and stop

Best practices:

  • Do not ever build RPMS as root.
  • K.I.S.S
  • Use patches, not rpm hacks
  • Avoid scriptlets. Minimize pre/post wherever possible.
  • Use Changelog
  • Look to Fedora packages
  • Use macros sanely
    • Be consistent
    • Utilize system macros
  • Use rpmlint and fix warnings and errors
  • Include configs / scripts as source files
  • Comments
    • Keep it legible
    • Think of the guy who will have to fix your package when you leave
  • Don’t ever call rpm from inside a spec file.

Building your own RPM package:

What are the basic steps to build your own RPM package?

  1. Never build RPM as root. Create a separate account just for building RPMs so that your normal account is protected if something went wrong with the build process. I created an "rpmbuild" account and use it for just this purpose. This might seem a bit tedious, but it is a lot safer. Below, when I refer to ~/ I am assuming you are logged into the "rpmbuild" account.
  2. Create the required directory structure
  3. Create the ~/.rpmmacros file
  4. Modifying the install routines
  5. Write the spec file
  6. Building the RPM
  7. Sign your RPM

How to create the required directory structure?

mkdir ~/rpm ~/rpm/BUILD ~/rpm/RPMS ~/rpm/RPMS/i386 ~/rpm/RPMS/i686 ~/rpm/RPMS/noarch ~/rpm/SOURCES ~/rpm/SPECS ~/rpm/SRPMS ~/rpm/tmp

You might have to add more directories if your system architecture is different from i386 or i686.

How to create the ~/.rpmmacros?

This is just a text file. It should contains at least the following lines:

%_topdir               /home/rpmbuild/rpm
%_tmppath              /home/rpmbuild/rpm/tmp

This file lets rpm-build know that you want to build locally by telling it to look for and create files in subdirectories of /home/rpmbuild/rpm. There are many other things that could be added to this file, but this is a start.

How to modify the install routines?

If the tar ball contains the typical configure, make, make install steps, building the RPM package is easy. See below. If the code that you are trying to build contains complex installation procedure, we may have some work to do.

Next you might need to modify the process by which the software normally builds and installs (ie. from a tarball or from CVS, without RPM). Basically, you want to modify your Makefile or install script so that, when rpm-build is building your software, it knows to place the files in a subdirectory of the build root (ie. that temporary directory where the files will be placed). If the Makefile or automake file is well written, you might not need to modify anything at all as rpmbuild relies on many standard names. If the Makefile is poorly written, but the package installs relatively few files, it is sometimes easiest to simply install the files manually from inside the spec file into the appropriate directories for rpmbuild.


How to write the spec file?

See below and

How to build the RPM?

cp myspec.spec ~/rpm/SPECS/
tar -zcvf ~/rpm/SOURCES/mypackagename-myversionnumber.tar.gz mypackagename-myversionnumber
rpmbuild -ba ~/rpm/SPECS/myspec.spec

Notice that your source files should be in a directory with the appropriate name and version number before tar'ing.

How to sign your RPM?

Recently, I have begun to submit RPMs to the Fedora project. They require all submissions to be digitally signed for security.

First you will want to do all signing in your normal user account or in a special signing account, but NOT the build account. This is for security reasons.

As your normal user, you generate a secret key with:

gpg --gen-key

This will ask you some questions regarding the name of the key you are generating, often called the USERID, UID or KEYID. Then you will enter a password. This will generate a key and it will be stored in some keyring somewhere.

gpg --list-sigs

will produce a list of your signatures.

Now you need to generate a public key to give to other people and publish it so Fedora users can get the key.

$ gpg --armor --export "USERID" > my.key.file.asc
$ gpg --keyserver --send-key "USERID"

The public key should be spread around as much as possible. It is used by others to verify that you signed your packages. It can also be used to send encrypted messages to you (which you open with the private companion to the public key).

Now create a ~/.rpmmacros file in the account you will use for signing. Place the following lines in the file:

%_signature gpg
%_gpg_name USERID
%_gpgbin /usr/bin/gpg

Now you can sign packages at will with:

rpm --addsign name_of_rpm_package

The complete process of setting up a build environment and building an RPM package from a tar ball:

If the tar ball contains the typical configure, make, make install steps, building the RPM package is easy. We do not have to worry much about modifying the build procedure. Use rpmdev-newspec to generate the default spec file (see below), then complete the self-explanatory sections of the spec file, and let rpmbuild do the rest. rpmbuild has its own mechanism for tracking which files will be installed and it will warn you. Just open up the spec file (a text file), navigate to the %files section and put the files that rpmbuild complains about there.

// Execute one of the following commands:
sudo yum install @development-tools
sudo yum install fedora-packager
sudo yum install rpmdevtools
sudo yum install rpm-devel rpmdevtools rpmlint rpm-build

// Install wget so that we can use it to download the source tar ball
sudo yum -y install wget

// Create the rpmbuild user that we can use for building RPM packages
sudo useradd rpmbuild
sudo usermod -a -G mock rpmbuild
sudo passwd rpmbuild

// Log into your rpmbuild account

// Execute one of the following command (the last one is preferred)
mkdir -p ~/rpmbuild/{SPECS,SOURCES}

cd ~/rpmbuild/SOURCES
cd ~/rpmbuild/SPECS
rpmdev-newspec hello

Sample spec file:

Release: 1%(?dist) // Just change the number.
Group: Applications/Tools

Comments in the spec file starts with #

Source0: The name of the file (the tar ball) that we copied to the SOURCES folder


These are the things that are required to get this package compiled.


These are things that are required for your package to work. This is a list of package names, separated by commas

BuildArch: noarch

:set syntax=off // Vim, turn off syntax highlighting or coloring

To build the RPM package:

rpmbuild -bp ~/rpmbuild/SPECS/packageName.spec
rpmbuild -bi ~/rpmbuild/SPECS/packageName.spec
rpmbuild -ba ~/rpmbuild/SPECS/packageName.spec
rpmbuild -ba —sign ~/rpmbuild/SPECS/packageName.spec

rpm sign —add sign ~/rpmbuild/RPMS/noarch/packageName.rpm

sudo yum localinstall -nogpg packagename.rpm

gpg —list-keys
gpg —armor —export yourKey > RPM-GPG-KEYS-herlo
rpm —import RPMG-GPG-KEYS.herlo

rpm -qa ‘*gpg*’

How to setup and install a yum repository?

sudo yum install httpd
cd /var/www/html
cp /path/to/rpm .
createrepo -vv

yum list packageName // display the repositories that contains the given package
yum clean all

cd /etc/yum.repos.d/
vim repoName.repo:

Name=What ever name you want or a description of your repo

How to submit your RPM package to Fedora?


Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License