Chapter 34

Compiling SuSE Source Packages
 

 
 
In this chapter:
 
 
* Installing Source-RPM (SRPM) packages
* Exploring the Contents of SRPMs
* Walking through the Build hierarchy
* Learning About RPM's Build stages
* Reviewing an example of the entire Build process
 
 
 
Most of the applications shipping with SuSE Linux are licensed under the Gnu General Public License (GPL) or a similar Open Source license. This requires that SuSE makes the source code for these packages available to everyone who gets the binaries. SuSE did the obvious thing and put these sources on the CDs that come with the SuSE Linux set.
 
The sources are packaged in Source RPMs (SRPM). This means SuSE takes advantage of RPM's abilities to ease handling the source code for the binary packages that are provided. It was one of RPM's major design goals to include source code handling into the package concept. We'll learn a whole lot more about this in chapter 36 when we start building our own RPM package files. In chapter 33 we learned how to use RPM to install binary packages. In this chapter we will extend our knowledge about RPM and see how to build and install software using the SRPM packages shipped with SuSE Linux.
34.1 Installing SRPMs
 


 
All source packages are collected in the series zq - Source Packages. They can be installed using YaST or by manually calling rpm -i, which is explained in chapter 33.
 

NOTE Unlike ordinary packages, they can't be uninstalled using RPM. SRPM packages are not under the control of the RPM database. All RPM does is copy the files contained in the package to the hard disk. SRPMs are not listed in the RPM database and not marked as installed in YaST's package selection forms.
 
 
Why is this? The main reason is that their source code is not really part of the system. A SRPM typically contains a tar-archive with the original sources, a spec-file describing the software, and a patch file to adopt the original package for the SuSE distribution. None of these files change the system's behavior.
 
Let's have a closer look at the contents of a SRPM. We'll stick with the rxvt example from the last chapter, and look at the SRPM for this package:
 
 
rpm -qpl rxvt.spm 
rxvt-2.4.7.dif 
rxvt-2.4.7.tar.gz 
rxvt.spec 
 
 
You see the SRPM has the extension spm instead of rpm. This is not the main difference. If you look at the contents you see three files, but no path indicating where they should be installed. Where do these files go when you install the package? RPM sorts them into a special hierarchy in /usr/src depending on the function of each file (source, /patch or spec file). We will see in chapter 36 how the package builder tells RPM which of the files is used to build the package, which are sources, and which are patches. The spec file is RPM's source of information during the package build, so it is fully aware of everything that is going on.
 
34.2 The RPM build tree
 

To use RPM as a tool for building software packages, we must follow some rules in terms of locations for the source code used to build this software. Expect three different kinds of input to build a package:
 

 
* The Sources
Of course we need source code to build the package. At this point when we talk about sources we mean the original source tree as provided by the author of the software without any customizations. Usually these sources are distributed as compresse tar file (tgz). RPM can handle other formats too, but all SuSE source packages use tgz files for source archives.
* The Patches
Sources downloaded from the Internet seldom reflect the layout of the particular system you want to install them on. This means changes are needed. These changes are made using the utility diff and are stored in so-called patch or diff files. Keeping the changes separate from the source makes sense for reasons we'll learn more in chapter 36 .
* The Spec File
The spec file is the heart of RPM's package building process. It's a little bit like a make file, as it contains information on how to build the package. But it's settled on a much higher level and contains also all meta information about the package. Spec-files usually have the extension .spec.
 
 
If you go back to the rxvt example, you see a spec, a patch, and a tgz file listed in the package contents. The source file containing the original source tree is rxvt-2.4.7.tar.gz, the spec file is rxvt.spec, and the patches are in rxvt-2.4.7.dif. RPM uses a special hierarchy to build software packages. It uses separate directories for spec files, source and patch files, resulting RPM and SRPM files, and for performing the actual build process. In SuSE Linux these directories are located in /usr/src/packages. Table 35-1 lists the five subdirectories used by RPM.
 
 
Table 34-1 RPM Directories for Building Packages
 
Directory Contents
SPECS Spec files
SOURCES Source and patch files
BUILD Used to build (unpack and compile) the software package
RPMS Contains the build RPM files (sorted by architecture)
SRPMS Contains the build SRPM files
  If we go back to our example and look for the files installed with the rxvt SRPM, we will find the following constellation:
 
 
# find /usr/src/packages/ 
/usr/src/packages/ 
/usr/src/packages/BUILD 
/usr/src/packages/RPMS 
/usr/src/packages/RPMS/i386 
/usr/src/packages/SOURCES 
/usr/src/packages/SOURCES/rxvt-2.4.7.dif 
/usr/src/packages/SOURCES/rxvt-2.4.7.tar.gz 
/usr/src/packages/SPECS 
/usr/src/packages/SPECS/rxvt.spec 
/usr/src/packages/SRPMS 
 
 
RPM put the source and the patch file in /usr/src/packages/SOURCES and the spec file in /usr/src/packages/SPEC. All other directories are empty. They will be used in the build process.
 
NOTE Note that there is a i386 subdirectory in /usr/src/packages/RPMS. RPM is designed to support multiple architectures. The package builder is advised to keep the SRPM architecture independent. This means it should build well on any architecture (Well, this is the theory...). Of course the binary package contains binaries for the architecture the package was compiled on. For this reason RPM will put the RPM packages into separate subdirectories for each architecture.
 
 
 
Table 34-2 RPM Build Stages
 
Flag Stage
p prep (unpack sources and apply patches)
l list check (do some cursory checks on %files)
c compile (prep and compile)
i install (prep, compile, install)
b binary package (prep, compile, install, package)
a bin/src package (prep, compile, install, package)
 
34.3 Building the Package
 

After the SRPM is installed and you know your way around in the build hierarchy, we can continue with the RPM build stages. RPM builds packages in four steps or stages.
 

 
* Preparation
The prep-stage is where the actual work building the binary package starts. In this stage the sources are unpacked and the patches to the sources are applied. If the package builder had forseen any additional preparations which have to be done prior to compiling the sources, they will be executed in this stage.
* Compilation
After the sources are prepared, the compilation process can take place. In this stage all source files are compiled and linked to the resulting binaries, libraries, etc.
* Installation
This stage installs the new software package on the system. At this point the build process changes your actual system. It puts the binaries, libraries, configuration files, etc. in the places where they belong for the new software package. No entry is made in the RPM database reflecting this installation. You should be aware of the fact that installing binaries from a source package doesn't include that the package is under the control of the RPM database.
* Packaging
The last step is to create the RPM and the SRPM for the new software package. You may wonder about this step -- if you got a SRPM from the CD, why is a new one created? You can turn off this stage, which makes sense when you just want to compile and install the package. If you can use the binary package for this software from the beginning, why do you want to do this in the first place? If you choose to use the source package, it's probably because you want to make changes to the sources that change the behavior of the binaries. This is a perfectly good reason to have a new RPM that includes your changes.
   
Table 34-3 RPM Build Options
 
Option Meaning
-bstage-spec or -tstage-tarball build package (see table 34-2 for stage spec)
--short-circuit skip straight to specified stage (only for c,i)
--clean remove build tree when done
--rmsource remove sources and spec file when done
--buildrootdir use dir as the build root
--buildarcharch build the packages for architecture arch
--buildosos build the packages for operating system os
--test do not execute any stages
--timechecksecs set the time check to secs seconds (0 disables)
--rebuildsrpm install source package, build binary package and remove spec file, sources, patches, and icons.
--rmsourcespec remove sources and spec file
--recompilesrpm like --rebuild, but don't build any package
 
 
To start the build process use the command rpm -b with the spec file as argument. More options for building packages are listed in table 34-3. Running rpm -ba will go through all stages and result in a RPM package, a SRPM package, and the software installed in your system (but not entered in the RPM database). If you don't want to go through the whole build process and want to stop at a certain stage, you can give the stage name as additional argument to rpm. The options for each stage are listed in table 34-2. For example, if you don't want to compile the package at all but just want to look something up in the sources, you can use this option. In this case you can use rpm -bpspec-file to execute the prep stage only.
 
We will walk through every stage using the rxvt package as an example. We start with the preparation stage:
 
 
# rpm -bp rxvt.spec 
Executing: %prep 
+ umask 022 
+ cd /usr/src/packages/BUILD 
+ cd /usr/src/packages/BUILD 
+ rm -rf rxvt-2.4.7 
+ /bin/gzip -dc /usr/src/packages/SOURCES/rxvt-2.4.7.tar.gz 
+ tar -xvvf - 
drwxr-xr-x mason/staff       0 1998-08-27 18:53 rxvt-2.4.7/ 
drwxr-xr-x mason/staff       0 1998-08-27 18:53 rxvt-2.4.7/autoconf/ 

 
[... file listing skipped ...]
 
-rw-r--r-- mason/staff 2824 1998-08-08 01:55 rxvt-2.4.7/INSTALL -rw-r--r-- mason/staff 1681 1998-08-27 17:12 rxvt-2.4.7/rxvt-2.4.7.lsm + STATUS=0 + '[' 0 -ne 0 ']' + cd rxvt-2.4.7 + chown -R root . + chgrp -R root . + chmod -R a+rX,g-w,o-w . + echo 'Patch #0:' Patch #0: + patch -p0 -s + CFLAGS=-D_GNU_SOURCE + ./configure --prefix=/usr/X11R6 --enable-xpm-background --with-xpm \\ --enable-utmp --enable-wtmp --enable-ttygid creating cache ./config.cache configuring for rxvt 2.4.7 checking for gcc... gcc checking whether the C compiler (gcc -D_GNU_SOURCE ) works... yes checking whether we are using GNU C... yes
 
[... autoconf output skipped ...]
 
creating rclock/Makefile creating config.h Configuration: Rxvt version: 2.4.7 : 28 AUGUST 1998 Source code location: . Install path: /usr/X11R6/bin Compiler: gcc Compiler flags: -D_GNU_SOURCE Xpm library: -L/usr/X11/lib -lXpm malloc support: system default utmp support: enabled utmp file: /var/run/utmp (config.h) wtmp file: /var/log/wtmp (config.h) ttys/ttytab file: (config.h) *** Please check src/feature.h for further options *** + exit 0
 
 
First the tar files gets uncompressed and unpacked. The patches are applied, and the configure script is started. If you look into the directory /usr/src/packages/BUILD after you execute the prep stage, you'll see that there is a subdirectory, rxvt-2.4.7, containing the source files for the rxvt package.
 
NOTE If you are only interested in looking at the source code, you are done at this point. The sources are installed, unpacked, and all changes SuSE made to them are applied. The source tree you have on your system now reflects the same source tree SuSE used to build the binary package on the CD.
 
 
To continue with the example, we'll go on to the compilation stage. You could either start over and let RPM do the preparation again, or use the prepared sources and jump right into the compilation. The default for RPM is to start over at the beginning. The command rpm -bc will have the source and patch files do the preparation work and then compile the source code.
 
Since we have gone through the preparation already, we will short-circuit RPM and only do the compilation:
 
 
# rpm -bc --short-circuit rxvt.spec 
Executing: %build 
+ umask 022 
+ cd /usr/src/packages/BUILD 
+ cd rxvt-2.4.7 
+ make 
make[1]: Entering directory `/usr/src/packages/BUILD/rxvt-2.4.7/src' 
/usr/bin/sed -n -f ./makeprotos-sed command.c > command.pro 
/usr/bin/sed -n -f ./makeprotos-sed graphics.c > graphics.pro 

 
[... output skipped ...]
 
make[1]: Entering directory `/usr/src/packages/BUILD/rxvt-2.4.7/rclock' cat ./rclock.1.in\ |sed -e 's%@RXVT_VERSION@%2.4.7%g;'\ |sed -e 's%@RXVT_DATE@%28 AUGUST 1998%g;'\ |sed -e 's%@RXVT_MAINT@%Geoff Wing%g;'\ > rclock.1 gcc -c -I/usr/X11R6/include -I. -I.. -I. -DHAVE_CONFIG_H -D_GNU_SOURCE rclock.c gcc -o rclock rclock.o -L/usr/X11R6/lib -lSM -lICE -lX11 make[1]: Leaving directory `/usr/src/packages/BUILD/rxvt-2.4.7/rclock' + exit 0
 
 
The parameter --short-circuit directs rpm not to execute the stages prior to the stage given as argument. In the output above you see that no preparation has taken place, and the prepped sources have been taken as start-point for the compilation.
 
After this step the binaries are ready to be installed in your system. You can copy them manually if you are only interested in special parts of the package, or let RPM install the entire set. This is done with rpm -bi. Again, this command by default starts at the very beginning. But we can use the --short-circuit switch again to skip the first two stages:
 
 
# rpm -bi --short-circuit rxvt.spec 
Executing: %install 
+ umask 022 
+ cd /usr/src/packages/BUILD 
+ cd rxvt-2.4.7 
+ make install 
./autoconf/mkinstalldirs /usr/X11R6/bin 
./autoconf/mkinstalldirs /usr/X11R6/man/man1 
make[1]: Entering directory `/usr/src/packages/BUILD/rxvt-2.4.7/src' 

 
[... output skipped ...]
 
+ DOCDIR=/usr/doc/packages/rxvt + export DOCDIR + rm -rf /usr/doc/packages/rxvt + /bin/mkdir -p /usr/doc/packages/rxvt + cp -pr doc/rxvt.html doc/rxvtRef-frame.html doc/rxvtRef-toc.html doc/rxvtRef.html doc/menu doc/BUGS doc/FAQ doc/README.greek doc/README.menu /usr/doc/packages/rxvt + cp -pr doc/README.xvt doc/TODO doc/rxvtRef.txt doc/xterm.seq doc/README.SuSE /usr/doc/packages/rxvt + exit 0 Finding provides... Finding requires... Provides: rclock rxvt Requires: ld-linux.so.2 libICE.so.6 libSM.so.6 libX11.so.6 libXpm.so.4 libc.so.6 /bin/sh
 
 
Besides the missing entry in the RPM database, you now have the same status as you would have with the installed binary package.
 
The last stage is to create the binary and the source packages. You do this with rpm -ba. Unfortunately there is no way to skip the other stages for this option. So you have to go through the whole process again. The only choice you have is to skip building of the source package. If you want to do this use rpm -bb instead of rpm -ba. In order to have a complete example we will create the binary and the source package:
 
# rpm -ba rxvt.spec 
Executing: %prep 
+ umask 022 
+ cd /usr/src/packages/BUILD 
+ cd /usr/src/packages/BUILD 
+ rm -rf rxvt-2.4.7 
+ /bin/gzip -dc /usr/src/packages/SOURCES/rxvt-2.4.7.tar.gz 
+ tar -xvvf - 
drwxr-xr-x mason/staff       0 1998-08-27 18:53 rxvt-2.4.7/ 
drwxr-xr-x mason/staff       0 1998-08-27 18:53 rxvt-2.4.7/autoconf/ 

 
[... output skipped ...]
 
Finding provides... Finding requires... Provides: rclock rxvt Requires: ld-linux.so.2 libICE.so.6 libSM.so.6 libX11.so.6 libXpm.so.4 libc.so.6 /bin/sh Wrote: /usr/src/packages/SRPMS/rxvt-2.4.7-28.src.rpm Wrote: /usr/src/packages/RPMS/i386/rxvt-2.4.7-28.i386.rpm
 
 
The build process is completed. RPM tells you where it put the source and the binary package. The source package rxvt-2.4.7-28.src.rpm can be found in /usr/src/packages/SRPMS, and the binary package rxvt-2.4.7-28.i386.rpm in /usr/src/packages/RPMS/i386. These two packages are the same packages as the ones shipped with the SuSE distribution, unless you changed something in the source code or the spec file. In terms of creativity, this example was not very useful. But it served well to discuss the principles of RPM's strategy on building a software package.
 
 
Summary:
  This chapter showed us that RPM is much more than a utility to install and uninstall packages. It also serves as a development tool. We learned about the file system tree used by RPM to build packages, and walked through the four stages of the build process: preparation, compilation, installation, and packaging. This discussion taught us how to execute a single stage, understand the preconditions, and what the output of every stage is.
 
--
Back Up Contents Next
--

Copyright (c) 1999 by Terrehon Bowden and Bodo Bauer
To contact the author please sent mail to bb@bb-zone.com