Files
master/chapter06/pkgmgt.html
2015-05-23 18:50:06 +08:00

253 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content=
"application/xhtml+xml; charset=utf-8" />
<title>
6.3. 管理软件包
</title>
<link rel="stylesheet" type="text/css" href="../stylesheets/lfs.css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1" />
<link rel="stylesheet" href="../stylesheets/lfs-print.css" type="text/css"
media="print" />
</head>
<body class="lfs" id="lfs-7.7-systemd">
<div class="navheader">
<h4>
Linux From Scratch - Version 7.7-systemd
</h4>
<h3>
第六章 安装基本的系统软件
</h3>
<ul>
<li class="prev">
<a accesskey="p" href="kernfs.html" title=
"准备虚拟内核文件系统">上一页</a>
<p>
准备虚拟内核文件系统
</p>
</li>
<li class="next">
<a accesskey="n" href="chroot.html" title=
"切换Chroot环境">下一页</a>
<p>
切换Chroot环境
</p>
</li>
<li class="up">
<a accesskey="u" href="chapter06.html" title=
"第六章 安装基本的系统软件">返回</a>
</li>
<li class="home">
<a accesskey="h" href="../index.html" title=
"Linux From Scratch - Version 7.7-systemd">首页</a>
</li>
</ul>
</div>
<div class="sect1" lang="en" xml:lang="en">
<h1 class="sect1">
<a id="ch-system-pkgmgt" name="ch-system-pkgmgt"></a>6.3. 管理软件包
</h1>
<p>
管理软件包是我们经常收到的要求添加到LFS手册里的需求。一个软件包管理器可以追踪安装的文件这样可以在移除或升级软件包时轻松地清理。不仅是二进制执行文件和库文件包管理器还会处理配置文件的安装。在你瞎想之前提醒一下&mdash;本节不涉及也不建议任何一个特定的包管理器。而是关于如果管理软件包的更一般的技术的综合概述。最适合你的包管理器可能就在这些技术里,或者可能是两个或更多的组合。本节还会简要提到升级软件包可能碰到的问题。
</p>
<p>
关于为什么LFS或BLFS手册里不采用任何软件包管理的一些原因
</p>
<div class="itemizedlist">
<ul>
<li class="listitem">
<p>
管理软件包偏离了本手册的主要目标&mdash;教大家Linux系统是如何构建出来的。
built.
</p>
</li>
<li class="listitem">
<p>
存在很多软件包管理的解决方案,每一个都有自己的长处和缺点。很难选择一种适合所有人的方式。
</p>
</li>
</ul>
</div>
<p>
关于软件包管理有很多资料,请访问<a class="ulink" href="http://www.linuxfromscratch.org/hints/list.html">Hints Project</a>看看是否有一个能适合你的需求。
</p>
<div class="sect2" lang="en" xml:lang="en">
<h2 class="sect2">
6.3.1. 升级问题
</h2>
<p>
软件包管理器可以在软件新版本发布后轻松升级。一般来说LFS和BLFS手册里的指令可以用来升级到新版本。下面是一些在你准备升级软件包时需要注意的事情特别是对已经开始运作的系统。
</p>
<div class="itemizedlist">
<ul>
<li class="listitem">
<p>
如果需要升级Glibc到新版本比如从glibc-2.19升级到glibc-2.20重新构建整个LFS会比较安全。虽然你<span class="emphasis"><em>也许</em></span>能够按依赖关系重新编译所有的软件包,不过我们不建议这样做。
</p>
</li>
<li class="listitem">
<p>
如果某个包含的动态库的软件包升级了而且库名字有改变那么所有动态链接到这个库的软件包都需要重新链接新的库。请注意软件包版本和库名字并不存在相关性。举个例子某个软件包foo-1.2.3安装了一个名叫<code class="filename">libfoo.so.1</code>的动态库。然后假设你把这个软件包升级到了新版本foo-1.2.4,而新版本会安装名叫<code class="filename">libfoo.so.2</code>的动态库。在这种情况下,所有动态链接到<code class="filename">libfoo.so.1</code>的软件包都需要重新编译链接到<code class="filename">libfoo.so.2</code>。注意在所有依赖软件包重新编译完成之前,请不要删除旧版的库文件。
</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<h2 class="sect2">
6.3.2. 软件包管理技术
</h2>
<p>
下面介绍一些常见的软件包管理技术。在决定用哪种包管理方式之前,先研究一下各种不同的技术,特别是了解特定体系下的不足。
</p>
<div class="sect3">
<h3 class="sect3">
6.3.2.1. 所有一切都在我脑袋里!
</h3>
<p>
是的,这也算一种软件包管理技术。有些人觉得不需要管理软件包,是因为他们非常熟悉软件包,知道每个包都安装了哪些文件。也有些用户不需要管理软件包,是因为他们会在某个软件包有更改后重建整个系统。
</p>
</div>
<div class="sect3">
<h3 class="sect3">
6.3.2.2. 在独立目录里安装
</h3>
<p>
这是一种简单的软件包管理方式不需要其他额外的软件来管理软件的安装。每一个软件包都被装到一个独立的目录里。例如软件包foo-1.1安装到目录<code class="filename">/usr/pkg/foo-1.1</code>里并创建一个软链接<code class="filename">/usr/pkg/foo</code>指向<code class="filename">/usr/pkg/foo-1.1</code>。在安装新版本foo-1.2的时候,它会被装到目录<code class="filename">/usr/pkg/foo-1.2</code>里,然后将之前的软链接替换成指向新版本软件的位置。
</p>
<p>
类似<code class="envar">PATH</code><code class="envar">LD_LIBRARY_PATH</code><code class="envar">MANPATH</code><code class="envar">INFOPATH</code><code class="envar">CPPFLAGS</code>之类的环境变量需要包含<code class="filename">/usr/pkg/foo</code>目录。在管理大量软件包时,这种方式就不可行了。
</p>
</div>
<div class="sect3">
<h3 class="sect3">
6.3.2.3. 软链接方式软件包管理
</h3>
<p>
这是前一种软件包管理技术的变种。每个软件包都和之前方式一样的安装。但不是建立目录的软链接,而是把每个文件都链接到<code class="filename">/usr</code>目录结构里。这样就不需要扩展环境变量了。尽管用户可以自己创建这些链接来自动安装还是有许多软件包管理器都采用了这种方式。几个比较流行的有Stow、Epkg、Graft和Depot。
</p>
<p>
这种安装方式需要伪装,这样软件包会认为自己被装到了<code class="filename">/usr</code>目录下,而实际上它被装到了<code class="filename">/usr/pkg</code>目录结构中。这样安装并不是一件琐碎的小事。例如假如你准备安装一个软件包libfoo-1.1。下面的指令可能不会正确地安装:
</p>
<pre class="userinput">
<kbd class="command">./configure --prefix=/usr/pkg/libfoo/1.1
make
make install</kbd>
</pre>
<p>
安装本身倒是没有问题但是可能一些依赖包不会像你期望的那样链接libfoo库。如果要编译一个链接libfoo的软件你可能会注意到它实际上链接的是<code class="filename">/usr/pkg/libfoo/1.1/lib/libfoo.so.1</code>而不是你所期望的<code class="filename">/usr/lib/libfoo.so.1</code>。正确的方式是使用<code class="envar">DESTDIR</code>策略来伪装软件包的安装过程。这种方式需要像下面这样操作:
</p>
<pre class="userinput">
<kbd class="command">./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install</kbd>
</pre>
<p>
大多数软件包支持这种方式,但也有一些例外。对于不兼容的软件包,你可能需要自己手动安装,或者直接安装到<code class="filename">/opt</code>目录下会更简单些。
</p>
</div>
<div class="sect3">
<h3 class="sect3">
6.3.2.4. 基于时间戳
</h3>
<p>
在这种方式里,每个文件在安装之前会打上时间戳。在安装完后,用一行简单的<span class="command"><strong>find</strong></span>命令加上合适的参数就可以生成在时间戳文件创建之后所安装的所有文件列表。采用这种方式的包管理器是install-log。
</p>
<p>
这种方式的优点是非常简单,但是它有两个缺陷。比如,在安装过程中,所安装文件的时间戳不是当前时间,那这些文件将不能被软件包管理器跟踪。还有,这种方式只能在一次安装一个软件包的情况下使用。如果在不同的终端里同时安装两个不同的软件包,此时的安装日志就不可靠了。
</p>
</div>
<div class="sect3">
<h3 class="sect3">
6.3.2.5. 追踪安装脚本
</h3>
<p>
在这种方式里,安装脚本所使用的命令都会被记录下来。有两种技术,一种技术是:
</p>
<p>
设定环境变量<code class="envar">LD_PRELOAD</code>指向一个在安装前预加载的库。在安装过程中,这个库会追踪软件包安装脚本里所包含的各种执行文件比如<span class="command"><strong>cp</strong></span><span class="command"><strong>install</strong></span><span class="command"><strong>mv</strong></span>以及追踪会修改文件系统的系统调用。要让这种方式有效的话所有的执行文件需要不带suid或sgid标志位动态链接。预加载这个库可能会引起安装过程中一些意外的副作用。不过建议做一些测试以保证软件包管理器不会造成破坏并且记录了所有的文件。
</p>
<p>
第二种技术是使用<span class="command"><strong>strace</strong></span>命令,它会记录下安装脚本执行过程中所有的系统调用。
</p>
</div>
<div class="sect3">
<h3 class="sect3">
6.3.2.6. 创建软件包存档
</h3>
<p>
在这种方式里,像之前的软链接软件包管理方式里所描述的那样,软件包被伪装安装到一个独立的目录树里。在安装完成后,会将已安装文件打包成一个软件包存档。然后这个存档会用来在本地机器或其他机器上安装软件包。
</p>
<p>
这种方式为商业发行版中的大多数包管理器所采用。一些例子是RPM它顺便也是<a class="ulink" href="http://refspecs.linuxfoundation.org/lsb.shtml">Linux标准规范</a>里所要求的、pkg-utils、Debian的apt、以及Gentoo的Portage系统。这个页面描述了如何在LFS系统里采用这种包管理方式<a class="ulink" href="http://www.linuxfromscratch.org/hints/downloads/files/fakeroot.txt">http://www.linuxfromscratch.org/hints/downloads/files/fakeroot.txt</a>
</p>
<p>
创建带有依赖关系的软件包存档非常复杂已经超出LFS手册范围了。
</p>
<p>
Slackware使用一个基于<span class="command"><strong>tar</strong></span>的系统来创建软件包存档。这套系统不像更复杂包管理器有意地不处理包依赖关系。关于Slackware包管理器的详细信息请参看<a class="ulink" href="http://www.slackbook.org/html/package-management.html">http://www.slackbook.org/html/package-management.html</a>
</p>
</div>
<div class="sect3">
<h3 class="sect3">
6.3.2.7. 基于用户的软件包管理
</h3>
<p>
在这种方式是LFS特有的由Matthias Benkmann所设计在网页<a class="ulink" href="http://www.linuxfromscratch.org/hints/list.html">Hints Project</a>里能找到。在这种方式里每个软件包都由一个单独的用户安装到标准的位置。属于某个软件包的文件可以通过检查用户ID轻松识别出来。关于这种方式的特性和短处非常复杂在本节里说不清楚。详细的信息请参看<a class="ulink" href="http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt">http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt</a>
</p>
</div>
</div>
<div class="sect2" lang="en" xml:lang="en">
<h2 class="sect2">
6.3.3. 在多个系统上布置LFS
</h2>
<p>
LFS系统的一个优点是没有会依赖磁盘系统里文件位置的文件。克隆一份LFS到和宿主机器相似配置的机器上简单到只要对包含根目录的LFS分区对于一个基本的LFS构建不压缩的话大概250MB使用<span class="command"><strong>tar</strong></span>命令,然后通过网络传输或光盘拷贝到新机器上解压。在这之后,还需要调整一些配置文件,包括:<code class="filename">/etc/hosts</code><code class="filename">/etc/fstab</code><code class="filename">/etc/passwd</code><code class="filename">/etc/group</code><code class="filename">/etc/shadow</code><code class="filename">/etc/ld.so.conf</code>
</p>
<p>
根据系统硬件和原始内核配置文件的差异,可能还需要重新编译一下内核。
</p>
<p>
最后,需要使用<a class="xref" href="../chapter08/grub.html" title="8.4.&nbsp;用GRUB设置引导过程">Section&nbsp;8.4,&ldquo;用GRUB设置引导过程&rdquo;</a>里所介绍的方法让新系统可引导。
</p>
</div>
</div>
<div class="navfooter">
<div class="book">
<div class="titlepage">
<div class="author">
<span class="firstname">翻译团队:<a href="http://lctt.github.io/" target="_blank">LCTT</a></span>
<span class="surname">译者/校对:<a href="http://github.com/zpl1025" target="_blank">zpl1025</a>/</span>
</div>
</div>
</div>
<ul>
<li class="prev">
<a accesskey="p" href="kernfs.html" title=
"准备虚拟内核文件系统">上一页</a>
<p>
准备虚拟内核文件系统
</p>
</li>
<li class="next">
<a accesskey="n" href="chroot.html" title=
"切换Chroot环境">下一页</a>
<p>
切换Chroot环境
</p>
</li>
<li class="up">
<a accesskey="u" href="chapter06.html" title=
"第六章 安装基本的系统软件">返回</a>
</li>
<li class="home">
<a accesskey="h" href="../index.html" title=
"Linux From Scratch - Version 7.7-systemd">首页</a>
</li>
</ul>
</div>
</body>
</html>