RPM homepage link
Home
Up

   Mandrake RPM HOWTO v1.1.1 Copy of: http://www.linux-mandrake.com/en/howtos/mdk-rpm/mdk-rpm.html
Date: 13 Nov 2002

This HOWTO is aimed at helping people who want to produce software packages which should integrate well in the Mandrake Linux distribution of GNU/Linux. In particular, it will stress in what way the packages are slightly different from the packages anyone would write for other rpm-based distributions. This document should be useful to MandrakeSoft developers, but also to external people.

The Mandrake Linux distribution of GNU/Linux is produced and published by MandrakeSoft, Inc.


1. Foreword

It is assumed in this document that the reader is "linux-ready". He already knows the basic commands, directory structure, and has already used rpm at least for installing packages.

This document is constructed as a step by step recipe to obtain a rpm package that can integrate well in the Mandrake Linux distribution of GNU/Linux, from either a previous source rpm or a tar source.

If you haven't done it yet, you should read the cooker web page, which explains the development process of Mandrake Linux.

RPM roughly means three things:

  • a program intended to install or create packages,

  • a format used in packages (source or binary) created by the program rpm,

  • a file called package which contains whether a binary or sources along with an information header about how to install/uninstall the program

The program rpm is, from the user's point of view, a powerful package manager. It acts as a "conductor" for any action on rpm packages. Among other things, it can:

  • install or upgrade a package verifying dependencies,

  • while installing a package, perform actions in order to make the program installed ready to use,

  • restore accidentally erased files from a package,

  • tell if a package is already installed,

  • find to which package belongs a particular file,

  • ....

From the programmer's point of view, the program rpm is a packager which encapsulates in a single rpm file all the information needed to install a program on a given platform.

It is important to distinguish from the beginning the difference between source (.src.rpm) and binary (.<archtype>.rpm) packages.

The first one contains (yes you guessed) the complete source tree from the original programmer, plus all the stuff the packager added in order to configure, compile and install the program. It generally consists of a spec file (the file used to tell rpm which operations perform in order to create the package) along with patches, if needed.

The second one contains the compiled binary, and all the files (documentation, config files, icons,...) that will be installed on the target system. It also contains the procedure used to put the files at their correct location, and the actions to perform in order to have the program operational.


2. Install the software


2.2. Building for Mandrake Linux

Building packages for Cooker (e.g. the development version of Mandrake Linux) is always submitted to small patches and enhancements on the rpm program in use. Open any Mandrake-Cooker mirror and get:

  • The package rpm which is our patched version of RedHat's.

  • The package rpm-build which holds scripts used to build packages.

  • The package spec-helper which is a tool to minimalize the specfiles by doing automatic things such as stripping the binaries and compressing the man pages.

  • The package libtool which is used by some configure scripts to build shared libraries.


3. Preliminary tasks


3.3. Subscribe to mailing lists

Mandrake's lists (Consult Mailing list pages on Mandrake Linux pages):


4. Building a RPM


4.1. From an existing source RPM

This is generally the case for the packages which are already included in the distribution.

The latest rpm files from cooker are available on many mirrors which list is available at http://www.linux-mandrake.com/en/cookerdevel.php3 . Under the ftp hierarchy, you will find:

  • /SRPMS/ for source rpms,

  • /cooker/Mandrake/RPMS/ for binary rpms.

  • /contrib/SRPMS/ for contrib source rpms,

  • /contrib/RPMS/ for contrib binary rpms.

When you find the source rpm you want to modify for Mandrake Linux, just issue rpm -ivh mypackage.src.rpm; it'll install all source files into your RPM directory.

For example:

[camille@kenobi ~/rpm]$ rpm -i /cooker/SRPMS/ktron-1.0.1-2mdk.src.rpm 
[camille@kenobi ~/rpm]$ ls -R * 
SRPMS: 
SPECS: 
ktron.spec 
SOURCES: 
ktron-1.0.1.tar.bz2 
RPMS: 
noarch/ i686/ i586/ i386/ 
BUILD: 

We see that rpm installed in our RPM tree the source file ktron-1.0.1.tar.bz2 and the spec file. It is all we need, in that case, to modify the spec file and then rebuild the package.

It is important to note that each package maintained at MandrakeSoft is stored on a cvs system. This allows every state of a package to being recorded by the system, so that the developer may consult the archive to check previous modifications and eventually come back to an older release version.

Each spec file is stored on a module called SPECS/<package> or contrib-SPECS/<package>.

For details on how to access cvs system, consult Mandrake Linux CVS pages


4.2. From raw sources

You found an interesting program at freshmeat or AppWatch or sourceforgewhich warns you when the tea is ready. And you want it available to all our Mandrake Linux's english tea drinkers.

Download it and place it in the SOURCES directory.


4.4. Inside the spec file

Here we are. This is the important section of this document. The spec file contains all the information needed by rpm to:

  1. compile the program and build source and binary rpms,

  2. install and uninstall the program on the final user's machine.

The fact that these two types of information are messed up into one single file may be quite confusing for the beginner. Actually, this is due to the source tar tree, which contains already this information. As installation procedure is extracted from the installation process generally run by make install into the source tree, both parts are tightly linked.

Important

In a nutshell, the spec file describes a "simulated" compilation and installation, tells rpm which files resulting from this installation are to be packed, and how to finally install these files onto the user's system. Commands there are executed using the /bin/sh shell, so such things like [ -f configure.in ] && autoconf is valid.

This part is not intended to explain you in details all the features of a spec file. The book Maximum RPM (see Section 7) explains it deeply. All we are going to do here is quickly check all of the features used into one standard example Mandrake spec file.

This is an example from the cooker repository. You may also consider our template spec file to begin your from scratch.

As you build more and more RPMs,you will find that there are some options that we have not told you about. RPM is extremely extensible, so, finding out all of those is left as an exercise to the reader. It is always good practice to open up some spec files to take a look at them and see how they work.

you can get a list of specs and patches here.

%define name gif2png 
%define version 2.0.1 
%define release 1mdk 

Name: %{name} 
Summary: tools for converting websites from using GIFs to using PNGs 
Version: %{version} 
Release: %{release} 
Source: http://www.tuxedo.org/~esr/gif2png/%{name}-%{version}.tar.bz2 
Source1: %{name}-%{version}-mdk-addon.tar.bz2 
Patch: gif2png-2.0.1-bugfix.patch.bz2 
URL: http://www.tuxedo.org/~esr/gif2png/ 
Group: Applications/Multimedia 
BuildRoot: %{_tmppath}/%{name}-buildroot 
License: MIT-like 
Requires: python 

%description
Tools for converting GIFs to PNGs. The program gif2png converts GIF files
to PNG files. The Python script web2png converts an entire web tree, also
patching HTML pages to keep IMG SRC references correct.

%prep 
rm -rf $RPM_BUILD_ROOT 
%setup -a 1 
%patch -p1 

%build 
%configure 
%make

%install 
%makeinstall

%clean 
rm -rf $RPM_BUILD_ROOT 

%files 
%defattr(-,root,root,0755) 
%doc README NEWS COPYING AUTHORS 
%{_mandir}/man1/gif2png.1*
%{_mandir}/man1/web2png.1*
%{_bindir}/gif2png 
%{_bindir}/web2png 

%changelog 
* Mon Nov 02 1999 Camille Begnis <camille@mandrakesoft.com> 2.0.1-1mdk
- Upgraded to 2.0.1 

* Mon Oct 25 1999 Camille Begnis <camille@mandrakesoft.com> 2.0.0-1mdk
- Specfile adaptations for Mandrake
- add python requirement
- gz to bz2 compression

Let's then analyze in details each line of this file.

Be careful, a % at the beginning of a line may tell different things :

  • the beginning of a section (prep, build, install, clean)

  • a built-in shell script macro (setup, patch)

  • a directive used by a special section (defattr, doc, ...)


4.4.1. Header section

%define name gif2png
%define version 2.0.1
%define release 1mdk

These three lines define constants that may be used in many following sections of the spec file, named %{name}, %{version} and %{release}.

Then, we can fill up some information fields for rpm :

Name: %{name}

The name of the package as used in package's name and package database on the user's machine.

Note that the "%{name}" is a reference to the previous define.

Version: %{version}
Release: %{release}

This is the moment to explain how is formed the name of a package. It is important to always respect this standard in order to make your work understandable to others.

There are also some tags that you might want to know about, but are not in the example spec file. There are some that you might encounter. It is not expected that you remember all of this if you just started building rpms, but after some time, this list makes good reference!

The name is generally chosen to be the name of the main binary of the package, though with adequate reasons this you can get away with another name.

The version is the number from the unpatched sources. It is the version number in the name of the original archive file: name-version.tar.gz.

The release is a number followed by mdk (stands for "Mandrake"; this is absolutely mandatory) which is incremented at each new build of the package. This may be due to a patch applied to the sources, a modification to the spec file, the addition of an icon, etc.

Summary: tools for converting websites from using GIFs to using PNGs

This line is a one-liner of the package description.

Source: http://www.tuxedo.org/~esr/gif2png/%{name}-%{version}.tar.bz2 

This line tells rpm what source file to use for building this package. Note that the filename is preceded by a complete URL (which is optional) pointing to the site where the original source is available; rpm will remove the url, keep the filename only, and search in the SOURCES directory. Although we say that the complete URL is optional, it is highly recommended as people will know where to find new sources should they take a liking to upgrading the source and do a recompilation.

When there are more than one source file, use other lines with Source1: ..., then Source2: ..., etc.

Patch: gif2png-2.0.1-bugfix.patch.bz2

Two reasons for this optional tag:

  1. You fixed a bug on the program sources. So you generated a patch file to be applied to the sources before compilation.

    Note that the patches are all bzipped, too. Even though if a patch is small you might not benefit from bzip2 compression it has to be bzipped, to be consistent.

  2. You've been warned of the existence of a patch for your software's version somewhere on the net, and downloaded it.

Note that the patch file must be placed into the SOURCES directory; as for the sources, there can be several patches, they will be named Patch1, Patch2, etc.

URL: http://www.tuxedo.org/~esr/gif2png/

This line (optional but highly recommended) points to the home page of the program.

Group: Multimedia

This is to tell rpm in which part of the general package tree to place this package. This feature is used with package managers front-end such as rpmdrake or kpackage.

The complete group structure to use, which is different from the one RedHat uses, is shown in Appendix C. It is mandatory to follow it, otherwise your package will mess with the other ones, in the package tree selection of Mandrake Linux installer, or in package manager front-ends.

BuildRoot: %{_tmppath}/%{name}-buildroot

This line is very important and cannot be omitted. It tells rpm that to install the program, it will have to use a special root directory (a fake "/") onto the compiling machine. There are two reasons for that:

  1. When building a rpm, you don't have root access to the machine, so you cannot install the package in normal directories ;

  2. The installation into the working tree of a working machine will probably mess the package's files with other files, and most important, it may be dangerous if the package is already installed. A lot of people like to use /var/tmp or /tmp for the buildroot. This is not necessarily a problem if you are the only user of your machine, but if you have multiple users on you machine, and they compile the same package at the same time rpm will barf. Therefore it is important that you define %{_tmppath}, and within your own home directory!

License: MIT-like

This tag (superseding Copyright) defines the license chosen by the copyright holder that will apply to the software being packed. In most cases it is GPL. See Appendix E for complete valid licenses list.

Here is a list of other licenses.at FSF. If you find that a package has a very similar license to a particlar license listed, but is not *quite* that license, you can put a suffix -like (see above.) for example, BSD-like.

Requires: python

This line was added because one of the programs included in the package is a python script. It then needs python to be executed. You can put optional minimum (or equal) version, for example: Requires: python >= 1.5.1

