📄 0229-0231.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="0225-0228.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0232-0234.html">Next</A>
</CENTER></P>
<A NAME="PAGENUM-229"><P>Page 229</P></A>
<!-- CODE //-->
<PRE>
+ cd cdplayer-1.0
+ exit 0
Source Packaging: cdplayer-1.0-1
cdplayer-1.0.spec
cdplayer-1.0.tgz
82 blocks
Generating signature: 0
Wrote: /usr/src/redhat/SRPMS/cdplayer-1.0-1.src.rpm
#
</PRE>
<!-- END CODE //-->
<P>Looking over the output from the %install section, we first see that the
RPM_BUILD_ROOT environment variable in the make
install command has been replaced with the path specified
earlier in the spec file on the BuildRoot: line. The
ROOT environment variable used in the makefile now has the appropriate value, as can be seen in the various install commands that follow.
</P>
<P>Note also that we use install's -d option to ensure that every directory in the path exists
before we actually install the software. Unfortunately, we can't do this and install the file in
one command.
</P>
<P>Looking at the section labeled Executing: special
doc, we find that RPM is doing something similar for us. It starts by making sure there is no preexisting documentation directory.
Next, RPM creates the documentation directory and copies files into it.
</P>
<P>The remainder of this example is identical to that of a package being built without a build
root being specified. However, although the output is identical, there is one crucial difference.
When the binary package is created, instead of simply using each line in the
%files list verbatim, RPM prepends the build root path first. If this weren't done, RPM would attempt to find the
files, relative to the system's root directory, and would, of course, fail. Because of the
automatic prepending of the build root, it's important to not include the build root path in any
%files list entry. Otherwise, the files would not be found by RPM, and the build would fail.
</P>
<P>Although RPM has to go through a bit of extra effort to locate the files to be packaged,
the resulting binary package is indistinguishable from the same package created without using
a build root.
</P>
<H4><A NAME="ch16_ 3">
16.1.1. Some Things to Consider
</A></H4>
<P>Once the necessary modifications have been made to support a build root, it's necessary for
the package builder to keep some issues in mind. The first is that the build root specified in
the spec file can be overridden. RPM will set the build root (and therefore, the value
of $RPM_BUILD_ROOT) to one of the following values:
</P>
<UL>
<LI> The value of
buildroot in the spec file
<LI> The value of
buildroot in an rpmrc file
<LI> The value following the
--buildroot option on the command line
</UL>
<A NAME="PAGENUM-230"><P>Page 230</P></A>
<P>Because of this, it's important that the spec file and the makefile be written in such a way
that no assumptions about the build root are made. The main issue is that the build root must
not be hard-coded anywhere. Always use the
RPM_BUILD_ROOT environment variable!
</P>
<P>Another issue to keep in mind is cleaning up after the build. Once software builds and is
packaged successfully, it's probably no longer necessary to leave the build root in place.
Therefore, it's a good idea to include the necessary commands in the spec file's
%clean section. Here's an example:
</P>
<!-- CODE SNIP //-->
<PRE>
%clean
rm -rf $RPM_BUILD_ROOT
</PRE>
<!-- END CODE SNIP //-->
<P>Since RPM executes the %clean section after the binary package has been created, it's the
perfect place to delete the build root tree. In this example, that's exactly what we're doing.
We're also doing the right thing by using
RPM_BUILD_ROOT instead of a hard-coded path.
</P>
<P>The last issue to keep in mind relates to the
%clean section we just created. At the start of
the chapter, we mentioned that it's not a good idea to define a build root of
/. The %clean section is why: If the build root were set to
/, the %clean section would blow away your root
filesystem! Keep in mind that this can bite you, even if the package's spec file doesn't specify
/ as a build root. It's possible to use the
--buildroot option to specify a dangerous build root, too:
</P>
<!-- CODE SNIP //-->
<PRE>
# rpm -ba --buildroot / cdplayer-1.0.spec
</PRE>
<!-- END CODE SNIP //-->
<P>But for all the possible hazards using build roots can pose for the careless, it's the only way
to prevent a build from disrupting the operation of certain packages on the build system. And
for the person wanting to build packages without root access, it's the first of three steps
necessary to accomplish the task. The next step is to direct RPM to build the software in a
directory other than RPM's default one.
</P>
<H3><A NAME="ch16_ 4">
16.2. Having RPM Use a Different Build Area
</A></H3>
<P>While RPM's build root requires a certain amount of spec file and makefile tweaking in
order to get it working properly, directing RPM to perform the build in a different directory is
a snap. The hardest part is to create the directories RPM will use during the build process.
</P>
<H4><A NAME="ch16_ 5">
16.2.1. Setting Up a Build Area
</A></H4>
<P>RPM's build area consists of five directories in the top level:
</P>
<UL>
<LI> The
BUILD directory is where the software is unpacked and built.
<LI> The
RPMS directory is where the newly created binary package files are written.
<LI> The
SOURCES directory contains the original sources, patches, and icon files.
<LI> The
SPECS directory contains the spec files for each package to be built.
<LI> The
SRPMS directory is where the newly created source package files are written.
</UL>
<A NAME="PAGENUM-231"><P>Page 231</P></A>
<P>The description of the RPMS directory is missing one key point. Since the binary package
files are specific to an architecture, the directory actually contains one or more subdirectories,
one for each architecture. It is in these subdirectories that RPM will write the binary package files.
</P>
<P>Let's start by creating the directories. We can even do it with one command:
</P>
<!-- CODE //-->
<PRE>
% pwd
/home/ed
% mkdir mybuild\
? mybuild/BUILD\
? mybuild/RPMS\
? mybuild/RPMS/i386\
? mybuild/SOURCES\
? mybuild/SPECS\
? mybuild/SRPMS
%
</PRE>
<!-- END CODE //-->
<P>That's all there is to it. You might have noticed that we created a subdirectory to
RPMS called i386. This is the architecture-specific subdirectory for Intel x86-based systems, which is
our sample build system.
</P>
<P>The next step in getting RPM to use a different build area is telling RPM where the new
build area is. And it's almost as easy as creating the build area itself.
</P>
<H4><A NAME="ch16_ 6">
16.2.2. Directing RPM to Use the New Build Area
</A></H4>
<P>All that's required to get RPM to start using the new build area is to define an alternate
value for topdir in an rpmrc file. For the nonroot user, this means putting the following line in a
file called .rpmrc, located in your home directory:
</P>
<!-- CODE SNIP //-->
<PRE>
topdir: <path>
</PRE>
<!-- END CODE SNIP //-->
<P>By replacing <path> with the path to the new build area's top-level directory, RPM will
attempt to use it the next time a build is performed. Using our newly created build area as
an example, we'll set topdir to /home/ed/mybuild:
</P>
<!-- CODE SNIP //-->
<PRE>
topdir: /home/ed/mybuild
</PRE>
<!-- END CODE SNIP //-->
<P>That's all there is to it. Now it's time to try a build.
</P>
<H4><A NAME="ch16_ 7">
16.2.3. Performing a Build in a New Build Area
</A></H4>
<P>In the following example, a nonroot user attempts to build the
cdplayer package in a personal build area. If the user has modified
rpmrc file entries to change the default build area, the
command used to start the build is just like the one used by a root user. Otherwise, the
--buildroot option will need to be used:
</P>
<!-- CODE SNIP //-->
<PRE>
% cd /home/ed/mybuild/SPECS
% rpm -ba --buildroot /home/ed/mybuildroot cdplayer-1.0.spec
* Package: cdplayer
</PRE>
<!-- END CODE SNIP //-->
<P><CENTER>
<a href="0225-0228.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0232-0234.html">Next</A>
</CENTER></P>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -