4.5.使用 Ports Collection

Ports Collection 由一组 Makefile、 补丁和描述文件构成。每一组这些文件都是用来在 FreeBSD 上编译和安装一个单独的应用程序,并被称为 port。

默认情况下,Ports Collection 本身是作为 /usr/ports 的一个子目录来存储的。

警告:

在安装和使用 Ports Collection 之前,请注意通常不建议将 Ports Collection 与通过 pkg 提供的二进制包一起使用来安装软件。pkg 默认会跟踪 ports 树的季度分支版本,而不是 HEAD。与季度分支版本中的 port 相比,HEAD 中的依赖关系可能有所不同,这可能导致 pkg 安装的依赖关系与 Ports Collection 中的依赖关系发生冲突。如果必须同时使用 Ports Collection 和 pkg ,那么请确保你的 Ports Collection 和 pkg 在 ports 树的同一个分支版本上。

Ports Collection 包含软件类别的目录。在每一个类别中,都有针对各个应用程序的子目录。每个应用程序的子目录都包含了一组文件,这些文件告诉 FreeBSD 如何编译和安装这个程序,这被称为 ports 骨架。每个 port 骨架都包括这些文件和目录:

  • Makefile:包含指定应用程序应如何被编译以及其组件应安装在何处的代码。

  • distinfo: 包含为构建 port 而必须下载的文件的名称和校验和。

  • pkg-descr: 提供了关于对该程序更详细的描述。

  • pkg-plist: 包含所有将被 port 安装的文件的列表。它也会告诉 ports 系统在卸载时要删除哪些文件。

一些 ports 包括pkg-message或其他文件来处理特殊情况。关于这些文件以及一般的 ports 的更多细节,请参考 FreeBSD Porter 的手册。

这个 port 并不包括实际的源代码,也就是所谓的 distfile。构建 port 的 extract 部分会自动将下载的源代码保存到/usr/ports/distfiles

4.5.1.安装 Ports Collection

在使用 port 编译应用程序之前,必须首先安装 Ports Collection。如果在安装 FreeBSD 时没有安装,可以使用下列方法来安装它。

Procedure: Portsnap 方法

FreeBSD 的基本系统包括 Portsnap。这是一个用于检索 Ports Collection 的快速且用户友好的工具,是大多数不运行 FreeBSD-CURRENT 的用户的推荐选择。这个工具可以连接到 FreeBSD 站点,验证安全密钥,并下载 Ports Collection 的新副本。这个密钥被用来验证所有下载文件的完整性。

请注意,Portsnap 更新是从 Ports Collection 主分支的快照生成的,不能配置为使用不同的分支(例如,quarterly)。如果有必要使用 Ports Collection 的不同分支(例如前面提到的与二进制包有关的分支),则必须使用 Git 方法。

1.要将 Ports Collection 的压缩快照下载到 /var/db/portsnap

  1. # portsnap fetch

2.第一次运行 Portsnap 时,将快照提取到 /usr/ports

  1. # portsnap extract

3.在如上所示完成了对 Portsnap 的第一次使用后,可以通过运行 /usr/ports 来根据需要更新:

  1. # portsnap fetch
  2. # portsnap update

当使用 fetch 时,提取或更新操作可以连续运行,像这样:

  1. # portsnap fetch update

Procedure:Git 方法

如果需要对 ports 树进行更多的控制,或需要维护本地的修改,或者运行 FreeBSD-CURRENT,可以使用 Git 来获取 Ports Collection。请参阅 Git Primer 以了解关于 Git 的详细介绍。

1.在用来检查 ports 树之前,必须先安装 Git。如果已经有了 ports 树的副本,请像这样安装 Git:

  1. # cd /usr/ports/devel/git
  2. # make install clean

如果 ports 树不可用,或者正在使用 pkg 管理软件包,那么可以将 Git 作为一个包来安装:

  1. # pkg install git

2.查看一下 ports 树的 HEAD 分支的副本:

  1. # git clone https://git.FreeBSD.org/ports.git /usr/ports

3.或者,查看一份季度分支构建的副本:

  1. # git clone https://git.FreeBSD.org/ports.git -b 2020Q3 /usr/ports

4.根据需要,在最初的 Git 签出后更新/usr/ports

  1. # git -C /usr/ports pull

5.根据需要,将/usr/ports切换到不同的季度分支:

  1. # git -C /usr/ports switch 2020Q4

4.5.2.安装 ports

本节提供了关于使用 Ports Collection 来安装或删除软件的基本说明。关于可用的 make 目标和环境变量的详细描述,可以在 ports(7) 中找到。

警告:

在编译任何 ports 之前,请务必按照前一节所述更新 Ports Collection。由于安装任何第三方软件都可能引入安全漏洞,因此建议首先检查 https://vuxml.freebsd.org/,以了解与该 port 有关的已知安全问题。另外,在安装一个新的 port 之前,可以运行pkg audit -F。这个命令可以被配置为在每日安全系统检查中自动执行安全审计和漏洞数据库的更新。更多信息,请参阅 pkg-audit(8) 和 periodic(8)。

使用 Ports Collection 的前提是有一个正常的互联网连接。它还需要超级用户的权限。

要编译和安装这个 port,请切换到要安装的 port 的目录,然后在提示符下输入make install。提示消息会显示进度:

  1. # cd /usr/ports/sysutils/lsof
  2. # make install
  3. >> lsof_4.88D.freebsd.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
  4. >> Attempting to fetch from ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/.
  5. ===> Extracting for lsof-4.88
  6. ...
  7. [extraction output snipped]
  8. ...
  9. >> Checksum OK for lsof_4.88D.freebsd.tar.gz.
  10. ===> Patching for lsof-4.88.d,8
  11. ===> Applying FreeBSD patches for lsof-4.88.d,8
  12. ===> Configuring for lsof-4.88.d,8
  13. ...
  14. [configure output snipped]
  15. ...
  16. ===> Building for lsof-4.88.d,8
  17. ...
  18. [compilation output snipped]
  19. ...
  20. ===> Installing for lsof-4.88.d,8
  21. ...
  22. [installation output snipped]
  23. ...
  24. ===> Generating temporary packing list
  25. ===> Compressing manual pages for lsof-4.88.d,8
  26. ===> Registering installation for lsof-4.88.d,8
  27. ===> SECURITY NOTE:
  28. This port has installed the following binaries which execute with
  29. increased privileges.
  30. /usr/local/sbin/lsof
  31. #

由于lsof是一个以增加权限运行的程序,所以在安装时将显示一个安全警告。安装完成后,将返回提示。

一些 shell 保留了PATH环境变量中列出的目录中可用的命令的缓存,以加快对这些命令的可执行文件的查找操作。tcsh shell 的用户应该输入rehash,这样就可以在不指定完整路径的情况下使用一个新安装的命令。在 sh shell 中使用hash -r来代替。更多信息请参考 shell 的文档。

在安装过程中,会创建一个工作子目录,其中包含了编译过程中使用的所有临时文件。删除这个目录可以节省磁盘空间,并在以后升级到较新版本的 port 时尽量减少出现问题的机会。

  1. # make clean
  2. ===> Cleaning for lsof-88.d,8
  3. #

注意:

为了节省这个额外的步骤,在编译 port 时应使用 make install clean

4.5.2.1.定制 ports 安装

一些 ports 提供了联编选项,可以用来启用或禁用应用程序组件,提供安全选项,或允许其他定制。例子包括 www/firefoxsecurity/gpgmemail/sylpheed-claws。如果这个 port 依赖于其他有可配置选项的 port,它可能会因为用户的互动而暂停数次,因为默认行为是提示用户从菜单中选择选项。为了避免这种情况,并在一个批次中完成所有的配置,可以在 port 的骨架中运行 make config-recursive。然后,运行 make install [clean] 来编译和安装这个 port。

提示:

当使用 config-recursive 时,要配置的 port 列表是由 all-depends-list 目标收集的。建议运行 make config-recursive 直到所有依赖的 ports 选项都被定义,并且不再出现 ports 选项屏幕,以确定所有的依赖选项都被配置了。

有几种方法可以重新访问 port 的联编选项菜单,以便在 port 联编完成后添加、 删除或修改这些选项。一种方法是cd进入包含 port 的目录,然后输入 make config。另一个方法是使用 make showconfig。另一个方法是执行 make rmconfig,它将删除所有选定的选项并允许你重新开始。所有这些选项,以及其他选项,在 ports(7) 中都有详细的解释。

ports 系统使用 fetch(1) 来下载源文件,它支持各种环境变量。如果 FreeBSD 系统位于防火墙或 FTP/HTTP 代理之后,可能需要设置 FTP_PASSIVE_MODEFTP_PROXYFTP_PASSWORD 这些变量。请参阅 fetch(3) 以了解支持的变量的完整列表。

对于那些不能保持连接到互联网的用户来说,make fetch 可以在 /usr/ports 中运行,以获取所有的 distfiles,或在一个类别中,例如 /usr/ports/net,或在特定的 port 骨架中运行。请注意,如果一个 port 有任何依赖关系,在一个类别或 port 骨架中运行此命令将不会获取另一个类别中的 port 的 distfiles。相反,使用 make fetch-recursive 来获取一个 port 的所有依赖关系的 distfiles。

在少数情况下,例如当一个组织有一个本地的 distfiles 仓库时,MASTER_SITES 变量可以用来覆盖 Makefile 中指定的下载位置。在使用时,应指定备用的位置:

  1. # cd /usr/ports/directory
  2. # make >MASTER_SITE_OVERRIDE= \
  3. ftp://ftp.organization.org/pub/FreeBSD/ports/distfiles/ fetch

WRKDIRPREFIXPREFIX变量可以覆盖默认的工作目录和目标目录。比如说:

  1. # make WRKDIRPREFIX=/usr/home/example/ports install

将在 /usr/home/example/ports 中编译 port,并在 /usr/local 中安装一切:

  1. # make PREFIX=/usr/home/example/local install

将在 /usr/ports 中编译这个 port,并将其安装在 /usr/home/example/local。还有:

  1. # make WRKDIRPREFIX=../ports PREFIX=../local install

将把这两者结合起来。

也可以把这些设置为环境变量。关于如何设置环境变量的说明,请参考你的 shell 的手册页。

4.5.3.移除已安装的 ports

已安装的 port 可以通过 pkg delete 来卸载。使用这一命令的例子可以在 pkg-delete(8) 手册中找到。

另外,也可以在 port 的目录中运行 make deinstall

  1. # cd /usr/ports/sysutils/lsof
  2. # make deinstall
  3. ===> Deinstalling for sysutils/lsof
  4. ===> Deinstalling
  5. Deinstallation has been requested for the following 1 packages:
  6. >lsof-4.88.d,8
  7. The deinstallation will free 229 kB
  8. [1/1] Deleting lsof-4.88.d,8... done

建议在卸载 port 的过程中阅读这些信息。如果这个 port 有任何依赖它的应用程序,这些信息将被显示出来,但卸载将继续进行。在这种情况下,为了防止依赖关系被破坏,重新安装该应用程序可能会更好。

4.5.4.升级 ports

随着时间的推移,Ports Collection 中会出现更新的软件版本。本节介绍了如何确定哪些软件可以升级,以及如何执行升级。

要确定所安装的 port 是否有更新的版本,应使用“Portsnap 方法”或“Git 方法”中描述的更新命令,确保安装了最新版本的 ports 树。在 FreeBSD 10 及更高版本上,或者如果系统已经转换为 pkg,下面的命令将列出已经安装的过时的 ports:

  1. # pkg version -l "<"

对于 FreeBSD 9.X 和更低版本,以下命令将列出已安装的过期 ports:

  1. # pkg_version -l "<"

重要:

在尝试升级之前,请从文件的顶部阅读 /usr/ports/UPDATING,以确定与上次升级 port 或安装系统最接近的日期。这个文件描述了用户在更新 port 时可能遇到的各种问题和需要执行的额外步骤,包括诸如文件格式的变化、 配置文件位置的变化,以及与先前版本不兼容的情况。请注意任何与需要升级的 port 相匹配的说明,并在执行升级时遵循这些说明。

4.5.4.1. 升级和管理 ports 的工具

Ports Collection 包含几个实用程序来执行实际的升级。每一个都有它的优势和劣势。

过去,大多数安装都使用 Portmaster 或 Portupgrade。Synth 是一个较新的选择。

哪种工具最适合某个特定的系统,都由系统管理员来选择。在使用这些工具之前,建议先备份你的数据。

4.5.4.2. 使用 Portmaster 升级 ports

ports-mgmt/portmaster是一个非常迷你的工具,用于升级已安装的 ports。它被设计用来使用 FreeBSD 基本系统中安装的工具,而不需要依赖其他 ports 或数据库。要把这个工具作为一个 port 来安装:

  1. # cd /usr/ports/ports-mgmt/portmaster
  2. # make install clean

Portmaster定义了四种类型的ports:

  • 根 ports:没有依赖关系,也不是任何其他 ports 的依赖关系。

  • 中继 ports:没有依赖关系,但其他 ports 依赖它。

  • 分支 ports:有依赖关系,其他 ports 依赖于它。

  • 叶子 ports:有依赖关系但没有其他 ports 依赖它。

要列出这些类别并搜索更新:

  1. # portmaster -L
  2. ===>>> Root ports (No dependencies, not depended on)
  3. ===>>> ispell-3.2.06_18
  4. ===>>> screen-4.0.3
  5. >===>>> New version available: screen-4.0.3_1
  6. ===>>> tcpflow-0.21_1
  7. ===>>> 7 root ports
  8. ...
  9. ===>>> Branch ports (Have dependencies, are depended on)
  10. ===>>> apache22-2.2.3
  11. >===>>> New version available: apache22-2.2.8
  12. ...
  13. ===>>> Leaf ports (Have dependencies, not depended on)
  14. ===>>> automake-1.9.6_2
  15. ===>>> bash-3.1.17
  16. >===>>> New version available: bash-3.2.33
  17. ...
  18. ===>>> 32 leaf ports
  19. ===>>> 137 total >installed ports
  20. >===>>> 83 have new versions available

该命令用于升级所有过时的 ports:

  1. # portmaster -a

注意:

在默认情况下,Portmaster 在删除现有 ports之前会做一个备份包。如果新版本的安装成功,Portmaster 将删除备份。使用 -b 可以指示 Portmaster 不自动删除备份。添加-i 可以在交互式模式下启动 Portmaster,在升级每个 port 之前提示确认。还有许多其他选项可用。请阅读 portmaster(8) 的手册以了解它们的详细用法。

如果在升级过程中遇到错误,可以添加-f来升级和重建所有ports:

  1. # portmaster -af

Portmaster 也可以用来在系统中安装新的 port,在联编和安装新 port 之前升级所有的依赖关系。要使用这个功能,需要在 Ports Collection 中指定ports的位置。

  1. # portmaster shells/bash

关于 ports-mgmt/portmaster 的更多信息可以在其 pkg-descr 中找到。

4.5.4.3.使用 Portupgrade 升级 ports

ports-mgmt/portupgrade是另一个可以用来升级 ports 的工具。它安装了一套可以用来管理ports的应用程序。然而,它依赖于 Ruby。要安装这个ports:

  1. # cd /usr/ports/ports-mgmt/portupgrade
  2. # make install clean

在使用这个工具进行升级之前,建议使用pkgdb -F扫描已安装的 port 列表,并修正它报告的所有不一致之处。

要升级系统中安装的所有过时的 port,请使用portupgrade -a。另外,也可以使用-i来确认每一次的升级:

  1. # portupgrade -ai

要升级一个指定的应用程序而不是所有可用的 ports,请使用portupgrade pkgname。包括-R是非常重要的,它可以首先升级指定应用程序所需的所有 ports:

  1. # portupgrade -R firefox

如果包含 -P,Portupgrade 会在 PKG_PATH中列出的本地目录中搜索可用的软件包。如果本地没有可用的软件包,它就会从远程站点获取软件包。如果在本地找不到软件包或无法从远程获取,Portupgrade 将使用 ports。要完全避免使用 ports,请指定 -PP。这最后一组选项告诉 Portupgrade,如果没有可用的包,就放弃:

  1. # portupgrade -PP gnome3

如果指定了-P,则只需获取 port distfiles 或 packages,而不需要编译或安装任何东西,请使用 -F。关于所有可用开关的进一步信息,请参考 portupgrade 的手册。

关于 ports-mgmt/portupgrade 的更多信息可以在其 pkg-descr 中找到。

4.5.5.ports 和磁盘空间

使用 Ports Collection 会随着时间的推移而耗尽磁盘空间。在联编和安装了一个 port 之后,在 ports 骨架中运行 make clean 将清理临时工作目录。如果使用 Portmaster 来安装一个 port,它将自动删除这个目录,除非指定了 -K。如果安装了 Portupgrade,这个命令将删除在 Ports Collection 本地副本中发现的所有工作目录:

  1. # portsclean -C

此外,过时的源码包文件会随着时间的推移在 /usr/ports/distfiles 中积累起来。要使用 Portupgrade 来删除所有不再被任何 ports 引用的 distfiles:

  1. # portsclean -D

Portupgrade 可以删除所有不被当前安装在系统上的任何 port 引用的 distfiles:

  1. # portsclean -DD

如果安装了 Portmaster,请使用:

  1. # portmaster --clean-distfiles

默认情况下,该命令是交互式的,提示用户确认是否应该删除一个 distfile。

除了这些命令之外,ports-mgmt/pkg_cutleaves还会自动删除已安装的、不再需要的 ports