%description
Tools for converting GIFs to PNGs. The program gif2png converts GIF files
to PNG files. The Python script web2png converts an entire web tree, also
patching HTML pages to keep IMG SRC references correct.

This is a quite special tag inside the header of the spec file, because it is of a whole text made of various lines and paragraphs if needed. It contains the full description of the software being installed in order to help the user to decide whether he wants to install the package or not.

You may be asking yourself at this point: "And what about translations?" Actually, to improve readability of spec files, translations of summary and description tags are strored in a special file called <package>.po.

These files are stored on poSPECS module into cooker cvs. When a new package is created, the base po file is automatically created in this module for future translations.

This method implies that all text into a .spec file is written in english. However, an exception to that is for packages intended to a special language (ispell-de for example). It is then recommended to have the text in both languages: English and the specific package language. You will use special tags for that: Summary(de): .. and %description -l de.


4.4.3. Build section

%build 

This section will contain the script responsible for the actual build of the software.

It consists of the commands being issued when building a package from an untarred source tree.

%configure

This is the line used for configuring autoconf'ed sources. %configure issues a ./configure with many add-ons such as export CFLAGS="$RPM_OPT_FLAGS" before the configure, and options such as i586-mandrake-linux --prefix=/usr --datadir=/usr/share etc.

Sometimes these arguments are not supported by the configure script. In such case, you have to discover the reason, and issue the ./configure with appropriate parameters. Give the target platform to the configure call, if supported, with %{_target_platform}; of course, specification of an architecture must be avoided in specfiles; on ix86, this will expand to i586-mandrake-linux, as shown in the example above.

Note that you will need the libtool package to use %configure with packages building shared libraries.

Important

When building, and when testing your package, you should verify that the target host is actually a i586 ; in particular, when compiling on a higher processor type, the default behaviour of the configure script is to discover your processor, and optimize for it. The target of the %configure macro is to avoid this behaviour.

%make

This is a simple macro that basically performs a make with appropriate multiprocessor parameter -j<num>.

For sources using xmkmf, you should replace the next make with:

make CDEBUGFLAGS="$RPM_OPT_FLAGS" CXXDEBUGFLAGS="$RPM_OPT_FLAGS" 

For other packages, in many (but not all) cases a simple make will do.


4.4.5. Files section

%files 

This section consists of a list of files that will be picked from our simulation directory tree to be packed into the package. See the fine manual for the different options not being used in that simple example.

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

Note that you should never use find to build a list of files to include but explicitely list all files (this'll show up bugs in new versions). The only exceptions is for locales for which you should use %find_lang %{name} in %install section and replace %files by %files -f %{name}.lang (see Appendix B).

Note about directory structure: The files being installed by your package "should" follow the FHS recommendations at http://www.pathname.com/fhs

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

%doc README NEWS COPYING AUTHORS

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.

%{_mandir}/man1/gif2png.1*
%{_mandir}/man1/web2png.1*

Here also it is recommended to list each man or info file separately.

Note

Also you may wonder why telling gif2png.1* and not gif2png.1.bz2. This is to preserve compatibility with other systems that could use gzip compression instead of Mandrake bzip. If you find such referencies to bz2 compression into spec files, change them to a wildcard. Most of the time you can even use %{_mandir}/man1/*, this will take all the files it can find.

%{_bindir}/gif2png
%{_bindir}/web2png

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}. For games, use %{_gamesbindir} and %{_gamesdatadir}.


6. Send your work

Quite an easy step!

Just upload your source rpm (mypackage.src.rpm) to ftp://ftp.linux-mandrake.com/incoming/ Then send an e-mail to lenny in order to warn him. Additionally, you may want to CC it to the "Cooker" list.

If it is just a small change to an existing spec file, or if you have just added a patch, usually sending in the spec difference file and any additional patch file will do.


8. Advanced

Here are several things not necessary to build a first RPM. You should become familiar with the preceding stuff, then come back here and read this section.


8.1. Menu system

As of the 7.1 version of Mandrake Linux, 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" \
                mimetypes="text/html,text/plain" accept_url="false" multiple_files="true"

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
 ... menu stuff here ... using ONE line only per menu entry ...
EOF
in the %install section. You noticed the %{_menudir} macro. It shall expand to %{_libdir}/menu.

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}

You will have to provide the three icons described earlier. One popular way of doing it is to declare the three icons, bzipped, with Source: tags, and install them in appropriate directories in the %install section:

Source10: %{name}.16.xpm.bz2
Source11: %{name}.32.xpm.bz2
Source12: %{name}.48.xpm.bz2
# ..

%install
# ..
install -d $RPM_BUILD_ROOT/%{_miconsdir}
install -d $RPM_BUILD_ROOT/%{_liconsdir}
bzcat %{SOURCE10} > $RPM_BUILD_ROOT/%{_miconsdir}/%{name}.xpm
bzcat %{SOURCE11} > $RPM_BUILD_ROOT/%{_iconsdir}/%{name}.xpm
bzcat %{SOURCE12} > $RPM_BUILD_ROOT/%{_liconsdir}/%{name}.xpm

8.2. Library policy

In order to enjoy better upgrades, it is important to keep old major library versions in the system so that programs which use them still work.

Libraries in /usr/lib, /lib and /usr/X11R6/lib must be separately packaged, in library-only package, named with the name of the main library concatenated with the major of the library. These packages should not contain any binaries, they should be separately packaged. The goal is to be able to install libfoo1 and libfoo2 on the same system.

In the first time it is fundamental that the sources rpm keep the same name without any major number, so that the CVS repository only contains one branch for each package.

When the distribution must contain two versions of the same library, for example qt1 and qt2, sources rpms will be separated so that we can include the two of them in the distribution. And since then the two branches will be independently maintained.

Here's a generic example; the following case happens when the library comes with binaries, config files, or anything else that won't fit in the main library package (where only libraries go) nor in the devel package (where headers and devel libraries go (e.g. *.so and *.a)).

Source Package:
        foo-2.3.4-4mdk.src.rpm

Binary Packages:
	foo-2.3.4-4mdk.arch.rpm 
        libfoo2-2.3.4-4mdk.arch.rpm
	libfoo2-devel-2.3.4-4mdk.arch.rpm

In the opposite case to this example, when replacing an existing package, for example foobar, with a new one called libfoobar3, in the case foobar will not exist any more because there are no binaries, and no config files, libfoobar3 must have an obsolete tag on foobar. This is often the case for "simpler" libraries.

Source Package:
        foobar-3.1-7mdk.src.rpm

Binary Packages:
        libfoobar3-3.1-7mdk.arch.rpm
        libfoobar3-devel-3.1-7mdk.arch.rpm

Ok we described the default policy for library packages, however some special cases can happen and must be handled using the brain. Remember to always check the soname of the libraries ("objdump -x libfoo.so.1 | grep SONAME"), because some sonames include library version number, for example libfoo-1.2.so.4, in this case the package should be named libfoo1.2_4-1.2.4-3mdk.

Packages ending with a number should be handle with a "_" before the major, for example libfoo23_4-1.2-3mdk (in this case the soname would be libfoo23.so.4).

It is not necessary to split each library in separate packages, if a package contains several library, the name would be build with the main library of the package. If there are problems keeping libraries in the same package, the package should be splitted.

It is important to supply some Provides. First reason: concerning the devel package, most of the time the client app will only want to put libfoo-devel in the BuildRequires, without any version information. Second reason, for compatibility with other RPM-based systems, it's important to provide also original names, qualifying versions. Please refer to following skeleton examples. It's important to understand that putting a Provides without the version information, makes it impossible for later client RPM's to put a version information on dependencies, e.g. "Provides: foo-devel" is NOT enough, please use "Provides: foo-devel = 1.2.4-3mdk".

Here's an example of specfile for a package with no binary and config files, so only lib* binary packages are needed.

%define name gtkmm
%define version	1.2.4
%define release 1mdk
%define lib_name_orig libgtkmm
%define lib_major 1.2
%define lib_name %{lib_name_orig}%{lib_major}

Name: %{name}
Summary: C++ interface for popular GUI library gtk+       #(!) summary for SRPM only
Version: %{version}
Release: %{release}

%description
#Full and generic description of the whole package. (this will be the SRPM
#description only)

#main package (contains *.so.[major].* only)
%package -n %{lib_name}
Summary: Main library for gtkmm                           #(!) summary for main lib RPM only
Group: System/Libraries
Provides: %{name} = %{version}-%{release}

%description -n %{lib_name}
This package contains the library needed to run programs dynamically
linked with gtkmm.

%package -n %{lib_name}-devel
Summary: Headers for developing programs that will use Gtk--
Group: Development/GNOME and GTK+
Requires: %{lib_name} = %{version}
Provides: %{lib_name_orig}-devel = %{version}-%{release}  #(!) **MANDATORY**
Provides: %{name}-devel = %{version}-%{release}           #(!) **MANDATORY**

%description -n %{lib_name}-devel
This package contains the headers that programmers will need to develop
applications which will use Gtk--, the C++ interface to the GTK+ (the Gimp
ToolKit) GUI library.

%post -n %{lib_name} -p /sbin/ldconfig
%postun -n %{lib_name} -p /sbin/ldconfig

%files -n %{lib_name}
# ..
%{_libdir}/*.so.*

%files -n %{lib_name}-devel
# ..
%{_bindir}/gtkmm-config
%{_includedir}/*.h
%{_libdir}/*.so

8.3. Deeper inside the specfiles...

Here are some more tags that you might see, some that you will see often, some not.

There is also some interesting macros to note. Say you wanted to do something, but not on every platform. You can do this within RPM with the conditional macros:

%ifarch alpha sparc ppc
%patch0 -p1
%endif

The explanation: only apply the patch if the architecture is alpha, sparc, or ppc. It is not limited to using here, for example you can include this in your %files section if you so wish.

Ok. So you know that you can use rpm -ba to build a package. But you have more to play around with:

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


8.5. update-alternatives

The program update-alternatives, originally written by Debian, is here to provide default system-wide commands through the use of symbolic links. An example will help to understand the point:

# Whenever you call 'vim'...
lrwxrwxrwx    1 root     root           21 Jan 31 10:25 /bin/vim -> /etc/alternatives/vim

# It will go to /etc/alternatives...
lrwxrwxrwx    1 root     root           26 Mar 20 00:51 /etc/alternatives/vim -> ../../usr/bin/vim-enhanced

# Then, to the real program.
-rwxr-xr-x    1 root     root      1724604 Jun 18 13:25 /usr/bin/vim-enhanced

When a new program wants to provide the same functionality (say, vim-minimal) it would register to the update-alternatives system, and potentially become the real program called under vim. The choice is either made automatically (under that scenario, the program with highest 'priority' will be used, see below) or manually.

Here's how emacs-nox and emacs-X11 register and unregister themselves to the update-alternatives system:

%post nox
update-alternatives --install %{_bindir}/emacs emacs %{_bindir}/emacs-nox 10
%post X11
update-alternatives --install %{_bindir}/emacs emacs %{_bindir}/emacs-%{version} 20

%postun nox
update-alternatives --remove emacs %{_bindir}/emacs-nox
%postun X11
update-alternatives --remove emacs %{_bindir}/emacs-%{version}

The syntax with the --install command is pretty self-explanatory: you need to provide the link, the name, the full path of the real binary, and the priority. Default behaviour of the resulting system is to follow the priority (e.g. the 'automatic' mode).


8.11. Easy handling of differences between two RPM's

Here is how Chmouel handles finely the differences between two RPM's.

rpmdiff () {
        if [[ -z $1 ]]
        then
                "Need a package"
                return 1
        fi
        package=$(rpm -qp --qf '%{NAME}' $1) 
        if [ -f /RPMS/$package-[0-9]* ]
        then
                /usr/bin/rpmdiff /RPMS/$package-[0-9]* $1 | \
                egrep '^(missing|added)' | egrep -v '/usr(/share)?/doc/'
        else
                echo "Can't find the pacakge  in /RPMS/"
        fi
}

example :

(chmou@kenobi)[RPMS/i586]-% rpmdiff util-linux-2.10n-1mdk.i586.rpm
missing    /usr/lib/more.help
added      /usr/share/misc/more.help
(chmou@kenobi)[RPMS/i586]-% 

8.12. To become a Jedi, use Emacs you have to

In a nutshell, Emacs can automate much of the work, with appropriate configuration file. A good start is Chmouel's, which is too big even to fit in appendices (> 1000 lines). You can find it on the web here: ftp://ftp.mandrakesoft.com/chmou/pub/rpm-spec-mode.el

Once installed, in addition to nice syntax highlighting, you'll increase the release tag with C-c r, add a new changelog entry (with your name, email address, correct version and release tag) with C-c e; you will even visit the bzipped patches (granted you have jka-compr and ffap) with minimal pain! And much more...

To use ffap/jka-compr in spec-file you can tell to the user to set this in ~/.emacs:

(if (not (jka-compr-installed-p)) (toggle-auto-compression))
(require 'ffap)
(defvar ffap-spec-path '("../SOURCES"))
(defun ffap-spec (name) (ffap-locate-file name t ffap-spec-path))
(add-to-list 'ffap-alist '(rpm-spec-mode . ffap-spec))

A. Of Pre- and Post-installation scripts


B. More macros

When building RPM's for Mandrake Linux, you have more macros to simplify the specfile.

  • Handling the info pages. An example is the best teacher:

    %post
    %_install_info %{name}.info
    
    %preun
    %_remove_install_info %{name}.info

  • The menu system. (detailed presentation in Appendix D)

    %post
    %{update_menus}
    
    %postun
    %{clean_menus}

  • Handling internationalization cleanly. The best way is not to put by hand the .mo files that usually are in /usr/share/locale/.., but to use a special macro in the %install section, which will fill up a special file for that:

    %find_lang %{name}

    Then you will use the file in the file list:

    %files -f %{name}.lang

  • Build macros. The build macros %configure and %makeinstall are quite big at present time. They specify the prefix, but also every common directories (such as bindir, datadir, and so on); in that respect, they work flawlessly with small and medium sized packages, but always need some attention for the rest. The macro %make performs the make command with appropriate -j<num> option to scale well with multiprocessors. If you need to call manually the ./configure script, remember to NEVER hardcode the architecture; the macro %{_target_platform} is made for that purpose (or even, %{_target_cpu} if necessary).

  • Building servers. To build safer servers, we use a specific macro, %serverbuild, to be used before actual build occurs. This allows for safer optimization flags. The %build section will often look like:

    %build
    %serverbuild
    %configure
    make

  • Initscript macros. When you install a package which will provide its own initscript (the files in the directory /etc/init.d), it needs to be added through a call which look like chkconfig --add .., but not in the case of upgrades, and it needs to be restarted if already running; when uninstalling, similar (opposite) things must be done; we have specific macros to do that without a glitch:

    %post
    %_post_service <initscript-name>
    
    %preun
    %_preun_service <initscript-name>

  • Handling ghostfiles. Mostly with games, sometimes packages use a varying file which may even not be present. That's where ghostfiles are useful. Here's an example:

    %install
    
    (...)
    
    mkdir -p $RPM_BUILD_ROOT/var/lib/games
    touch $RPM_BUILD_ROOT/var/lib/games/methanescores
    
    %post
    %create_ghostfile /var/lib/games/powermanga.hi root games 664
    
    (...)
    
    %files
    %attr(664, root, games) %ghost /var/lib/games/powermanga.hi

    The %create_ghostfile macro will expand to:

    if [ ! -f /var/lib/games/powermanga.hi ]; then 
      touch /var/lib/games/powermanga.hi
      chown root.games /var/lib/games/powermanga.hi
      chmod 664 /var/lib/games/powermanga.hi
    fi 

C. Mandrake Linux Groups

Here is the list of the groups to use for building a RPM package for Mandrake Linux. It is now different from the old one invented and used by RedHat, because it appeared (to our side) that it was no more suitable for today's distribution.

To give some examples, the list indicates that following are correct groups: System/Libraries, System/Fonts/Console, ..

- System
     - Servers
     - Kernel and hardware
     - Libraries
     - XFree86
     - Fonts  
         - Console
	 - True type
	 - Type1
	 - X11 bitmap
     - Base
     - Configuration
         - Hardware
	 - Packaging
	 - Networking
	 - Printing
	 - Boot and Init
	 - Other
     - Internationalization
- Development
     - Kernel
     - Databases
     - Perl
     - Python
     - C
     - C++
     - Java
     - GNOME and GTK+
     - KDE and QT
     - Other
- Sciences  
     - Astronomy	
     - Biology 
     - Chemistry
     - Computer science
     - Geosciences 
     - Mathematics
     - Physics
     - Other
- Communications
- Databases
- Editors
- Emulators
- Games
     - Adventure
     - Arcade
     - Boards
     - Cards
     - Puzzles
     - Sports
     - Strategy
     - Other
- Toys
- Archiving
     - Compression
     - Cd burning
     - Backup
     - Other
- Monitoring
- Sound
- Graphics
- Video
- Networking
     - File transfer
     - IRC
     - ICQ
     - Chat
     - News
     - Mail
     - WWW
     - Remote access
     - Other
- Office
- Publishing
- Terminals
- Shells
- File tools
- Text tools
- Graphical desktop
     - GNOME
     - Icewm
     - FVWM based
     - KDE
     - Sawmill
     - Window Maker
     - Enlightenment
     - Other
- Books
     - Howtos
     - Faqs
     - Computer books
     - Litterature
     - Other

D. Mandrake Linux Menu Structure

Here's the menu structure. It is mandatory to use it.

- {Window_Manager_Name}
  - Settings
  - Action
- Configuration
  - Hardware
  - Packaging
  - Networking
  - Printing
  - Boot and Init
  - Other
- Terminals
- Applications
  - Development
    - Interpreters
    - Code generators
    - Development environments
    - Tools
  - Sciences
    - Astronomy	
    - Biology 
    - Chemistry
    - Computer science
    - Geosciences 
    - Mathematics
    - Physics
    - Other    
  - Communications
  - Editors
  - Emulators
  - Archiving
     - Compression
     - Cd burning
     - Backup
     - Other
  - Monitoring
  - Publishing
  - Shells
  - File tools
  - Text tools
  - Finances
  - Databases
- Documentation
- Office
  - Spreadsheets
  - Time management
  - AddressBooks
  - Presentations
  - Graphs
  - PDA
  - Tasks management
  - Accessories
- Networking
  - File transfer
  - IRC
  - ICQ
  - Chat
  - News
  - Mail
  - WWW
  - Remote access
  - Other
- Amusement
  - Adventure
  - Arcade
  - Boards
  - Cards
  - Puzzles
  - Sports
  - Strategy
  - Other
  - Toys
- Multimedia
  - Sound
  - Graphics
  - Video


This menu is genereated specifically by each windowmanager,
to provide specific wm related functions (restart, etc.) :

- Session
  - Management
  - Windowmanagers
  - Restart session
  - Exit session

E. Mandrake Linux Valid Licenses

rpmlint will complain if you use a License: different from one or many of the following licenses:

- GPL
- LGPL
- Artistic
- BSD
- MIT
- QPL
- MPL
- IBM Public License
- Apache License
- PHP License
- Public Domain
- Modified CNRI Open Source License
- zlib License
- CVW License
- Ricoh Source Code Public License
- Python license
- Vovida Software License
- Sun Internet Standards Source License
- Intel Open Source License
- Jabber Open Source Licens

Last updated: Tue, 12 Nov 2002 23:12:03 -0500

Back to Top page
Maintained by Owl River Company -- Comments to: rpm editor, please.