分页: 1 / 1

《OpenBSD 4.6 FAQ 中文版 第十五章.OpenBSD的packages和ports系统》

发表于 : 2010-01-21 10:47
leo
15 - OpenBSD的packages和ports系统
目录
15.1 - 介绍
15.2 - Package管理
15.2.1 - 它是如何工作的?
15.2.2 - 让事情变简单: PKG_PATH
15.2.3 - 寻找package
15.2.4 - 安装新package
15.2.5 - 列出已经安装的package
15.2.6 - 更新安装的package
15.2.7 - 删除已经安装的package
15.2.8 - 不完整的package的安装或删除
15.3 - 使用ports
15.3.1 - 它是怎样工作的?
15.3.2 - 获取ports树
15.3.3 - 配置ports系统
15.3.4 - 搜索ports 树
15.3.5 - 简易的安装:一个简单的例子
15.3.6 - 构建完成后进行清理
15.3.7 - 卸载一个port的package
15.3.8 - 使用各种类型的port及subpackages
15.4 - FAQ
15.4.1 - 我看见大量错误信息, 看起来这个port就不能工作
15.4.2 - 怎么没有我最喜欢软件的最新版本!
15.4.3 - 为什么没有我最喜欢的软件的package?
15.4.4 - 为什么没有我最喜欢的软件的port?
15.4.5 - 为什么我最喜欢的软件没有包含在基本系统内?
15.4.6 - 我应该用哪个: packages 还是 ports?
15.4.7 - 怎样将ports调整成最佳性能?
15.4.8 - 我几周前提交了一个新port(或者一个更新), 为什么现在还没有审核?
15.5 - 报告问题
15.6 - 帮助我们

--------------------------------------------------------------------------------

15.1 - 介绍
有大量可能被人需要运行于OpenBSD系统上的第三方程序。要让这些软件容易安装和管理并遵循OpenBSD的策略和目的, 这些第三方软件被移植到OpenBSD上, 这种移植的努力包含了很多不同的工作, 例如:让软件使用标准的OpenBSD目录布局(例如:配置文件放到/etc目录下), 符合OpenBSD的共享库规范, 尽可能的让软件更安全等。

移植的努力是以让软件成为准备安装的二进制packages为最终结果, 使用packages系统的目的是清楚哪些软件被安装了, 以便软件可以在任何时间轻松地被更新或删除。这样可以确保没有任何不需要的文件被保留下来, 用户可以保证他们的系统是清洁的, packages系统也帮助用户确保不会因为误操作删除有用的数据而使程序丧失功能。另一个好处是用户很少需要从源代码编译程序, 因为packages已经是被编译过的并可以随时使用在一个OpenBSD系统上。在几分钟内, 可以下载大量的packages并安装到系统上, 一切全步入正轨。

packages和ports树并非完全像openBSD系统一样通过了严格的安全认证, 虽然我们力图尽可能地提高packages的质量, 但因为人力资源的不足, 我们仍不能完全确保这些packages具有与系统一样的性能和安全性。

15.2 - Package管理
15.2.1 - 它是如何工作的?
package是一些最常用的第三方软件经过预编译产生的二进制文件。用户可以国通一些工具对package进行轻松的管理, 这些工具通常也被称为pkg* tools:

pkg_add(1) - 一个用来安装和升级package的工具。
pkg_delete(1) - 一个用来删除已经安装的package的工具。
pkg_info(1) - 一个用来显示package信息的工具。
pkg_create(1) - 一个用来产生package的工具。
为了正常运行, 一个程序X可能会需要系统安装程序Y和Z, 程序Y和Z称为程序X的依赖包, 依次, Y可能需要其他的程序P和Q, 而Z可能需要程序R, 这样就形成了一个完整的依赖关系树。

package看起来像简单的.tgz压缩包, 基本上就是这样, 但是他们有一个至关紧要的区别:package里有一些额外的包装信息。这些包装信息可以被pkg_add(1)用于不同的目的:

不同的检查:是否这些package已经被安装过了?是否与其他的已经安装的package或文件名冲突?
依赖包如果尚未在系统内安装, pkg_add(1)将会在安装package之前先自动获取并安装它的依赖包。
所有package的有关信息全被储存在一个文献中心, 默认情况下在/var/db/pkg/目录, 除其他功能外, 尤其可以防止依赖包在package被删除前就先被删除。这可以确保软件不会被粗心的用户意外地破坏。
15.2.2 - 让事情变简单: PKG_PATH
您可以用PKG_PATH环境变量让事情真正变的简单。把它指向您喜欢的地方, 然后pkg_add(1)将会在那里自动搜寻您指定的任何package, 而且可以自动获取并安装所需的依赖包。一个可能获得package的位置清单在下一小节给出。

例 1: 从您的CDROM上获取, 假设您已经把它挂载到了/mnt/cdrom目录上

代码: 全选

$ export PKG_PATH=/mnt/cdrom/4.5/packages/`machine -a`/


例 2: 从附近的FTP mirror获取。

代码: 全选

$ export PKG_PATH=ftp://your.ftp.mirror/pub/OpenBSD/4.5/packages/`machine -a`/


(译者注:注意上面的命令里machine -a是用"` "符号(左上角的波浪号"~"那个键, 但可不是"~"符号)圈注的而不是引号"’"或"~", 还有就是一定要注意这里的OpenBSD的大小写, 如果您输错了, pkg_add时将会找不到该文件或目录。如果还找不到,用你的平台名称,如i386等直接替代,注意这时是实际的目录名称,就不用加这个"`"号了,这样写export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.5/packages/i386/)

通常的一个好办法是在~/.profile文件里加入类似上面例子中的一行。因为您可以以冒号分开不同的PATH参数从而指定多个不同地点。在OpenBSD 4.4以前, PKG_PATH参数后的任何一个path全需要用斜杠(/)结束。这样即使您用":"分开各个URL地址pkg_add也可以区分它们。如果第一个输入的PKG_PATH地址无效, pkg_add会尝试使用下一个地址, 直到找到package。如果所有地址全失败, 则会产生一个错误信息。

