📄 0225-0228.html
字号:
<HTML>
<HEAD>
<TITLE>Maximum RPM (RPM):Making a Package That Can Build Anywhere:EarthWeb Inc.-</TITLE>
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<SCRIPT>
<!--
function displayWindow(url, width, height) {
var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>
-->
<!-- ISBN=0672311054 //-->
<!-- TITLE=Maximum RPM (RPM)//-->
<!-- AUTHOR=Edward Bailey//-->
<!-- PUBLISHER=Macmillan Computer Publishing//-->
<!-- IMPRINT=Sams//-->
<!-- CHAPTER=16 //-->
<!-- PAGES=0225-0236 //-->
<!-- UNASSIGNED1 //-->
<!-- UNASSIGNED2 //-->
<P><CENTER>
<a href="../ch15/0222-0224.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0229-0231.html">Next</A>
</CENTER></P>
<A NAME="PAGENUM-225"><P>Page 225</P></A>
<H3><A NAME="ch16_ 1">
Chapter 16
</A></H3>
<H2>
Making a Package That <BR>
Can Build Anywhere
</H2>
<A NAME="PAGENUM-226"><P>Page 226</P></A>
<P>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:
</P>
<UL>
<LI> You are unable to
dedicate a system to RPM package building, or the software
you're packaging would disrupt the build system's operation if it were installed.
<LI> You would like to package software, but you don't have root access to an
appropriate build system.
</UL>
<P>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:
</P>
<UL>
<LI> Writing the package's spec file to support a build root
<LI> Directing RPM to build software in a user-specified build area
<LI> Specifying file attributes that RPM needs to set on installation
</UL>
<P>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.
</P>
<H3><A NAME="ch16_ 2">
16.1. Using Build Roots in a Package
</A></H3>
<P>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.
</P>
<P>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:
</P>
<UL>
<LI> A default build root
must be defined in the package's spec file.
<LI> The installation method used by
the software being packaged must be able to
support installation in an alternate root.
</UL>
<P>The first part is easy. It entails adding the following line to the spec file:
</P>
<!-- CODE SNIP //-->
<PRE>
BuildRoot: <root>
</PRE>
<!-- END CODE SNIP //-->
<A NAME="PAGENUM-227"><P>Page 227</P></A>
<P>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.
</P>
<P>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.
</P>
<P>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:
</P>
<UL>
<LI> The environment variable
RPM_BUILD_ROOT is set by RPM and contains the value of
the build root to be used when the software is built and installed.
<LI> The
%install section of the spec file is modified to use
RPM_BUILD_ROOT as part of the installation process.
<LI> If the software is installed using
make, the makefile is modified to use
RPM_BUILD_ROOT and to create any directories that may not exist at installation time.
</UL>
<P>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:
</P>
<!-- CODE SNIP //-->
<PRE>
BuildRoot: /tmp/cdplayer
</PRE>
<!-- END CODE SNIP //-->
<P>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:
</P>
<!-- CODE SNIP //-->
<PRE>
%install
make ROOT="$RPM_BUILD_ROOT" install
</PRE>
<!-- END CODE SNIP //-->
<P>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:
</P>
<!-- CODE //-->
<PRE>
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
</PRE>
<!-- END CODE //-->
<A NAME="PAGENUM-228"><P>Page 228</P></A>
<P>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.
</P>
<P>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.
</P>
<P>Let's see how it works:
</P>
<!-- CODE //-->
<PRE>
# 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
</PRE>
<!-- END CODE //-->
<P><CENTER>
<a href="../ch15/0222-0224.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0229-0231.html">Next</A>
</CENTER></P>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -