-->

Previous | Table of Contents | Next

Page 225

Chapter 16

Making a Package That
Can Build Anywhere

Page 226

Although RPM makes building packages as easy as possible, some of the default design decisions might not work well in a particular situation. Here are two situations where RPM's method of package building may cause problems:

Either of these situations can be resolved by directing RPM to build, install, and package the software in a different area on your build system. It requires a bit of additional effort to accomplish this, but taken a step at a time, it is not dificult. Basically, the process can be summed up by addressing the following steps:

The methods discussed here are not required in every situation. For example, a system administrator developing a package on a production system may only need to add support for a build root. On the other hand, a student wishing to build a package on a university system will need to get around the lack of root access by implementing every method described here.

16.1. Using Build Roots in a Package

Part of the process of packaging software with RPM is to actually build the software and install it on the build system. The installation of software can be accomplished only by someone with root access, so a nonprivileged user will certainly need to handle RPM's installation phase differently. There are times, however, when even a person with root access will not want RPM to copy new files into the system's directories. As mentioned earlier, the reason might be due to the fact that the software being packaged is already in use on the build system. Another reason might be as mundane as not having enough free space available to perform the install into the default directories.

Whatever the reason, RPM provides the capability to direct a given package to install into an alternate root. This alternate root is known as a build root. Several requirements must be met in order for a build root to be utilized:

The first part is easy. It entails adding the following line to the spec file:


BuildRoot: <root>

Page 227

Of course, you would replace <root> with the name of the directory in which you'd like the software to install. (Keep in mind that the build root can be overridden at build time using the --buildroot option or the buildroot rpmrc file entry. See Chapter 12, "rpm -b Command Reference," for more details.) If, for example, you specify a build root of /tmp/foo, and the software you're packaging installs a file bar in /usr/bin, you'll find bar residing in /tmp/foo/usr/bin after the build.

A note for you nonroot package builders: Make sure you can actually write to the build root you specify! Those of you with root access should also make sure you choose your build root carefully. For a variety of reasons, it's not a good idea to declare a build root of /. We'll get into the reasons shortly.

The final requirement for adding build root support is to make sure the software's installation method can support installing into an alternate root. The difficulty in meeting this requirement can range from dead simple to nearly impossible. There are probably as many different ways of approaching this as there are packages to build. But in general, some variant of the following approach is used:

Here's an example of how these components work together to utilize a build root. First, there's the definition of the build root in the spec file:


BuildRoot: /tmp/cdplayer

This line defines the build root as being /tmp/cdplayer. All the files installed by this software will be placed under the cdplayer directory. Next is the spec file's %install section:


%install

make ROOT="$RPM_BUILD_ROOT" install

Since the software we're packaging uses make to perform the actual install, we simply define the environment variable ROOT to be the path defined by RPM_BUILD_ROOT. So far, so good. Things really start to get interesting in the software's makefile, though:


install: cdp cdp.1.Z

# chmod 755 cdp

# cp cdp /usr/local/bin

install -m 755 -o 0 -g 0 -d $(ROOT)/usr/local/bin/

install -m 755 -o 0 -g 0 cdp $(ROOT)/usr/local/bin/cdp

# ln -s /usr/local/bin/cdp /usr/local/bin/cdplay

ln -s ./cdp $(ROOT)/usr/local/bin/cdplay

# cp cdp.1 /usr/local/man/man1

install -m 755 -o 0 -g 0 -d $(ROOT)/usr/local/man/man1/

install -m 755 -o 0 -g 0 cdp.1 $(ROOT)/usr/local/man/man1/cdp.1

Page 228

In this example, the commented lines were the original ones. The uncommented lines perform the same function, but also support installation in the root specified by the environment variable ROOT.

One point worth noting is that the makefile now takes extra pains to make sure the proper directory structure exists before installing any files. This is often necessary because build roots are deleted, in most cases, after the software has been packaged. This is why install is used with the -d option: to make sure the necessary directories have been created.

Let's see how it works:


# rpm  -ba   cdplayer-1.0.spec

* Package:   cdplayer

Executing:  %prep

+  cd   /usr/src/redhat/BUILD

...

+  exit  0

Executing:   %build

+  cd   /usr/src/redhat/BUILD

+  cd  cdplayer-1.0

...

+  exit  0

+  umask  022

Executing:  %install

+  cd  /usr/src/redhat/BUILD

+  cd  cdplayer-1.0

+ make ROOT=/tmp/cdplayer install

install -m 755 -o 0 -g 0 -d /tmp/cdplayer/usr/local/bin/

install -m 755 -o 0 -g 0 cdp /tmp/cdplayer/usr/local/bin/cdp

ln -s ./cdp /tmp/cdplayer/usr/local/bin/cdplay

install -m 755 -o 0 -g 0 -d /tmp/cdplayer/usr/local/man/man1/

install -m 755 -o 0 -g 0 cdp.1 /tmp/cdplayer/usr/local/man/man1/cdp.1

+ exit 0

Executing: special doc

+  cd  /usr/src/redhat/BUILD

+  cd  cdplayer-1.0

+        DOCDIR=/tmp/cdplayer//usr/doc/cdplayer-1.0-1

+  rm    -rf /tmp/cdplayer//usr/doc/cdplayer-1.0-1

+ mkdir -p /tmp/cdplayer//usr/doc/cdplayer-1.0-1

+  cp   -ar  README /tmp/cdplayer//usr/doc/cdplayer-1.0-1

+  exit  0

Binary   Packaging:   cdplayer-1.0-1

Finding   dependencies...

Requires   (2):   libc.so.5 libncurses.so.2.0

usr/doc/cdplayer-1.0-1

usr/doc/cdplayer-1.0-1/README

usr/local/bin/cdp

usr/local/bin/cdplay

usr/local/man/man1/cdp.1

93 blocks

Generating signature: 0

Wrote:    /usr/src/redhat/RPMS/i386/cdplayer-1.0-1.i386.rpm

+ umask 022

+ echo Executing: %clean

Executing:   %clean

+   cd   /usr/src/redhat/BUILD





Previous | Table of Contents | Next