注意上面那行使用的machine(1), 这里会自动替换成您自己的"应用平台"(译者注:也就是不用输入i386或amd64……, 服务器会自动识别,不过我没有成功过,我还是直接用平台名称), 一般情况下是您的平台名称, 但非总是这样, 当然了如果您使用的是快照版, 把这里的"4.5"替换成"snapshots"。

15.2.3 - 寻找package
在多数平台上提供了数量众多的预编译package, 您只需到下列几个地方查找您的package:
官方发行的CD-ROMs中的一张CD盘, 这些CD-ROMs 上只包含了常用平台的package, 它们是可以自由再发行的。
在 FTP mirror servers的 /pub/OpenBSD/4.5/packages目录。 在FTP上不同的构架提供了不同的package。
OpenBSD网站上开列出的package清单
Packages for OpenBSD 4.5
Packages for OpenBSD 4.4
Packages for OpenBSD 4.3
Packages for OpenBSD 4.2
如果您的计算机上有ports树, 您可以用 搜寻ports树的方法找到您所需要的package。

您会注意到一些特定的package提供几个不同的变种, 严格意义上应该称他们为不同类型的版本。其它是同一应用的不同小块, 这些单独的小块可能可以分别安装, 它们被称为subpackage, 这在应用类型和subpackage说的更详细, 但是类型版本基本上意味着它们配置了不同的选项。当前许多package有不同类型的版本, 例如:有些类型支持的数据库不同, 有些类型仅支持非X系统, 或有些类型在网络上增加了对SSL和IPv6的支持。每个package的类型版本在其名字后面有一个不同的后缀, 更多关于package的命名请参考packages-specs(7)。

注意: FTP上并不能完全提供可能的package!一些package不能运行在所有的平台上, 一些package因为使用许可的原因不能通过FTP或CD-ROM进行分发, 可能还有很多组合的package可以运行在OpenBSD上, 但是因为OpenBSD开发人力资源不足, 无法加入ports或packages树中, 如果您需要的组合package没有提供, 您就不得不自己动手从源码构建port, 更多的关于信息请参阅ports小节的这篇文档应用类型和subpackage.

15.2.4 - 安装新package
安装package使用工具 pkg_add(1) 。如果您设置了 PKG_PATH 环境变量, 完成了准备工作。您只需用pkg_add(1)加上package的名称就可以, 看下面的简单例子:

代码: 全选

$ sudo pkg_add -v screen-4.0.3p1
parsing screen-4.0.3p1
installed /etc/screenrc from /usr/local/share/examples/screen/screenrc | 71%
screen-4.0.3p1: complete 


在这个例子中-v 标签被用来让安装程序提供更多的信息, 这个选项有利于进行调试工作, 并且用在这里我们可以方便地洞察pkg_add(1)工具正在干一些什么工作。注意上面显示的提示信息etc/screenrc, 设定更多的–v 参数将得到更为详尽的输出信息。

(译者注:例如我们安装vsftpd-2.0.5.tgzpackage, 下面给出了三种命令, 1.不带-v, 2.带一个-v, 3.带两个-v

代码: 全选

#pkg_add vsftpd-2.0.5 这个只显示安装过程进度
#pkg_add –v vsftpd-2.0.5 同上, 并增加了发现的库文件和配置文件位置
#pkg_add –v –v vsftpd-2.0.5 同上, 并增加了文件解压的位置和产生的新目录
总之, -v参数越多, 屏幕输出的信息越多。我在这里试过10个–v标签, 但发现和两个没有区别, 读者有兴趣自己试试看, 也许其他package会略有差异。)

使用pkg_add(1)的交互模式
从OpenBSD 3.9开始pkg_add(1)提供了交互模式, 交互模式可以通过-i 参数进行调用, 使用-i参数后在pkg_add将在自己不能做出决定时会向您提出问题。例如, 您不知道package具体的版本号, 您可以这样:

代码: 全选

$ sudo pkg_add -i screen
Ambiguous: screen could be screen-4.0.3p1 screen-4.0.3p1-shm screen-4.0.3p1-static
Choose one package
0: <None>
1: screen-4.0.3p1
2: screen-4.0.3p1-shm
3: screen-4.0.3p1-static
Your choice: 1
screen-4.0.3p1: complete 


对一些package来说, 安装过程提供了一些额外的关于配置和在OpenBSD上运行的信息, 因为这些信息很重要, 所以您能否看见这些信息取决于您是否使用了–v参数。请参考下面的例子:

代码: 全选

$ sudo pkg_add ghostscript-fonts-8.11
ghostscript-fonts-8.11: complete
You may wish to update your font path for /usr/local/share/ghostscript/fonts
--- ghostscript-fonts-8.11 -------------------
To install these fonts for X11, just make sure that the fontpath
lists the 75dpi or 100dpi bitmap fonts before the ghostscript fonts, \
and make sure you have the string ":unscaled" appended to the bitmap
font's fontpath. This way, the bitmap fonts will be used if they
match, and the Type 1 versions will be used if the font needs to be
scaled. Below is the relevant section from a typical xorg.conf file.
FontPath "/usr/X11R6/lib/X11/fonts/misc/"
FontPath "/usr/X11R6/lib/X11/fonts/75dpi/:unscaled"
FontPath "/usr/X11R6/lib/X11/fonts/100dpi/:unscaled"
FontPath "/usr/local/lib/X11/fonts/ghostscript/"
FontPath "/usr/X11R6/lib/X11/fonts/Type1/" 

现在我们继续看一个有依赖包的package安装过程:

代码: 全选

$ sudo pkg_add -v tin-1.8.2p0
parsing tin-1.8.2p0
Dependencies for tin-1.6.2 resolve to: gettext-0.14.6, libutf8-0.8, pcre-6.4p1, \
libiconv-1.9.2p3 (todo: libiconv-1.9.2p3, gettext-0.14.6, pcre-6.4p1, \
libutf8-0.8)
tin-1.8.2p0:parsing libiconv-1.9.2p3
tin-1.8.2p0:libiconv-1.9.2p3: complete
tin-1.8.2p0:parsing gettext-0.14.6
Dependencies for gettext-0.14.6 resolve to: expat-2.0.0, libiconv-1.9.2p3 \
(todo: expat-2.0.0)
tin-1.8.2p0:parsing expat-2.0.0
tin-1.8.2p0:expat-2.0.0: complete
tin-1.8.2p0:gettext-0.14.6: complete
tin-1.8.2p0:parsing pcre-6.4p1
tin-1.8.2p0:pcre-6.4p1: complete
tin-1.8.2p0:parsing libutf8-0.8
tin-1.8.2p0:libutf8-0.8: complete
tin-1.8.2p0: complete 

这里再强调一下, -v 标签可以让您看见安装程序正在做什么, 我们研究一下上面的信息会发现依赖包被发现并在该package之前安装。您在信息中部可以发现gettext package已经被安装了, 它依赖于libiconvpackage, 所以在gettextpackage安装前, pkg_add检查gettext的安装信息并校验是否libiconv package已经被安装了。
这行可以包括多个package的名字, package会随着它的依赖包一并安装。

如果您因为某些原因不想用PKG_PATH环境变量, 您也可以在命令行上指定package的具体位置, 这个具体位置可以是本地路径也可以是FTP, HTTP或SCP上的路径, 我们下面的这个例子是通过FTP安装的:

代码: 全选

$ sudo pkg_add [URL]ftp://ftp.openbsd.org/pub/OpenBSD/4.5/[/URL] \
packages/`machine -a`/screen-4.0.3p1.tgz
screen-4.0.3p1: complete 


这个例子中我们没有使用-v标签, 所以安装过程仅显示必要的信息。还有我们在这里加上了package的后缀名.tgz, 您也像前面的例子那样不加后缀, 因为pkg_add工具会为您自动添加。

注意: 并非所有的平台全提供了同样的package, 某些ports可能并不适合某些平台, 并且一些平台的性能限制了从其他平台为其创建的package的个数。

为了安全起见, 如果您正在重新安装一个已安装并删除过的package(或它的老版本), pkg_add(1)不会用已经更改(更新)的配置文件覆盖老的配置文件, 而是通知您(然而仅在您使用-v参数时):

代码: 全选

$ sudo pkg_add -v screen-4.0.3p1
parsing screen-4.0.3p1
The existing file /etc/screenrc has NOT been changed** | 71%
It does NOT match the sample file /usr/local/share/examples/screen/screenrc
You may wish to update it manually
screen-4.0.3p1: complete 

有些时候您可能会遇见一个错误信息, 像下面这个例子:

代码: 全选

$ sudo pkg_add xv-3.10ap4
xv-3.10ap4:jpeg-6bp3: complete
xv-3.10ap4:png-1.2.14p0: complete
xv-3.10ap4:tiff-3.8.2p0: complete
Can't install xv-3.10ap4: lib not found X11.9.0
Even by looking in the dependency tree:
tiff-3.8.2p0, jpeg-6bp3, png-1.2.14p0
Maybe it's in a dependent package, but not tagged with @lib ?
(check with pkg_info -K -L)
If you are still running 3.6 packages, update them

这个例子是pkg_add安装依赖包时突然停止安装xvpackage, 这是从OpenBSD3.7开始提供的另一个安全防范措施, package信息包含了所需的系统或第三方的库文件, 如果缺少一个库文件, package将停止安装, 因为即使安装完成该软件也不能提供所需功能。
为了解决这个冲突, 您必须手动寻找所需的库文件, 检查下面几项:

您可能已经安装了老版本的package:系统内提供的是老的库文件, 这种情况您需要升级这些package。
您的系统可能不完善:您在创建系统时没有安装包含该库文件的所需的组件, 您仅需要 添加所需系统组件 。
您的系统已经不维护了:您仅有所需库文件的老版本, 从安装介质启动(详参FAQ 4), 选择(U)pgrade全部升级您的系统。
15.2.5 - 列出已经安装的package
您可以通过 pkg_info(1)工具列出已经安装的package。

代码: 全选

$ pkg_info
aterm-0.4.2p1 color vt102 terminal emulator with transparency support
bzip2-1.0.4 block-sorting file compressor, unencumbered
expat-2.0.0 XML 1.0 parser written in C
fluxbox-0.9.15.1p0 window manager based on the original Blackbox code
gettext-0.14.6 GNU gettext
imlib2-1.3.0 image manipulation library
jpeg-6bp3 IJG's JPEG compression utilities
libiconv-1.9.2p3 character set conversion library
libltdl-1.5.22p1 GNU libtool system independent dlopen wrapper
libungif-4.1.4p0 tools and library routines for working with GIF images
libutf8-0.8 provides UTF-8 locale support
mutt-1.4.2.2i tty-based e-mail client
pcre-6.4p1 perl-compatible regular expression library
png-1.2.14p0 library for manipulating PNG images
screen-4.0.3p1 multi-screen window manager
tcsh-6.14.00p1 extended C-shell with many useful features
tiff-3.8.2p0 tools and library routines for working with TIFF images
tin-1.8.2p0 threaded NNTP and spool based UseNet newsreader 

当给出一个已安装的package名字时(或给出一个package所在位置), pkg_info(1)会提供此package更为详尽的信息。

15.2.6 - 更新安装的package
从OpenBSD 3.7开始pkg_add(1)已经可以使用-r参数(= 取代)更新package了, OpenBSD3.8为pkg_add(1)提供了-u 参数, 一直到OpenBSD3.9才提供了真正意义上的package升级机制。
我们假设您在从OpenBSD4.4升级到OpenBSD.FAQ之前安装了一个老版本的unzippackage, 现在您可以轻松地升级到新的4.5版本的package:

代码: 全选

$ sudo pkg_add -u unzip
unzip-5.52p0 (extracting): complete
unzip-5.52 (deleting): complete
unzip-5.52p0 (installing): complete
Clean shared items: complete 


如果一个package有依赖包(也就是安装该package所需的软件), 它们也会被核查并更新, 如果在pkg_add –u后面不添加任何package名称, 那么pkg_add将更新所有系统已经安装的package。

注意: -u 参数依赖PKG_PATH 环境变量, 如果您没有设置它, pkg_add(1)将无法找到更新的package 。

从OpenBSD 4.2开始允许为PKG_PATH提供多个地址, 但是这不意味着PKG_PATH会尝试所有的地址, 它在找到第一个合适的地址后就不会再尝试其余的地址。

如果您有一个老的package的配置文件, 并且您修改过它, 那么在升级时这个文件不会被改动, 不管怎样您可以通过使用-c参数让pkg_add(1)用新的默认配置文件强制覆盖它。.

15.2.7 - 删除已经安装的package
删除一个package只需要将pkg_info(1) (参看上一小节 列出已经安装的package )列出的package名称放到pkg_delete(1) 工具后面就可以删除这个package了。下面的例子中我们将删除screenpackage。注意, 有时您删除一个package时, 有一些额外的项目pkg_delete工具并不会为您删除它们, 您需要使用-v参数以便获得更多的输出信息。

代码: 全选

$ sudo pkg_delete screen
screen-4.0.3p1: complete
Clean shared items: complete 


注意: 通常您不需要指定package的版本号和类型名称, 因为pkg_delete会自己查找出package的全名, 只有在是使用简略名称pkg_delete无法判断哪一个是您需要删除的package时您才需要输入package的全名。

为了安全起见, 如果您已经修改了package中的配置文件, pkg_delete将不会删除这些配置文件, 而是提醒您, 就像下面的例子:

代码: 全选

$ sudo pkg_delete screen
screen-4.0.3p1: complete
Clean shared items: complete 
--- screen-4.0.3p1 -------------------
You should also remove /etc/screenrc (which was modified) 


注意, 这里您不必输入软件版本, 另外信息显示您修改了某些文件, 所以pkg_delete不会删除它们, 您需要手工进行删除。

如果您想在删除package的同时自动删除这些修改过的配置文件, 您只需要加上-c 参数就可以了。

15.2.8 - 不完整的package的安装或删除
在某些偶然的情况下, 您没有完整的添加或删除package, 可能因为与其它文件冲突, 没有完全安装的package通常会在package的名称前加上"partial-"前缀, 例如, 这样的情况可能发生在安装过程中您使用CTRL+C中断了安装:

代码: 全选

$ sudo pkg_add screen-4.0.3p1
screen-4.0.3p1: complete 7%
Adjusting md5 for /usr/local/info/screen.info-3 from 49fb3fe1cc3a3b0057518459811b6dac to 3b9c7811244fb9f8d83bb27d3a0f60d8
/usr/sbin/pkg_add: Installation of screen-4.0.3p1 failed , partial installation recorded as partial-screen-4.0.3p1 


对您来说删除未完全安装的package并修正导致安装失败的因素永远是最好的方案, 当您未完全安装package时通常会有一个提示告诉您您的系统并不干净, 但是也有可能是从源码安装时与其它软件混在一起了。

15.3 - 使用ports
如前所述, package是通过port树编译的。这一小节我们将解释ports树是如何工作的, 什么时候您应该使用ports树, 以及如何使用它们。
重要提示: ports树是只适合高级用户。我们鼓励每个人都使用预编译的二进制package(packages)。不要在邮件列表上提一些初级问题, 诸如:"我怎样才能让ports树上的软件运行?"。如果您有关于ports树的问题, 我们先假设您已经阅读了用户手册和FAQ, 也就是意味着您已经可以自己解决这些问题了。

15.3.1 - 它是怎样工作的?
Ports树是一个最初借用FreeBSD的概念, 是一组Makefiles的集合。Makefiles是用来控制每个第三方软件
从哪里及怎样获得源代码,
还需要哪些依赖包,
怎样修改源代码(如果必须),
怎样配置和构建它,
怎样测试它(可选),
怎样安装它。
除了Makefile外, 每个port至少还包含下列内容:

一个 PLIST 或 打包清单, 它包含了从源码构建应用程序并产生封装package的指令,
一个 DESCR 或 一份应用程序的描述,
一个 distfile, 包含了发行文件的校验和大小。
所有这些信息全保留在的目录/usr/ports结构下, 这个目录包含了三个特殊的子目录:

distfiles/ - 这个目录用在存放ports系统下载的软件发行组件。
infrastructure/ - 这是ports的主要目录, 包含了所有的脚本和makefiles。
packages/ - 这个目录存放所有由ports系统构建的二进制package。
其他的子目录分属不同的应用种类, 也就是当前ports的子目录。复杂的ports也许会有更深的目录层次, 例如, 它们可能有一个核心部分和一系列扩展, 或者一个稳定版和快照版。每个port目录都包含一个包含了打包清单和描述文件的pkg 子目录, 也可能有patches或files子目录, 它们分别用来存放补丁文件和附加的文件 。
当用户在某个port的子目录里运行make(1)时系统会递归地查询(遍历)它的依赖关系树, 检查这个port的依赖包是否已经被安装了, 并构建和安装任何缺少的依赖包, 然后构建用户所需的port。所有的构建过程全在该port产生的工作目录中进行, 这个目录可能是该port主目录下的任何子目录, 这个目录可能是前缀为"w-"的目录, 或者如果您已经设定了WRKOBJDIR变量(请参看配置ports系统), 这个目录就在WRKOBJDIR目录的子目录中。

注意: ports永远不会直接安装在您的系统上!它使用一个虚拟的安装目录, 只是把所有安装需要的文件全被放在这个目录里, 然后将它们打包成一个package文件(二进制package, 就像我们前面提到的那样, 这个package文件储存在这个ports的packages子目录里)。安装一个port的真正含义就是:产生一个二进制package, 然后安装这个package!

有关ports系统更多的信息您可以在下面的用户手册上找到:

ports(7) - 描述了不同的port安装过程(根据不同的make目标), 各类型版本和子文件包的使用, 及一些其他选项。
bsd.port.mk(5) -更深入阐述了所有make过程, 变量及虚拟(安装目录)框架等。
15.3.2 - 获取ports树
继续之前, 您必须阅读关于不要混淆不同类型的 OpenBSD 系统和 ports 树。一旦您确定使用什么类型的ports, 您可以从相应的途径获得它, 下表列出了不同ports树的获取途径。"x"表示有效的获取途径;"-"表示无效的途径。

代码: 全选

Source Form Flavor 
-release -stable snapshots -current 
CD-ROM .tar.gz x - - - 
FTP mirrors .tar.gz x - x - 
AnonCVS cvs checkout x x - x 

在CD-ROM和FTP镜像上查找ports.tar.gz这个文件, 您需要在/usr目录下untar这个文件, 会产生一个/usr/ports目录及其子目录。例如:

代码: 全选

$ cd /tmp
$ ftp [URL]ftp://ftp.openbsd.org/pub/OpenBSD/4.5/ports.tar.gz[/URL]
$ cd /usr
$ sudo tar xzf /tmp/ports.tar.gz

FTP镜像上每天都从当前版的ports树上生成快照版的ports树。您可以在/pub/OpenBSD/snapshots/目录下找到快照版的ports树(ports.tar.gz文件), 注意您需要安装一个快照版的OpenBSD系统才可以使用它。一定要确保您的ports树和您的OpenBSD系统同步!

更多关于通过AnonCVS 获得ports树的方法请参阅AnonCVS page , 它上面包含了一个有效的服务器列表及一些实例。

15.3.3 - 配置ports系统
说明: 这一小节介绍了从ports系统构建应用软件的全局设置。您可以跳过这一节, 但在后面的例子中要求您以root身份执行很多make操作。

因为OpenBSD项目并无足够的人手仔细审核所有ports树中的软件, 所以您自己在配置ports系统时可以做一些安全防护措施。Ports体系既允许普通用户构建软件, 也允许他们执行一些root权限的步骤。如虚拟目录和安装package, 不管怎样说, 因为您使用port时拥有root的权限, 但是即使您编译, 安装的的是一个恶意软件, ports系统并不能发现和保护您。

您可以设置 sudo(8) 使ports系统具有构建和安装时所需的超级用户权限, 您只需让/etc/mk.conf文件包含下面这行:

代码: 全选

SUDO=/usr/bin/sudo

您可以修改potrs树的所有权以便您可以用一般用户的身份在那里进行写操作。这时这个一般用户已经被加入到了wsrc组, 并且允许对下面子目录的进行写操作。

代码: 全选

# chgrp -R wsrc /usr/ports
# find /usr/ports -type d -exec chmod g+w {} \;


您可以通过在/etc/mk.conf 中加入如下的一行来让ports树使用 systrace(1):

代码: 全选

USE_SYSTRACE=Yes


这行的目的是强制构建过程仅在允许的目录中进行, 并禁止在非法的地方写入数据。因此极大程度上减小了对系统的危害性, 注意, 使用systrace(1)会增加20%的程序构建时间。
单独隔离出在构建过程中需要进行写操作的目录就可以让整个ports目录在使用过程中处于一个只读的状态:

WRKOBJDIR 变量指定哪个目录作为ports的工作目录。
DISTDIR 变量指定哪个目录用来存放程序的发行文件。
PACKAGE_REPOSITORY变量指定发行文件生成的package的存放位置。
例如, 您可以将下面几行加入/etc/mk.conf

代码: 全选

WRKOBJDIR=/usr/obj/ports
DISTDIR=/usr/distfiles
PACKAGE_REPOSITORY=/usr/packages


如果您愿意, 您也可以将这些目录的所有人设定成您的本地用户和组。这样ports系统可以以一般用户身份创建子目录。
15.3.4 - 搜索 ports 树
一旦您的系统内有了ports树, 您可以方便地查找程序。只需使用make search 加上程序关键字"key"就可以了, 见下例:

代码: 全选

$ cd /usr/ports
$ make search key=rsnapshot
Port: rsnapshot-1.2.9
Path: net/rsnapshot
Info: remote filesystem snapshot utility
Maint: Sigfred Haversen
Index: net
L-deps: 
B-deps: :net/rsync
R-deps: :net/rsync
Archs: any 


搜索的结果较详细地显示了port的信息:port的名称, port所在位置, port的简单描述, port涉及的关键字, library/build/runtime的依赖体及port可应用构架。
这个机制还是很基本的, 只是在ports的检索文件上运行awk(1)。从OpenBSD 4.0开始有了一个叫"sqlports"的port, 可以使用SQL进行细致的检索, 它是一个SQL的小型数据库, 只是主要用来产生port体系的各种数据格式。Sqlports包含了用来生成ports数据库的脚本, 它可以提供不同格式的ports数据库。

您只需pkg_add(1)加载sqlportspackage, 这里, 我们先启动sqlite3:

代码: 全选

$ sqlite3 /usr/local/share/sqlports
SQLite version 3.3.12
Enter ".help" for instructions
sqlite> SELECT FULLPKGNAME, COMMENT FROM Ports WHERE COMMENT LIKE '%statistics%';
Guppi-0.40.3p1|GNOME-based plot program with statistics capabilities
mailgraph-1.12|a RRDtool frontend for Postfix statistics
R-2.4.1|clone of S, a powerful math/statistics/graphics language
py-probstat-0.912p0|probability and statistics utilities for Python
darkstat-3.0.540p1|network statistics gatherer with graphs
pfstat-2.2p0|packet filter statistics visualization
tcpstat-1.4|report network interface statistics
wmwave-0.4p2|Window Maker dockapp to display wavelan statistics
diffstat-1.43p0|accumulates and displays statistics from a diff file
sqlite> 

上面仅是一个基本的搜索, 如果您使用SQL可以搜索到您想找的任何东西, 包括依赖体, 配置文件, 共享库等。
15.3.5 - 简易的安装: 一个简单的例子
为了便于读者理解, 我们安装一个简单的port——rsnapshot, 这个应用程序有一个依赖包是rsync。

代码: 全选

$ cd /usr/ports/net/rsnapshot
$ make install
===> Checking files for rsnapshot-1.2.9
>> rsnapshot-1.2.9.tar.gz doesn't seem to exist on this system.
>> Fetch [URL]http://www.rsnapshot.org/downloads/rsnapshot-1.2.9.tar.gz[/URL].
100% |**************************************************| 173 KB 00:02
>> Size matches for /usr/ports/distfiles/rsnapshot-1.2.9.tar.gz
>> Checksum OK for rsnapshot-1.2.9.tar.gz. (sha1)
===> rsnapshot-1.2.9 depends on: rsync-2.6.9 - not found
===> Verifying install for rsync-2.6.9 in net/rsync
===> Checking files for rsync-2.6.9
>> rsync-2.6.9.tar.gz doesn't seem to exist on this system.
>> Fetch [URL]ftp://ftp.samba.org/pub/rsync/old-versions/rsync-2.6.9.tar.gz[/URL].
100% |**************************************************| 792 KB 00:31
>> Size matches for /usr/ports/distfiles/rsync-2.6.9.tar.gz
>> Checksum OK for rsync-2.6.9.tar.gz. (sha1)
===> Verifying specs: c
===> found c.40.3
===> Extracting for rsync-2.6.9
===> Patching for rsync-2.6.9
===> Configuring for rsync-2.6.9
[...snip...]
===> Building for rsync-2.6.9
[...snip...]
===> Faking installation for rsync-2.6.9
[...snip...]
===> Building package for rsync-2.6.9
Link to /usr/ports/packages/i386/ftp/rsync-2.6.9.tgz
Link to /usr/ports/packages/i386/cdrom/rsync-2.6.9.tgz
===> Installing rsync-2.6.9 from /usr/ports/packages/i386/all/rsync-2.6.9.tgz
rsync-2.6.9: complete
===> Returning to build of rsnapshot-1.2.9
===> rsnapshot-1.2.9 depends on: rsync-2.6.9 - found
===> Extracting for rsnapshot-1.2.9
===> Patching for rsnapshot-1.2.9
===> Configuring for rsnapshot-1.2.9
[...snip...]
===> Building for rsnapshot-1.2.9
[...snip...]
===> Faking installation for rsnapshot-1.2.9
[...snip...]
===> Building package for rsnapshot-1.2.9
Link to /usr/ports/packages/i386/ftp/rsnapshot-1.2.9.tgz
Link to /usr/ports/packages/i386/cdrom/rsnapshot-1.2.9.tgz
===> rsnapshot-1.2.9 depends on: rsync-2.6.9 - found
===> Installing rsnapshot-1.2.9 from /usr/ports/packages/i386/all/rsnapshot-1.2.9.tgz
rsnapshot-1.2.9: complete 

如您所见, port系统自动做了很多事情。它会先下载源代码, 解压, 并给源程序打补丁, 配置, 构建(编译)源代码, 安装到一个虚拟目录, 根据打包清单产生一个package(程序包), 然后将这个程序包安装在您的系统上(通常安装在 /usr/local/ 目录下)。并且ports系统可以递归地自动安装程序包的所有依赖包。注意上面的"===> Verifying install for ..." 和 "===> Returning to build of ..."之间的这些行(译者注:为方便查阅已经标记为蓝色), 说明ports系统遍历了整个依赖关系树。

如果您已经在计算机上安装了一个软件的以往版本, 您只需使用make update替代make install, 它将让pkg_add工具调用 -r参数。

说明: 大的应用需要很多的系统资源, 这方面最好的例证就是GCC 4.0 或 Java 2 Software Development Kit。当您构建一个port时如果看到类似"out of memory"的错误提示, 通常是以下原因之一:

您的设置的构建(编译)环境过于严格(安全), 调整一下ksh的ulimit或csh的limit就可以了, 如果还不行, 就用root登录或使用sudo(8)加上-c参数来限制登录级别编译程序源码(更多关于登录级别的信息请参阅login.conf(5)。
您的内存不够。
15.3.6 - 构建完成后进行清理
您或许想在生成和安装package后清理port工作目录。

代码: 全选

$ make clean
===> Cleaning for rsnapshot-1.2.9


另外您可以用下面的命令清理所以依赖包的工作目录:

代码: 全选

$ make clean=depends
===> Cleaning for rsync-2.6.9
===> Cleaning for rsnapshot-1.2.9 


如果您想删除程序的源代码用下面的命令:

代码: 全选

$ make clean=dist
===> Cleaning for rsnapshot-1.2.9
===> Dist cleaning for rsnapshot-1.2.9 


有时您可能编译了一个port的不同类型版本, 想一次性清理所有类型版本的目录:

代码: 全选

$ make clean=flavors


下面的命令可以在构建package后自动清除上面所提目录:

代码: 全选

$ make package BULK=Yes


15.3.7 - 卸载一个port的package
卸载一个port很简单:

代码: 全选

$ make uninstall
===> Deinstalling for rsnapshot-1.2.9
rsnapshot-1.2.9: complete
Clean shared items: complete


这将调用pkg_delete命令删除系统中相应的package, 您也可以先卸载再重新安装一个port的package, 用下面的命令:

代码: 全选

$ make reinstall
===> Cleaning for rsnapshot-1.2.9
/usr/sbin/pkg_delete rsnapshot-1.2.9
rsnapshot-1.2.9: complete
Clean shared items: complete
===> Installing rsnapshot-1.2.9 from /usr/ports/packages/i386/all/rsnapshot-1.2.9.tgz
rsnapshot-1.2.9: complete 


如果您想删除您刚构建的文件包, 用下面的命令:

代码: 全选

$ make clean=packages
===> Cleaning for rsnapshot-1.2.9
rm -f /usr/ports/packages/i386/all/rsnapshot-1.2.9.tgz 


15.3.8 - 使用各种类型的port及subpackages
请务必阅读ports(7)用户手册, 它提纲携领地阐述了这个议题。出于不同的目的我们采用两种方式进行程序打包。
第一种方式是根据程序的不同特征用途, 这里特征是指一系列指定的编译选项, 例如"no_x11"选项编译出的package仅能应用在没有安装X的系统上, 有些shell具有静态(static)特征, 它就需要一个静态链接版本的package, 为适合不同图形工具包而制作的特性package。其余的例子还有:支持不同的数据库类型, 不同的网络连接类型(SSL, IPv6......), 不同的页面尺寸等等。

小结: 很有可能您正在找的package刚好没有您需要的类型, 这种情况下您需要自己确认所需的port并自行构建一个package。

通常情况下同一个port的不同类型的源代码分别在各自的目录里, 编译过程生成的各类package也会采用特征名称以避免混淆。您可以进入该port的子目录输入如下命令:

代码: 全选

$ make show=FLAVORS


您也可以看到该port的 DESCR 文件, 它说明了有哪些可用类型。
第二种方式是分包. 如果port逻辑上可以拆分, 程序员也许会决定将程序分装成不同的subpackage, 您会看到有的程序分成客户端和服务器两部分。有时也会看见大量的文档被打包成一个独立的subpackage, 因为它们会占据相当多的磁盘空间。额外的功能如果需要大量的依赖体也会被单独打包处理。程序员也要确定那个subpackage是主要的subpackage, 这个subpackage会设置成默认安装, 其它还有例如随程序发行的扩展测试套件, 为不同功用定制的不同subpackage等等。 小结: 有些port被分成了几个package, 您安装时仅需要安装主要的subpackage。

列出一个port创建的不同的package使用如下命令:

代码: 全选

$ make show=PACKAGES


make install 命令只安装主程序模块, 如果您想安装所有模块使用如下命令:

代码: 全选

$ make install-all


列出程序所有的模块, 使用如下命令:

代码: 全选

$ make show=MULTI_PACKAGES


也有可能您只想安装一个port的部分subpackage, 经过一系列校验后会, 进程会调用pkg_add(1)来安装您想要的subpackage。

代码: 全选

$ env SUBPACKAGE="-server" make install


注意: subpackage机制只能处理package, 它不会在构建前对修改任何配置选项, 如果您需要不同配置的package请自行选择不同类型的package。

15.4 - FAQ
15.4.1 -我看见大量错误信息, 看起来这个port根本无法安装。
这种情况很像您使用了不同类型的系统和ports树

Sorry?

请阅读OpenBSD's Flavors:的所有细节: -release, -stable, 和 -current, 下面是一个小结, 但是请一定要阅读前面的文章搞清楚您到底要使用什么版本类型。
Release: 在发行CD上。
Stable: 发行版基础上增加了安全性和可靠性。
Current: OpenBSD的最新开发版。
不要check out一个–current版 ports树, 然后希望可以在-release版或者–stable版运行。这是最常见的错误之一, 如果这种情况下您请求别人的帮助会激怒这些人。如果您使用当前版的系统您只能使用当前版的ports树。没错, 这绝对意味着新的port将不能安装在"老"系统上——即使这个"老"系统几周前曾经是当前版。记住如果您的系统安装了X11, 您的系统也只能跟进相应的分支!
因为稳定版并不增添新功能, 所以它可以应用发行版的packages 和 ports, 没有必要因为几个额外的补丁就更新您所有的packages。
另一个常见的错误是没有安装X11, 即使您想编译的port并不依赖于X11, 但可能它的依赖体或模块需要X11的头文件或库文件, 如果您在未安装x11的系统上安装ports, 我们将无法提供技术支持, 所以如果您坚持这样做您只有自行解决所遇问题。然而很多ports并不提供"no_x11"特征版本, 这些版本才适合未安装X11的系统。

在OpenBSD 4.2时, 很多package使用libexpat, 即使它们没有图形功能但是仍需要安装系统组件xbase42.tgz 。 这个问题在OpenBSD 4.3时得到了修正, libexpat 已经包含在系统基本组件base43.tgz文件里内。 因此, libexpat不再依赖任何 X 组件。更详细的说明请参看 升级指南。

15.4.2 - 怎么没有我最喜欢软件的最新版本!
如果您使用稳定版的OpenBSD, 您会发现任何package都不提供更新, 它们的更新版会出现在下一个发行版, 或者可能因为安全问题而必须对该port进行升级, 这时更新的port和相关软件才会出现在稳定版的分支中。
警告: 不要混用不同版本类型的Ports和OpenBSD!

如果您这样做迟早(事实上很可能很快)会让您焦头烂额, 请参阅各种各样的错误!

嗨, 但是我已经全跟进到当前版了!

Port收集是一个志愿项目, 有时这个项目因为开发者人力不足, 不能将每个软件全更新成最新版, 开发者只能尽量多地挑选那些他们感兴趣和环境允许的条件下进行软件测试, 您的捐赠 可以让很多平台上的这种现象得到改善。

有些port落后于主流更新进度正是因为如此。有的程序可能在五月份已经有了新版本, 但是port树上收集的只是它一月份的老版本, 这通常是有意而为之, 通常可能是新版本运行在OpenBSD上存在某些问题维护者正在尽力解决, 或者新版本的运行情况干脆不如老版本:OpenBSD的目标可能与其他主流开发项目不同, 有时这可能导致package的设计, 特色, 执行等不符合OpenBSD开发者的目标 。更新被推迟也可能是该软件的更内容并非至关重要。

如果您真是需要一个新版本的port, 您应该要求这个port的维护人员对它进行更新(看下面)您可以知道谁具体维护它)。如果您可以在这方面帮助我们那更好。

15.4.3 - 为什么没有我最喜欢的软件的package?
这有几种可能的原因:
OpenBSD发布的 CD-ROMs因为容量的限制无法提供所有平台的所有软件, 所以仅有最常用的软件才会包含在CD上, 另外有些软件只能在自由的再次分发, 所以也无法包含在CD里面, 如果您不能在CD上找到您需要的package, 试试FTP。
有的软件不能以二进制的形式分发, 还有的是因为版权限制不能再次分发。如果您的软件属于上面的情况您可以自行下载port, 然后从源码编译它们。
很显然, 总被遗忘的是:就没有 您最喜欢软件的port , 您可以通过搜索ports树来确认, 如果确实没有您喜欢的软件的二进制包, 那么我们欢迎您帮助我们。
15.4.4 - 为什么port里没有我最喜欢的软件?
收集ports是一个志愿工程, 现行的port发展仅靠有限的几个人, 并且是在他们的空余时间, 这些人通常只是更新自己使用和感兴趣的port。您可以提供帮助考虑一下制作您自己的port。 这里有一些有用的文档:制作一个OpenBSD的Port, 阅读它, 然后再读一遍。 特别是管理您的port那部分内容。然后小心地进行测试并逐步完成。如果最后成功了, 提交到邮件列表[email protected]。如果您运气好会有一些反馈信息及其他人的测试结果。如果测试成功, 您的port可能会被加入port树。

15.4.5 - 为什么我最喜欢的软件没有包含在基本系统内?
因为OpenBSD应该是一个小巧的独立的类UNIX操作系统, 关于系统包含什么我们需要画一条分界线。通常, 一个程序被包含在系统内需要:
这个程序必须有极高的设计水准, 它必须深蕴OpenBSD的理念。
这个程序的使用许可必须不能包含过于严格的限制, 而且要与OpenBSD的使用许可保持一致。
这个程序的体积不能过大, 必须在基本系统所能接受的范围内。
对这个问题更详细的回答也可以在FAQ 1里找到。

15.4.6 - 我应该用哪个: packages 还是 ports?
通常, 我们强烈推荐您使用packages而不是从ports自己构建一个应用程序。我们使用port的最终目的是提供packages, 而不是ports本身。
从源码构建一个大的程序并非易事, 并非只是编译程序源代码, 用来编译源代码的工具本身也需要从源代码编译。很遗憾, OpenBSD, 这些编译工具, 需要编译的程序全处于一个动态的发展状态, 让它们能在一起协调工作是一个极大的挑战, 即使某次可以成功, 但是可能第二天它们中的一个进行了一些修正就会导致问题重现。每隔六个月OpenBSD推出一个新发行版, 测试每个平台上的每个port可否编译这项工作也已完成。但是在这六个月的发展周期内, 一些ports很可能会有变化。 除了让各部分协调一致的工作外, 从源码编译某些应用程序所需的时间和资源也是一个问题。一个普遍的例子就是CVSup, 它是一个跟踪OpenBSD 源代码树的工具。在一个网速较快性能强劲的计算机上只需要10秒钟左右——这里指下载和解压缩单个779KB的文件包;与此相反, 还在这台计算机上如果从源代码构建CVSup将是一个繁重的任务, 需要很多工具以及一步一步地引导编译器完成编译工作, 耗时长达半个小时。其它的应用程序例如Mozilla或KDE 可能花费数小时并且占用大量的硬盘空间和内存及交换分区空间来构建。当一个已经被编译完的程序在您的CD-ROM 或 FTP mirror 上等着被使用, 为什么还要花这样多的时间和精力去重新编译它呢?

当然, 某些情况下使用ports比packages更适合:

发行许可限制OpenBSD用packages的形式发行这个软件。
您希望修改或调试这个软件或想学习它的源代码。
您需要的port类型OpenBSD ports团队并没有提供。
您需要修改目录结构(也就是修改前缀或配置文件目录)。
然而对大多数用户和大多数应用程序而言, 直接使用packages更简单, 对一个OpenBSD系统来说直接安装packages的方法更简洁明了的也是被推荐的方式。
15.4.7 - 怎样将ports调整成最佳性能?
OpenBSD力求稳定和安全, 就像我们只支持标准的GENERIC内核一样, ports团队要确保ports可以正常稳定的工作。如果您想自己尝试编译器内的所有参数, 那是您自己的事情, 当您尝试开启一些隐含的参数以使port编译后的程序运行的更快, 请不要在port的邮件列表上问诸如:"为什么它无法通过编译?"这样的问题。所有的这些调整对99%的用户来讲没有必要, 对您, 对其他用户, 同样也对阅读您的问题的开发人员来说更像是浪费时间, 而实际上它是一个不应该被提出的问题。

15.4.8 我几周前提交了一个新port(或者一个更新), 为什么现在还没有审核?
Ports团队的资源非常有限, 他们没有能及时审核您提交的程序, 这可能多少有点让您觉得心灰意冷, 别在意这种情况, 保管好您的port并发送更新, 最终会有人处理它们的, 这要看这些团队成员是否有空余的时间可以审核您的port。当成员的兴趣转移到您的ports上时也会审核的, 如果他们还记得这回事。

15.5 - 报告问题
如果您在使用一个port时遇到了困难, 请发一封邮件给port的维护者, 来看一下谁具体维护这个port, 例如这样:

代码: 全选

$ cd /usr/ports/archivers/unzip
$ make show=MAINTAINER


而如果没有维护者或者您无法联系上维护者, 请给[email protected]发一封信, 请勿使用邮件列表[email protected]提问有关port的问题。

任何情况下需提供:

您的OpenBSD版本类型及应用的补丁。用sysctl –n kern.version命令查看内核版本。
您ports的版本:如果/usr/ports/CVS/Tag 这个文件存在, 请提供它, 如果这个文件不存在, 那么您正在使用的当前版的ports树。
一个对问题完整详尽的描述:不要害怕提供所有细节, 说明出现问题前您的所有操作步骤。这个问题是反复出现吗?您提供的细节越多就越有可能获得帮助。
对没有正确构建的ports来说, 提供一份完整的构建过程描述是十分必要的, 您可以使用portslogger脚本, 它位于/usr/ports/infrastructure/build, 下面是运行portslogger的一个实例:

代码: 全选

$ mkdir ~/portslogs
$ cd /usr/ports/archivers/unzip
$ make clean install 2>&1 | /usr/ports/infrastructure/build/portslogger ~/portslogs


做完这个步骤, 系统会在~/portslogs目录下生成一个日志文件, 还是那句话请不要使用任何特殊的选项编译Ports, 例如修改/etc/mk.conf。
您还可以:

用script(1)生成一个完整的构建过程描述。另外别删除配置信息。
附上您的pkg_info(1)信息, 即使可能和它没有关系。
如果出现gcc(1) 内部编译器错误请给gcc邮件列表发送一份错误报告, 并至少提供一份gcc -save-temps生成文档, 如果您遵循他们的回复, 会节省大量的时间。
15.6 - 帮助我们
您可以从很多途径对我们提供帮助, 下面的列表提供了具体的方法, 由易至难:
报告错误用您的经历。
您可以系统的测试ports并回复程序问题或者提供改进的方法。您仅需阅读Port Testing Guide.
测试在ports邮件列表上的ports更新
发送一个ports的更新或补丁给ports维护人员, 如果这个port没有维护人就发到ports的邮件列表上。除非您的补丁或更新会浪费开发者的时间而不是节约他们的时间, 否则大家全会感谢您的。
如果您乐于助人并想掌握所有制作ports的方法, 您可以尝试自己制作ports, Building an OpenBSD Port给您提供了一个良好的开端。
注意: 您必须使用当前版才能制作一个新port或者更新一个port, 因为当前版是在不断发展中, 所以, 通常情况下当前版并非所有人期望使用的, 您要先确认自己心甘情愿使用当前版。