Quick Guide to RPM

Installing a new package

Checking files installed by a package

Checking files offered by a  new package

Checking which package provides a file

Building RPMs from source files

rpm --rebuild Zope-2.4.1-1.src.rpm

The compiled RPM is located under /usr/src/redhat/RPMS/

Quick Steps

  1. Log on as a regular user. Do NOT build RPMs when logged as root, as you could erase/replace important system files by mistake. Always work as a regular user, and create the RPM directory structure in your home directory
  2. In your home directory, build the RPM directory tree through
    mkdir -p ~/rpm/{BUILD,RPMS/$ARCH,RPMS/noarch,SOURCES,SRPMS,SPECS,tmp}
    , where $ARCH is the architecture for which you want to create RPMs (ie. i386, sparc, alpha, ppc)
  3. ~/.rpmmacros
    	%_target               linux
    	%_topdir               /home/jdoe/rpm
    	%_tmppath              /home/jdoe/rpm/tmp
  4. Create a dummy tar ball through cd ~/rpm/SOURCES ; mkdir tmp ; touch tmp/jdoe ; tar czvf mytar-1-0.tar.gz tmp/jdoe ; rm -Rf ~/rpm/SOURCES/tmp
  5. Build mytar-1-0.specs in ~/rpm/SPECS following the sample below
  6. Cd to ~/rpm/SPECS, and build the package through rpm -ba mytar-1-0.spec. Provided things went smoothly, the binary RPM is in ~/rpm/RPMS and the source RPM is located in ~/rpm/SRPMS
  7. To install the package, you must su to root, at least to allow RPM to update its applications database which lives in /var/lib/rpm/packages.rpm

SPECS file sample

You'll want to name your spec file according to a standard convention. It should be package name-dash-version number-dash-release number-dot-spec (eg. mytar-1-0.tar.gz)
	Summary: Fred's very first RPM package!
	Name: mytar
	Version: 1 
	Release: 0
	Copyright: public domain
	Group: Dummy Package Group/MyGroup
	Source: %{name}-%{version}-%{release}.tar.gz
	BuildRoot: %{_tmppath}/%{name}-buildroot
	#Requires: python >= 1.5.1
	BuildArchitectures: noarch
	My very fine description
	rm -rf $RPM_BUILD_ROOT/tmp
	mkdir -p $RPM_BUILD_ROOT/tmp
	zcat $RPM_SOURCE_DIR/mytar-1-0.tar.gz | (cd $RPM_BUILD_ROOT ; tar -xvSpf-)
	if [ "${RPM_BUILD_ROOT}X" != "X" ]; then
	    rm -rf ${RPM_BUILD_ROOT}
	* Tue Feb 29 2000 John Doe 
	- My very first RPM package!

How does RPM work?

RedHat creates an RPM directory tree under /usr/src/redhat. If you install any .src.rpm package, its spec file is installed in /usr/src/redhat/SPECS: General settings are set in /usr/lib/rpm/macros

Basic Command Reference

Action RPM Command
Installing/updating rpm -Uvh package.rpm
Erasing rpm -e package
Querying RPM for all installed packages rpm -qa | less
Querying for information on a non-installed package rpm -qip package
Querying for a list of files contained in a non-installed package rpm -qlp package
Querying RPM to find out which package installed a given file rpm -qf /usr/bin/unknownfile
Querying RPM to check whether any file is missing or has been modified from all installed packages rpm -Va
Querying RPM whether any file in an installed package is missing or has been modified rpm -Vv package
Checking the integrity of a non-installed package rpm -K --nopgp package.rpm
Building a binary RPM from a source RPM rpm --rebuild package.src.rpm, followed by rpm -Uvh package.rpm
Compressing and rebuilding RPM's database rpm --rebuilddb


Temp stuff

The basic procedure to build an RPM is as follows:
Make sure your /etc/rpmrc is setup for your system.
Get the source code you are building the RPM for to build on your system.
Make a patch of any changes you had to make to the sources to get them to build properly.
Make a spec file for the package.
Make sure everything is in its proper place.
Build the package using RPM.

the only configuration of RPM is available via the /etc/rpmrc file
	require_vendor: 1
	distribution: I roll my own!
	require_distribution: 1
	topdir: /usr/src/me
	vendor: Mickiesoft
	packager:  Mickeysoft Packaging Account 
	optflags: i386 -O2 -m486 -fno-strength-reduce
	optflags: alpha -O2
	optflags: sparc -O2
	signature: pgp
	pgp_name: Mickeysoft Packaging Account
	pgp_path: /home/packages/.pgp
	tmppath: /usr/tmp

The 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 require_distribution and require_group lines.

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).

You can use: rpm --showrc to find out how your tags are set and what all the available flags are.

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):

	Summary: This is a one line description of the package.
	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.
	Copyright: This line tells how a package is copyrighted. You should use something like GPL, BSD, MIT, public domain, distributable, or commercial.

	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. 

	BuildRoot: 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.

	Source: sunsite.unc.edu:/pub/Linux/utils/disk-management/eject-1.4.tar.gz
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:
Source0: blah-0.tar.gz
Source1: blah-1.tar.gz
Source2: fooblah.tar.gz
These files would go in the SOURCES directory. (The directory structure is discussed in a later section, "The Source Directory Tree".)

	Patch: eject-1.4-make.patch
	Patch1: eject-1.4-jaz.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:
Patch0: blah-0.patch
Patch1: blah-1.patch
Patch2: fooblah.patch
These files would go in the SOURCES directory.

	It's not really a header item, but should be described with the rest of the header. You need one description tag per package and/or subpackage. This is a multi-line field that should be used to give a comprehensive description of the package.	

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 do a make.

Each of these sections is really just a place to execute shell scripts. You could simply make an sh script and put it after the %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 cd's into the source directory. It also takes the following options:
-n name will set the name of the build directory to the listed name. The default is $NAME-$VERSION. Other possibilities include $NAME, ${NAME}${VERSION}, or whatever the main tar file uses. (Please note that these ``$'' variables are not real variables available within the spec file. They are really just used here in place of a sample name. You need to use the real name and version in your package, not a variable.)
-c will 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 -c so don't do it). This is only useful with multiple source files.
-a # will untar Source# after cd'ing into the directory.
-T This option overrides the default action of untarring the Source and requires a -b 0 or -a 0 to get the main source file untarred. You need this when there are secondary sources.
-D Do 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).

	%patch -p1
	%patch1 -p1
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.
-P The default action is to apply Patch (or Patch0). This flag inhibits the default action and will require a 0 to get the main source file untarred. This option is useful in a second (or later) %patch macro that required a different number than the first macro.
You can also do %patch# instead of doing the real command: %patch # -P
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 cd into subdirectories if necessary.
	install -s -m 755 -o 0 -g 0 eject /usr/bin/eject
	install -m 644 -o 0 -g 0 eject.1 /usr/man/man1
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 make 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.

6.7 Optional pre and post Install/Uninstall Scripts
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:
%pre is the macro to do pre-install scripts.
%post is the macro to do post-install scripts.
%preun is the macro to do pre-uninstall scripts.
%postun is the macro to do post-uninstall scripts.
The contents of these sections should just be any sh style script, though you do not need the #!/bin/sh.
	%doc README COPYING ChangeLog

6.8 Files This is the section where you must list the files for the binary package. 

There are some macros available to do some special things as well. They are listed and described here:

%doc is 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.

%config is 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 .rpmsave appended to the filename. You can list multiple files with this macro as well.

%dir marks 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 
%dir macro, EVERYTHING in that directory is included in the file list and later installed as part of that package.

%files -f  will allow you to list your files in some arbitrary file within the build directory of the sources. This is nice in cases where you have a package that can build it's own filelist. You then just include that filelist here and you don't have to specifically list the files.
The biggest caveat in the file list is listing directories. If you list /usr/bin by accident, your binary package will contain every file in /usr/bin on your system.

8.1. Menu system
As of the 7.1 version of Linux-Mandrake, we now use the Menu System written by Debian.
This excellent software provides a Window-Manager independant way to register an application to the system. Most of the time, this registration will become effective in the Start button or alike of your favourite Window Manager.
It works like this: each package includes a file in directory /usr/lib/menu/. Most of the time the filename will be the name of the package. In this file, it will have one line per menu-entry, like this:
?package(xbase):command="/usr/bin/X11/xedit" icon="xbase.xpm" \
                needs="X11" section="Applications/Editors" title="Xedit" \
                longtitle="The basic editor for the X Window system"
It is suggested that you put the menu file within the spec, instead of creating a separate source for it. To do that you can :
cat << EOF > $RPM_BUILD_ROOT/%{_menudir}/myprogram
EOF in the %install section. You noticed the %{_menudir} macro. It shall expand to %{_libdir}/menu. command: the command to launch ; it can be absolute or not (if so, it will use the PATH of the Window-Manager) icon: the xpm icon to be used by the Window Manager to refer to the application ; mainly used in the start button alike, but also can be used to dock (include in a toolbar/panel) the app ; therefore, you will not give an absolute path, and provide three classes of icons in your rpm package: a 16x16, a 32x32, and a 48x48, respectively in /usr/share/icons/mini, /usr/share/icons, and /usr/share/icons/large with the same name. There are macros for these three directories: %{_miconsdir} ; %{_iconsdir} ; %{_liconsdir}. needs: there are three classes of needs: x11 indicates an application that will be launched under a private window provided by the X-Window system; text indicates an application needing a terminal to be run (for example, this is the case for "telnet", "gnuplot", etc); the last one is the name of a Window Manager, in order to prevent the other WM's from proposing this app; for example you will like that "iceconf" appear in the menu only under icewm, and you will use needs="icewm" for this one. section: the section where the application will go ; it has to be normalized in order to be efficient, therefore see Appendix Appendix D for the complete menu structure title: the name under which the application will be registered in the start button alike of the Window Managers longtitle: used by the Window Managers which support tooltips to display more information Whenever root runs update-menus, it will check all new or changed menufiles in /etc/menu and /usr/lib/menu, and run the installation scripts Window Managers should provide in /etc/menu-methods on them. Use our special macros for that: %post %{update_menus} %postun %{clean_menus} rpm -bp: stops after completion of the %prep section. Basically, it uncompresses the sources and applies the relevant patches. rpm -bc: stops after completion of the %build section. Generally involves the equivalent of "make". rpm -bi: stops after completion of the %install section. Well, do you have to use -ba to build again? No! All is not lost. The Mandrake RPM system has been specially patched to allow the -bi option to work with --short-circuit, which will basically resume the process. So, let's say you screwed up your %files section, and now you have fixed it, you don't have to build again from -ba. You can just use rpm -bi --short-circuit file.spec, and then rpm -ba --short-circuit file.spec to build it. Bear in mind, this is for advanced users ONLY as it is very easy to build a broken spec if you do that. rpm --eval %macroname can evaluate a particular RPM macro. This seems to be an undocumented feature in the RPM 3.0.x series. For example, if you would like to find the %packager macro stands for, do: rpm --eval %packager. To sign your RPM packages while building, you can use the --sign argument. To add one to an existing RPM, do rpm --addsign file.rpm. To resign an existing one, use the --resign option. But alas, when you type this you get nothing, because you still haven't set up your ~/.rpmmacros yet. Now, add 2 lines to your ~/.rpmmacros. Add %signature pgp and %_pgp_name Your_Signature_Name. Replace pgp with gpg, if you choose to use that one instead. Sometimes setting the permissions of the installed files for RPM is not always %defattr(-,root,root). You can set individual permissions for files, with the %attr() macro. %attr follows a similar format to %defattr, except that %attr is put in front of the filename. To tell RPM that the file specified is a configuration file, place a %config at the front of the file. That way, RPM will upgrade the file, but save a copy of the old one on the local hard drive. Most of the time, it is NOT the desired behaviour, because you shall lose (temporarily) your precious configuration in exchange of the default one which is obviously far poorer than what you need. To address this issue, use %config(noreplace). %pre This script is executed just before the package is installed on the system. %post This script is executed just after the package is installed on the system. %preun This script is executed just before the package is uninstalled from the system. %postun This script is executed just after the package is uninstalled on the system. There are several features that make building packages on all platforms easy. The first of these is the ``optflags'' directive in the /etc/rpmrc. It can be used to set flags used when building software to architecture specific values. Another feature is the ``arch'' macros in the spec file. They can be used to do different things depending on the architecture you are building on. Another feature is the ``Exclude'' directive in the header. In this example, you see how the ``optflags'' directive is used from the /etc/rpmrc. Depending on which architecture you are building on, the proper value is given to RPM_OPT_FLAGS. You must patch the Makefile for your package to use this variable in place of the normal directives you might use (like -m486 and -O2). You can get a better feel for what needs to be done by installing this source package and then unpacking the source and examine the Makefile. Then look at the patch for the Makefile and see what changes must be made. In some cases the configure script will be partially broken and you may need to lurk in the Makefiles to guess the additional parameters to have it install correctly. One of the most common ones is that sometimes you have to use make DESTDIR=$RPM_BUILD_ROOT install. %files The file list must be written by hand in the spec file. It may be constructed by listing all files created by rpm in the build directory tree. In order to do that, issue a rpm -bi mypackage.spec in order to stop the building process just after the simulated install. Then, look in the simulated installation directory, ~/rpm/tmp/gif2png-buildroot in our case, to see which files you want to put in your package (most of the time, you will put them all). %defattr(-,root,root,0755) This tag defines the attributes to be applied to each file being copied to the user's system. The four arguments given means: -: all the attributes for regular files are remained unchanged, root: the owner of the file is root, root: the group of the file is root, 0755: the attributes applied to all directories owned by this package are 0755. The special tag %doc designates files being part of the documentation of the package. The files so-called will be placed in /usr/doc/gif2png-2.0.1/. This directory will be also automatically created. Files specified by %doc are relative to your untarred source directory in BUILD. As you can see, you have macros for every kind of path you need. Here are the most useful ones (look at /usr/lib/rpm/macros for everything) : %{_prefix}, %{_bindir}, %{_sbindir}, %{_datadir}, %{_libdir}, %{_sysconfdir}, %{_mandir}, %{_infodir}. * Mon Nov 02 1999 Camille Begnis 2.0.1-1mdk The first line of the paragraph begins with * and, in order, each one separated by a space: three letters for the day of the week, three letters for the month, two figures for the day of the month, four figures for the year, First name of the packager, Last name of the packager, e-mail of the packager between <>. version and release of current modifs. To stop the building process just after the simulated install rpm -bi mypackage.spec To build the whole package rpm -ba mypackage.spec ---------------------------------------------------------------------------------- [/usr/src/redhat/SPECS]# less docbook.spec Summary: An SGML DTD for technical documentation. Name: docbook %define version 3.1 %define release 3 Version: %{version} Release: %{release} Copyright: Copyright 1992, 1993, 1994, 1995, 1996 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., and Fuj itsu Software Corporation. Prereq: sgml-common Source: ftp://sourceware.cygnus.com/pub/docbook-tools/docware/SOURCES/docbook-%{version}.tgz Source1: ftp://sourceware.cygnus.com/pub/docbook-tools/docware/SOURCES/docbook-3.0.tgz Group: Applications/Text BuildArch: noarch BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root Prefix: /usr %description DocBook is an SGML DTD (document type definition). DTDs define how the markup tags in SGML documents should be interpreted. DocBook is well suited for the creation of books and papers about computer hardware and software. %prep %setup -q -c -b1 %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/sgml/docbook-3.0 install -m644 dtd/docbook-3.1/*.{mod,dtd,cat,dcl} $RPM_BUILD_ROOT/%{prefix}/lib/sgml/ install -m644 dtd/docbook-3.0/*.{mod,dtd,cat,dcl} $RPM_BUILD_ROOT/%{prefix}/lib/sgml/docbook-3.0 %clean rm -rf $RPM_BUILD_ROOT %post # since old-postun is run *after* new-post, we must always cycle. V=%{version}-%{release} %{prefix}/bin/install-catalog --install docbook --version $V >/dev/null V=3.0-%{version}-%{release} %{prefix}/bin/install-catalog --install docbook-3.0/docbook --version $V >/dev/null %postun # since old-postun is run *after* new-post, we must always cycle. V=%{version}-%{release} %{prefix}/bin/install-catalog --remove docbook --version $V >/dev/null V=3.0-%{version}-%{release} %{prefix}/bin/install-catalog --remove docbook-3.0/docbook --version $V >/dev/null %files %defattr(-,root,root) %doc dtd/docbook-3.1/*.txt dtd/docbook-3.1/ChangeLog %{prefix}/lib/sgml/* %changelog * Fri Jan 28 2000 Bill Nottingham - fix %pre/%post * Wed Jan 5 2000 Bill Nottingham - add in docbook-3.0 stuff - sanitize specfile * Mon Nov 8 1999 Tim Powers - updated to 3.1 * Tue Jul 13 1999 Tim Powers - changed buildroot to /var/tmp/docbook-root - updated source download location - built for 6.1 * Fri Apr 23 1999 Michael K. Johnson - quiet scripts