📄 0154-0157.html
字号:
<HTML>
<HEAD>
<TITLE>Maximum RPM (RPM):rpm -b Command Reference: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=12 //-->
<!-- PAGES=0139-0162 //-->
<!-- UNASSIGNED1 //-->
<!-- UNASSIGNED2 //-->
<P><CENTER>
<a href="0150-0153.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0158-0160.html">Next</A>
</CENTER></P>
<A NAME="PAGENUM-154"><P>Page 154</P></A>
<!-- CODE //-->
<PRE>
RPM_PACKAGE_VERSION="1.0"
RPM_PACKAGE_RELEASE="1"
set -x
umask 022
echo Executing: %prep
cd /usr/src/redhat/BUILD
cd /usr/src/redhat/BUILD
rm -rf cdplayer-1.0
gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
if [ $? -ne 0 ]; then
exit $?
fi
cd cdplayer-1.0
cd /usr/src/redhat/BUILD/cdplayer-1.0
chown -R root.root .
chmod -R a+rX,g-w,o-w .
</PRE>
<!-- END CODE //-->
<P>As you can see, this script contains the %prep section from the spec file. The script starts
by defining a number of environment variables and then leads into the
%prep section. In the spec file used in this build, the
%prep section consists of a single %setup macro. In this file, we
can see exactly how RPM expands that macro. The remaining files follow the same basic
layout—a section-defining environment variables, followed by the
commands to be executed.
</P>
<P>Note that the --test option will only create script files for each build stage, as specified in
the command line. For example, if the previous command were changed to
</P>
<!-- CODE SNIP //-->
<PRE>
# rpm -bp --test cdplayer-1.0.spec
#
</PRE>
<!-- END CODE SNIP //-->
<P>only one script file, containing the %prep commands, would be written. In any case, no
matter what RPM build command is used, the --test option can let you see exactly what is going
to happen during a build.
</P>
<H4>
12.1.12. --clean: Clean Up After Build
</H4>
<P>The --clean option can be used to ensure that the package's build
directory tree is removed at the end of a build. Although it can be used with any build stage, it doesn't always make
much sense to do so:
</P>
<!-- CODE //-->
<PRE>
# rpm -bp --clean cdplayer-1.0.spec
* Package: cdplayer
Executing: %prep
...
+ exit 0
+ echo Executing: sweep
Executing: sweep
+ cd /usr/src/redhat/BUILD
+ rm -rf cdplayer-1.0
+ exit 0
#
</PRE>
<!-- END CODE //-->
<A NAME="PAGENUM-155"><P>Page 155</P></A>
<P>In this example, we see a typical %prep section being executed. The line
+ echo Executing: sweep indicates the start of
--clean's activity. After changing directory into the build
directory, RPM issues a recursive delete on the package's top-level directory.
</P>
<P>As noted previously, this particular example doesn't make much sense. We're only
executing the %prep section, which creates the package's build tree, and using
--clean, which removes it! Using --clean with the
-bc option isn't very productive either, as the newly built software
remains in the build tree. Once again, there would be no remnants left after
--clean has done its thing.
</P>
<P>Normally, the --clean option is used once the software builds and can be packaged
successfully. It is particularly useful when more than one package is to be built, since
--clean ensures that the filesystem holding the build area will not fill up with build trees from each package.
</P>
<P>Note also that the --clean option only removes the files that reside in the software's build
tree. If there are any files that the build creates outside this hierarchy, it will be necessary to write
a script for the spec file's %clean section.
</P>
<H4>
12.1.13. --buildroot <path>: Execute
%install Using <path> As the Root
</H4>
<P>The --buildroot option can make two difficult situations much easier:
</P>
<UL>
<LI> Performing a build without affecting the build system
<LI> Allowing non-root users to build packages
</UL>
<P>Let's study the first situation in a bit more detail. Say, for example, that
sendmail is to be packaged. In the course of creating a
sendmail package, the software must be installed. This
would mean that critical sendmail files, such as
sendmail.cf and aliases, would be overwritten.
Mail handling on the build system would almost certainly be disrupted.
</P>
<P>In the second case, it's certainly possible to set permissions such that non-root users can
install software, but highly unlikely that any system administrator worth his salt would do so.
What can be done to make these situations more tenable?
</P>
<P>The --buildroot option is used to instruct RPM to use a
directory other than / as a build root. The term build
root is a bit misleading, in that the build root is not the root directory
under which the software is built. Rather, it is the root directory for the install phase of the
build. When a build root is not specified, the software being packaged is installed relative to the
build system's root directory /.
</P>
<P>However, it's not enough to just specify a build root on the command line. The spec file
for the package must be set up to support a build root. If you don't make the necessary
changes, this is what you'll see:
</P>
<A NAME="PAGENUM-156"><P>Page 156</P></A>
<!-- CODE SNIP //-->
<PRE>
# rpm -ba --buildroot /tmp/foo cdplayer-1.0.spec
Package can not do build prefixes
Build failed.
#
</PRE>
<!-- END CODE SNIP //-->
<P>Chapter 16, "Making a Package That Can Build Anywhere," has complete instructions on
the modifications necessary to configure a package to use an alternate build root,
as well as methods to permit users to build packages without root access. Assuming that the necessary
modifications have been made, here is what the build would look like:
</P>
<!-- CODE //-->
<PRE>
# rpm -ba --buildroot /tmp/foonly 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/foonly install
install -m 755 -o 0 -g 0 -d /tmp/foonly/usr/local/bin/
install -m 755 -o 0 -g 0 cdp /tmp/foonly/usr/local/bin/cdp
rm -f /tmp/foonly/usr/local/bin/cdplay
ln -s /tmp/foonly/usr/local/bin/cdp /tmp/foonly/usr/local/bin/cdplay
install -m 755 -o 0 -g 0 -d /tmp/foonly/usr/local/man/man1/
install -m 755 -o 0 -g 0 cdp.1 /tmp/foonly/usr/local/man/man1/cdp.1
+ exit 0
Executing: special doc
+ cd /usr/src/redhat/BUILD
+ cd cdplayer-1.0
+ DOCDIR=/tmp/foonly//usr/doc/cdplayer-1.0-1
+ rm -rf /tmp/foonly//usr/doc/cdplayer-1.0-1
+ mkdir -p /tmp/foonly//usr/doc/cdplayer-1.0-1
+ cp -ar README /tmp/foonly//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 //-->
<A NAME="PAGENUM-157"><P>Page 157</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>As the somewhat edited output shows, the %prep,
%build, and %install sections are executed in RPM's normal build directory. However, the
--buildroot option comes into play when the make
install is done. As we can see, the ROOT variable is set to
/tmp/foonly, which was the value following
--buildroot on the command line. From that point on, we can see that
make substituted the new build root value during the install phase.
</P>
<P>The build root is also used when documentation files are installed. The documentation
directory cdplayer-1.0-1 is created in
/tmp/foonly/usr/doc, and the README file is placed in it.
</P>
<P>The only remaining difference that results from using
--buildroot is that the files to be included in the binary
package are not located relative to the build system's root directory.
Instead, they are located relative to the build root
/tmp/foonly. The resulting binary and source package files are functionally equivalent to packages built without the use of
--buildroot.
</P>
<B>
12.1.13.1. Using --buildroot Can Bite You!
</B>
<P>Although the --buildroot option can solve some problems, using a build root can actually
be dangerous. How? Consider the following situation:
</P>
<UL>
<LI> A spec file is configured to have a build root of
/tmp/blather, for instance.
<LI> In the %prep section (or the %clean section; it doesn't matter—the end result is
the same), there is an rm -rf $RPM BUILD ROOT command to clean out any old
installed software.
<LI> You decide to build
the software so that it installs relative to your system's
root directory, so you enter the following command:
rpm -ba --buildroot / foo.spec.
</UL>
<P>The end result? Since specifying / as the build root sets
$RPM BUILD ROOT to /, that innocuous little rm -rf $RPM BUILD
ROOT turns into rm -rf /! A recursive delete, starting at your
system's root directory, might not be a total disaster if you catch it quickly, but in either case, you'll
be testing your ability to restore from backup (er, you do have backups, don't you?).
</P>
<P>The moral of this story is to be very careful when using
--buildroot. A good rule of thumb is to always specify a unique build root. For example, instead of specifying
/tmp as a build root (and possibly losing your system's directory for holding temporary files), use the path
/tmp/mypackage, where the directory mypackage is used only by the package you're building.
</P>
<P><CENTER>
<a href="0150-0153.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0158-0160.html">Next</A>
</CENTER></P>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -