Chapter 34
Compiling SuSE Source Packages
|
|
|
|
|
![](gif/black.gif) |
In this chapter: |
|
|
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Installing Source-RPM (SRPM) packages
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Exploring the Contents of SRPMs
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Walking through the Build hierarchy
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Learning About RPM's Build stages
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
Reviewing an example of the entire Build process
|
|
|
|
![](gif/black.gif) |
|
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](gif/icon_note.gif) |
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:
|
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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
.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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](gif/icon_note.gif) |
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.
|
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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.
|
![*](gif/bullet.gif) ![](gif/clear.gif) |
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](gif/icon_note.gif) |
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.
|
![](gif/black.gif) |
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.
|
![](gif/black.gif) |