Building RPMs is fairly easy to do, especially if you can get the software you are trying to package to build on its own.
The basic procedure to build an RPM is as follows:
/etc/rpmrcis setup for your system.
Under normal operation, RPM builds both binary and source packages.
Right now, the only configuration of RPM is available via the
/etc/rpmrc file. An example one looks like:
require_vendor: 1 require_distribution: 1 require_group: 1 distribution: RHL 2.0 vendor: Red Hat Software arch_sensitive: 1 topdir: /usr/src/redhat-2.0 optflags: i386 -O2 -m486 optflags: axp -O2
require_vendor line causes RPM to require that it find
a vendor line. This can come from the
/etc/rpmrc or from the
header of the spec file itself. To turn this off, change the number to
0. The same holds true for the
The next line is the
distribution line. You can define that here
or later in the header of the spec file. When building for a particular
distribution, it's a good idea to make sure this line is correct, even though
it is not required. The
vendor line works much the same way, but
can be anything (ie. Joe's Software and Rock Music Emporium).
The next line is
arch_sensitive. This specifies where the binary
RPMs go and what they are named. Right now, i386 is defined as
a type within RPM. That means if you are building on an Intel machine
and have this value set to true, your RPMs will go in
/usr/src/redhat-2.0/RPMS/i386/ and their name will be something
foobar-1.0-1.i386.rpm. If you set this value to
the RPMs will be placed in
/usr/src/redhat-2.0/RPMS/ and will
be named something like
foobar-1.0-1.bin.rpm. This does not
affect the name or placement of the source RPM, however.
RPM also now has support for building packages on multiple architectures.
rpmrc file can hold an ``optflags'' variable for building things
that require architecture specific flags when building. See later sections
for how to use this variable.
In addition to the above macros, there are several more. You can use:
topdirto specify the top level directory for building. In Red Hat 2.0, this directory is
specdiris the directory under topdir to use for the spec files. The default for this is
builddirspecifies the top level of the build directory. The default for this is
sourcedirspecifies the top level of the source directory. The default for this is
SOURCES. This is where the pristine tar files, the patches, and the icons go.
rpmdirsets the directory for the binary RPMs. The default for this is
srcrpmdirsets the directory for the source RPMs. The default for this is
docdirspecifies where the documentation should be installed. By default, this is
libdirsets the path for the RPM database. By default, this is
timechecksets whether or not to do a timecheck by default.
We'll begin with discussion of the spec file. Spec files are required to build a package. The spec file is a description of the software along with instructions on how to build it and a file list for all the binaries that get installed.
You'll want to name your spec file according to a standard convention. It should be the package name-dash-version number-dash-release number-dot-spec.
Here is a small spec file (vim-3.0-1.spec):
Description: VIsual editor iMproved Name: vim Version: 3.0 Release: 1 Icon: vim.gif Source: sunsite.unc.edu:/pub/Linux/apps/editors/vi/vim-3.0.tar.gz Patch: vim-3.0-make.patch Copyright: distributable Group: Applications/Editors %prep %setup %patch -p1 cd src cp makefile.unix makefile %build cd src make %install rm -f /bin/vim cd src make install ln -sf vim /bin/vi %files %doc doc/reference.doc doc/unix.doc tutor/tutor /bin/vim /bin/vi /usr/man/man1/vim.1 /usr/lib/vim.hlp
The header has some standard fields in it that you need to fill in. There are a few caveats as well. The fields must be filled in as follows:
Description:This one is kind of obvious. You can span multiple lines by ending each line with a backslash.
Name:This must be the name string from the rpm filename you plan to use.
Version:This must be the version string from the rpm filename you plan to use.
Release:This is the release number for a package of the same version (ie. if we make a package and find it to be slightly broken and need to make it again, the next package would be release number 2).
Icon:This is the name of the icon file for use by other high level installation tools (like Red Hat's ``glint''). It must be a gif and resides in the SOURCES directory.
Source:This line points at the HOME location of the pristine source file. It is used if you ever want to get the source again or check for newer versions. Caveat: The filename in this line MUST match the filename you have on your own system (ie. don't download the source file and change its name). You can also specify more than one source file using lines like:
These files would go in the
Source0: blah-0.tar.gz Source1: blah-1.tar.gz Source2: fooblah.tar.gz
SOURCESdirectory. (The directory structure is discussed in a later section, "The Source Directory Tree".)
Patch:This is the place you can find the patch if you need to download it again. Caveat: The filename here must match the one you use when you make YOUR patch. You may also want to note that you can have multiple patch files much as you can have multiple sources. ] You would have something like:
These files would go in the
Patch0: blah-0.patch Patch1: blah-1.patch Patch2: fooblah.patch
Copyright:This line tells how a package is copyrighted. You should use something like GPL, BSD, MIT, public domain, distributable, or commercial.
Root:This line allows you to specify a directory as the ``root'' for building and installing the new package. You can use this to help test your package before having it installed on your machine.
Group:This line is used to tell high level installation programs (such as Red Hat's ``glint'') where to place this particular program in its hierarchical structure. The group tree currently looks something like this:
Applications Communications Editors Emacs Engineering Spreadsheets Databases Graphics Networking Mail Math News Publishing TeX Base Kernel Utilities Archiving Console File System Terminal Text Daemons Documentation X11 XFree86 Servers Applications Graphics Networking Games Strategy Video Amusements Utilities Libraries Window Managers Libraries Networking Admin Daemons News Utilities Development Debuggers Libraries Libc Languages Fortran Tcl Building Version Control Tools Shells Games
This is the second section in the spec file. It is used to get the
sources ready to build. Here you need to do anything necessary to
get the sources patched and setup like they need to be setup to
One thing to note: Each of these sections is really just a place to
execute shell scripts. You could simply make an
sh script and put it
%prep tag to unpack and patch your sources. We have
made macros to aid in this, however.
The first of these macros is the
%setup macro. In its simplest form
(no command line options), it simply unpacks the sources and
the source directory. It also takes the following options:
-n namewill set the name of the build directory to the listed
name. The default is
$NAME-$VERSION. Other possibilities include
$NAME$VERSION, or whatever the main tar file uses.
-cwill create and cd to the named directory before doing the untar.
-b #will untar Source# before cd'ing into the directory (and this makes no sense with
-cso don't do it). This is only useful with multiple source files.
-a #will untar Source# after cd'ing into the directory.
-TThis option overrides the default action of untarring the Source and requires a
-a 0to get the main source file untarred. You need this when there are secondary sources.
-DDo not delete the directory before unpacking. This is only useful where you have more than one setup macro. It should only be used in setup macros after the first one (but never in the first one).
The next of the available macros is the
%patch macro. This macro
helps automate the process of applying patches to the sources. It takes
several options, listed below:
#will apply Patch# as the patch file.
-p #specifies the number of directories to strip for the patch(1) command.
-PThe default action is to apply
Patch0). This flag inhibits the default action and will require a
0to get the main source file untarred. This option is useful in a second (or later)
%patchmacro that required a different number than the first macro.
%patch#instead of doing the real command:
%patch # -P
That should be all the macros you need. After you have those right, you
can also do any other setup you need to do via
sh type scripting.
Anything you include up until the
%build macro (discussed in the
next section) is executed via
sh. Look at the example above for
the types of things you might want to do here.
There aren't really any macros for this section. You should just put
any commands here that you would need to use to build the software
once you had untarred the source, patched it, and cd'ed into the directory.
This is just another set of commands passed to
sh, so any legal
sh commands can go here (including comments). Your current
working directory is reset in each of these sections to the toplevel
of the source directory, so keep that in mind. You can
subdirectories if necessary.
There aren't really any macros here, either. You basically just want to
put whatever commands here that are necessary to install. If you have
make install available to you in the package you are building, put
that here. If not, you can either patch the makefile for a
install and just do a
make install here, or you can hand install
them here with
sh commands. You can consider your current
directory to be the toplevel of the source directory.
You can put scripts in that get run before and after the installation
and uninstallation of binary packages. A main reason for this is
to do things like run
ldconfig after installing or removing
packages that contain shared libraries. The macros for each of the
scripts is as follows:
%preis the macro to do pre-install scripts.
%postis the macro to do post-install scripts.
%preunis the macro to do pre-uninstall scripts.
%postunis the macro to do post-uninstall scripts.
The contents of these sections should just be any
script, though you do not need the
This is the section where you must list the files for
the binary package. RPM has no way to know what binaries get installed
as a result of
make install. There is NO way to do this.
Some have suggested doing a
find before and after the package
install. With a multiuser system, this is unacceptable as other files
may be created during a package building process that have nothing to
do with the package itself.
There are some macros available to do some special things as well. They are listed and described here:
%docis used to mark documentation in the source package that you want installed in a binary install. The documents will be installed in
/usr/doc/$NAME-$VERSION-$RELEASE. You can list multiple documents on the command line with this macro, or you can list them all separately using a macro for each of them.
%configis used to mark configuration files in a package. This includes files like sendmail.cf, passwd, etc. If you later uninstall a package containing config files, any unchanged files will be removed and any changed files will get moved to their old name with a
.rpmsaveappended to the filename. You can list multiple files with this macro as well.
%dirmarks a single directory in a file list to be included as being owned by a package. By default, if you list a directory name WITHOUT a
%dirmacro, EVERYTHING in that directory is included in the file list and later installed as part of that package.
The biggest caveat in the file list is listing directories. If you list
/usr/bin by accident, your binary package will contain every file
/usr/bin on your system.
The first thing you need is a properly configured build tree.
This is configurable using the
/etc/rpmrc file. Most people
will just use
You may need to create the following directories to make a build tree:
BUILDis the directory where all building occurs by RPM. You don't have to do your test building anywhere in particular, but this is where RPM will do it's building.
SOURCESis the directory where you should put your original source tar files and your patches. This is where RPM will look by default.
SPECSis the directory where all spec files should go.
RPMSis where RPM will put all binary RPMs when built.
SRPMSis where all source RPMs will be put.
The first thing you'll probably want to to is get the source to
build cleanly without using RPM. To do this, unpack the sources,
and change the directory name to $NAME.orig. Then unpack the
source again. Use this source to build from. Go into the source
directory and follow the instructions to build it. If you have to
edit things, you'll need a patch. Once you get it to build, clean
the source directory. Make sure and remove any files that get made
cd back out of the source directory
to its parent. Then you'll do something like:
This will create a patch for you that you can use in your spec file. Note that the ``linux'' that you see in the patch name is just an identifier. You might want to use something more descriptive like ``config'' or ``bugs'' to describe why you had to make a patch. It's also a good idea to look at the patch file you are creating before using it to make sure no binaries were included by accident.
diff -uNr dirname.orig dirname > ../SOURCES/dirname-linux.patch
Now that you have source that will build and you know how to do it, build it and install it. Look at the output of the install sequence and build your file list from that to use in the spec file. We usually build the spec file in parallel with all of these steps. You can create the initial one and fill in the easy parts, and then fill in the other steps as you go.
Once you have a spec file, you are ready to try and build your package. The most useful way to do it is with a command like the following:
rpm -ba -v foobar-1.0.spec
There are other options useful with the
-b switch as well:
pmeans just run the
prepsection of the specfile.
lis a list check that does some checks on
cdo a prep and compile. This is useful when you are unsure of whether your source will build at all. It seems useless because you might want to just keep playing with the source itself until it builds and then start using RPM, but once you become accustomed to using RPM you will find instances when you will use it.
ido a prep, compile, and install.
bprep, compile, install, and build a binary package only.
abuild it all (both source and binary packages).
-bswitch. They are as follows:
--short-circuitwill skip straight to a specified stage (can only be used with c and i).
--cleanremoves the build tree when done.
--keep-tempswill keep all the temp files and scripts that were made in /tmp. You can actually see what files were created in /tmp using the
--testdoes not execute any real stages, but does keep-temp.
--time-check #is very useful. By default, the time-check value is 7200 seconds (two hours). What this does is check all the files in
%filesand warns you if they are more than
#seconds old (or the default). This lets you make sure that the newly created binaries are getting installed and not old ones that just happen to be still lying around. This author can attest to the value of this feature after having to release several RPP updates because old binaries were accidentally included. You can also turn this off (useful when building binary only packages of commercial software) by setting the value to zero.
Once you have a source and binary rpm for your package, you need to
test it. The easiest and best way is to use a totally different machine
from the one you are building on to test. After all, you've just
done a lot of
make install's on your own machine, so it should
be installed fairly well.
You can do an
rpm -u packagename on the package to test, but that
can be deceiving because in building the package, you did a
If you left something out of your file list, it will not get uninstalled.
You'll then reinstall the binary package and your system will be complete
again, but your rpm still isn't. Make sure and keep in mind that just
because you do a
rpm -ba package, most people installing your package will
just be doing the
rpm -i package. Make sure you don't do anything
install sections that will need to be done when
the binaries are installed by themselves.
Once you've made your own RPM of something (assuming its something that hasn't already been RPM'ed), you can contribute your work to others (also assuming you RPM'ed something freely distributable). To do so, you'll want to upload it to an FTP site somewhere. We hope RPM will become a standard that everyone starts using. If that is the case, you should probably upload your RPMs to sunsite.unc.edu. Until then, please upload them to our official Red Hat Mirror, ftp.pht.com:/pub/linux/redhat/Incoming. We are currently mirrored on several other sites, and this is the best place to find new RPMs.