第 4 章 安装应用程序:软件包和 Ports

如果发现翻译错误,请直接 发起PR修改

4.1. 简介

FreeBSD 捆绑了丰富的系统工具作为基本系统的一部分。此外,FreeBSD 还提供了两种互补的技术来安装第三方软件:FreeBSD Ports Collection 用于从源代码安装,而软件包则用于从预编译的二进制文件安装。可以使用任一方法从本地媒体或网络安装软件。

阅读完本章后,您将了解:

  • 二进制包和 ports 之间的区别。

  • 如何找到已经移植到 FreeBSD 的第三方软件。

  • 如何使用 pkg 管理二进制软件包。

  • 如何使用 Ports Collection 从源代码构建第三方软件。

  • 如何找到应用程序安装后的文件,以进行后续配置。

  • 如果软件安装失败,应该怎么办。

4.2. 软件安装概述

FreeBSD 的 ports 是一组文件,旨在自动化从源代码编译应用程序的过程。组成 ports 的文件包含了自动下载、提取、打补丁、编译和安装应用程序所需的所有必要信息。

如果软件尚未在 FreeBSD 上进行适配和测试,源代码可能需要进行编辑,以便正确安装和运行。

然而,在 36000 上已经有许多第三方应用程序被移植到了 FreeBSD。在可行的情况下,这些应用程序会以预编译的软件包形式提供下载。

可以使用 FreeBSD 软件包管理命令来操作软件包。

包和 ports 都能理解依赖关系。如果使用包或 ports 来安装一个应用程序,并且所依赖的库尚未安装,那么该库将会自动被先安装。

一个 FreeBSD 软件包包含了一个应用程序的预编译副本,以及任何配置文件和文档。可以使用 pkg(8) 命令来操作软件包,例如 pkg install

虽然这两种技术相似,但软件包和 ports 各有各的优势。选择符合您安装特定应用程序需求的技术。

包的好处
  • 通常,压缩的软件包 tarball 比包含应用程序源代码的压缩 tarball 要小。

  • 包不需要编译时间。对于大型应用程序,如 Firefox 、KDE Plasma 或 GNOME,在慢速系统上这一点可能很重要。

  • 在 FreeBSD 上编译软件的过程中,包不需要任何理解。

Port 的好处
  • 通常情况下,软件包会使用保守的选项进行编译,因为它们需要在尽可能多的系统上运行。通过从 ports 进行编译,可以更改编译选项。

  • 一些应用程序具有与安装的功能相关的编译时选项。例如,NGINX® 可以配置多种不同的内置选项。

    在某些情况下,为了指定特定的设置,同一个应用程序可能会存在多个软件包。例如,NGINX® 有一个 nginx 软件包和一个 nginx-lite 软件包,取决于是否安装了 Xorg。如果一个应用程序有超过一两个不同的编译选项,创建多个软件包将很快变得不可能。

  • 一些软件的许可条件禁止二进制分发。这类软件必须以源代码的形式分发,并由最终用户进行编译。

  • 有些人不信任二进制发行版,或者更喜欢阅读源代码以寻找潜在问题。

  • 为了应用自定义补丁,需要提供源代码。

要跟踪更新的 ports ,请订阅 FreeBSD ports mailing listFreeBSD ports bugs mailing list

在安装应用程序之前,请检查 https://vuxml.freebsd.org/ 是否存在相关的安全问题。

要对已安装的软件包进行已知漏洞的审计,请运行 pkg audit -F

本章的其余部分将解释如何使用软件包和 ports 在 FreeBSD 上安装和管理第三方软件。

4.3. 寻找软件

FreeBSD 的可用应用程序列表不断增长。有多种方法可以找到要安装的软件:

  • FreeBSD 网站维护着一个最新的可搜索的应用程序列表,位于 Ports Portal。可以通过应用程序名称或软件类别来搜索 ports。

  • Dan Langille 维护着 FreshPorts,该网站提供了一个全面的搜索工具,并跟踪 Ports Collection 中应用程序的变化。注册用户可以创建一个定制的监视列表,以便在所监视的 ports 更新时收到自动邮件通知。

  • 如果找到一个特定的应用程序变得困难,可以尝试在 SourceForge 或者 GitHub 这样的网站上进行搜索,然后再回到 Ports Portal 查看该应用程序是否已经被移植。

  • 使用 pkg(8) 命令在二进制软件包仓库中搜索一个应用程序

4.4. 使用 pkg 进行二进制包管理

pkg(8) 提供了一个用于操作软件包的接口:注册、添加、删除和升级软件包。

对于只希望使用 FreeBSD 镜像站点提供的预编译二进制包的网站,使用 pkg(8) 来管理软件包可能已经足够了。

然而,对于那些从源代码构建网站的用户,将需要使用单独的 ports 管理工具。

由于 pkg(8) 只能用于二进制软件包,它并不能替代这些工具。这些工具可以用于安装来自二进制软件包和 Ports Collection 的软件,而 pkg(8) 只能安装二进制软件包。

4.4.1. 开始使用 pkg

所有支持的 FreeBSD 版本现在都包含 /usr/sbin/pkg,也被称为 pkg(7) 。这是一个小的占位符,只包含安装真正的 pkg(8) 所需的最小功能。

在引导过程中,需要一个互联网连接才能成功。

运行 pkg(8) 命令行:

# pkg

输出应该类似于以下内容:

The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]

pkg(7) 将拦截该命令,如果您确认这是您的意图,将下载 pkg(8) tarball ,并从中安装 pkg(8),引导本地软件包数据库,然后继续运行您最初请求的命令。

较新版本的 pkg(7) 可以理解 pkg -N 作为一种测试,用于检查是否安装了 pkg(8),而不触发安装操作。相反,pkg bootstrap[-f] 用于安装 pkg(8)(或强制重新安装),而不执行任何其他操作。

可以通过查看 pkg(8) 手册页面或者在运行 pkg 命令时不添加额外参数来获取 pkg 的使用信息。有关其他 pkg 配置选项的描述,请参阅 pkg.conf(5)

每个 pkg 命令参数都在特定命令的手册页中有详细说明。

例如,要阅读 pkg install 的手册页,请运行以下命令:

# pkg help install

本节的其余部分演示了使用 pkg(8) 执行的常见二进制包管理任务。每个演示的命令都提供了许多开关来自定义其使用方式。有关详细信息和更多示例,请参阅命令的帮助或 man 页面。

4.4.2. 季度和最新的 ports 分支

Quarterly 分支为用户提供了更可预测和稳定的 ports 和软件包安装和升级体验。这主要通过只允许非功能性更新来实现。季度分支旨在接收安全修复(可能是版本更新或提交的回溯)、错误修复和 ports 合规性或框架更改。季度分支在每年的一月、四月、七月和十月的季度初从 HEAD 中切出。分支的命名方式根据它们创建的年份(YYYY)和季度(Q1-4)。例如, 2023 年 1 月创建的季度分支被命名为 2023Q1。而 Latest 分支为用户提供了软件包的最新版本。

要将 pkg(8) 从季度版切换到最新版,请运行以下命令:

# mkdir -p /usr/local/etc/pkg/repos
# echo 'FreeBSD: { url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest" }' > /usr/local/etc/pkg/repos/FreeBSD.conf

然后运行以下命令来更新本地软件包仓库目录,以获取最新分支的内容:

# pkg update -f

4.4.3. 配置 pkg

pkg.conf(5)pkg(8) 工具使用的系统级配置文件。该文件的默认位置是 /usr/local/etc/pkg.conf

FreeBSD 不需要有 pkg.conf 文件。许多安装可以在没有任何 pkg.conf 文件或只有空的 pkg.conf 文件(除了注释行)的情况下正常工作。

以"#"开头的行是注释,会被忽略。

该文件采用 UCL 格式。有关 libucl(3) 语法的更多信息,请访问 official UCL website

识别以下类型的选项 - 布尔型、字符串型和列表型选项。

如果在配置文件中指定了以下值之一 - YES 、TRUE 和 ON,则将布尔选项标记为已启用。

要搜索一个软件包,可以使用 pkg-search(8) 命令:

# pkg search nginx

输出应该类似于以下内容:

modsecurity3-nginx-1.0.3       Instruction detection and prevention engine / nginx Wrapper
nginx-1.22.1_2,3               Robust and small WWW server
nginx-devel-1.23.2_4           Robust and small WWW server
nginx-full-1.22.1_1,3          Robust and small WWW server (full package)
nginx-lite-1.22.1,3            Robust and small WWW server (lite package)
nginx-naxsi-1.22.1,3           Robust and small WWW server (plus NAXSI)
nginx-prometheus-exporter-0.10.0_7 Prometheus exporter for NGINX and NGINX Plus stats
nginx-ultimate-bad-bot-blocker-4.2020.03.2005_1 Nginx bad bot and other things blocker
nginx-vts-exporter-0.10.7_7    Server that scraps NGINX vts stats and export them via HTTP
p5-Nginx-ReadBody-0.07_1       Nginx embeded perl module to read and evaluate a request body
p5-Nginx-Simple-0.07_1         Perl 5 module for easy to use interface for Nginx Perl Module
p5-Test-Nginx-0.30             Testing modules for Nginx C module development
py39-certbot-nginx-2.0.0       NGINX plugin for Certbot
rubygem-passenger-nginx-6.0.15 Modules for running Ruby on Rails and Rack applications

4.4.5. 安装和获取软件包

要安装一个二进制软件包,可以使用 pkg-install(8) 命令。该命令使用存储库数据来确定要安装的软件的版本以及是否有未安装的依赖项。例如,要安装 curl :

# pkg install curl

输出应该类似于以下内容:

Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 9 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        ca_root_nss: 3.83
        curl: 7.86.0
        gettext-runtime: 0.21
        indexinfo: 0.3.1
        libidn2: 2.3.3
        libnghttp2: 1.48.0
        libpsl: 0.21.1_4
        libssh2: 1.10.0.3
        libunistring: 1.0

Number of packages to be installed: 9

The process will require 11 MiB more space.
3 MiB to be downloaded

Proceed with this action? [y/N]

新的软件包以及作为依赖项安装的任何其他软件包都可以在已安装软件包列表中看到:

# pkg info

输出应该类似于以下内容:

ca_root_nss-3.83               Root certificate bundle from the Mozilla Project
curl-7.86.0                    Command line tool and library for transferring data with URLs
gettext-runtime-0.21.1         GNU gettext runtime libraries and programs
indexinfo-0.3.1                Utility to regenerate the GNU info page index
libidn2-2.3.3                  Implementation of IDNA2008 internationalized domain names
libnghttp2-1.48.0              HTTP/2.0 C Library
libpsl-0.21.1_6                C library to handle the Public Suffix List
libssh2-1.10.0.3               Library implementing the SSH2 protocol
libunistring-1.0               Unicode string library
pkg-1.18.4                     Package manager

要获取一个软件包并稍后安装它或在另一个地方安装,请使用 pkg-fetch(8)。例如,要下载 nginx-lite

# pkg fetch -d -o /usr/home/user/packages/ nginx-lite
  • -d:用于获取所有的依赖项

  • -o:用于指定下载目录

输出应该类似于以下内容:

Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following packages will be fetched:

New packages to be FETCHED:
        nginx-lite: 1.22.1,3 (342 KiB: 22.20% of the 2 MiB to download)
        pcre: 8.45_3 (1 MiB: 77.80% of the 2 MiB to download)

Number of packages to be fetched: 2

The process will require 2 MiB more space.
2 MiB to be downloaded.

Proceed with fetching packages? [y/N]:

要安装下载的软件包,可以使用 pkg-install(8) 命令,具体操作如下:

# cd /usr/home/user/packages/
# pkg install nginx-lite-1.22.1,3.pkg

4.4.6. 获取已安装软件包的信息

可以通过运行 pkg-info(8) 来查看系统上安装的软件包的信息。当不带任何开关运行时,它将列出所有已安装软件包或指定软件包的版本信息。

例如,要查看已安装的 pkg 版本,请运行:

# pkg info pkg

输出应该类似于以下内容:

pkg-1.19.0
Name           : pkg
Version        : 1.19.0
Installed on   : Sat Dec 17 11:05:28 2022 CET
Origin         : ports-mgmt/pkg
Architecture   : FreeBSD:13:amd64
Prefix         : /usr/local
Categories     : ports-mgmt
Licenses       : BSD2CLAUSE
Maintainer     : [email protected]
WWW            : https://github.com/freebsd/pkg
Comment        : Package manager
Options        :
        DOCS           : on
Shared Libs provided:
        libpkg.so.4
Annotations    :
        FreeBSD_version: 1301000
        repo_type      : binary
        repository     : FreeBSD
Flat size      : 33.2MiB
Description    :
Package management tool

WWW: https://github.com/freebsd/pkg

4.4.7. 升级已安装的软件包

已安装的软件包可以使用 pkg-upgrade(8) 命令升级到最新版本。

# pkg upgrade

该命令将比较已安装的版本与存储库目录中可用的版本,并从存储库中升级它们。

4.4.8. 审核已安装的软件包

第三方应用程序经常会发现软件漏洞。为了解决这个问题,pkg 包含了一个内置的审计机制。要确定系统上安装的软件是否存在已知的漏洞,请使用 pkg-audit(8) 命令。

# pkg audit -F

输出应该类似于以下内容:

Fetching vuln.xml.xz: 100%  976 KiB 499.5kB/s    00:02
chromium-108.0.5359.98 is vulnerable:
  chromium -- multiple vulnerabilities
  CVE: CVE-2022-4440
  CVE: CVE-2022-4439
  CVE: CVE-2022-4438
  CVE: CVE-2022-4437
  CVE: CVE-2022-4436
  WWW: https://vuxml.FreeBSD.org/freebsd/83eb9374-7b97-11ed-be8f-3065ec8fd3ec.html

4.4.9. 移除软件包

不再需要的软件包可以使用 pkg-delete(8) 命令进行删除。

例如:

# pkg delete curl

输出应该类似于以下内容:

Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 1 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
        curl :7.86.0

Number of packages to be removed: 1

The operation will free 4 MiB.

Proceed with deinstallation packages? [y/N]: y
[1/1] Deinstalling curl-7.86.0...
[1/1] Deleting files for curl-7.86.0: 100%

4.4.10. 自动删除未使用的软件包

删除一个软件包可能会留下不再需要的依赖项。可以使用 pkg-autoremove(8) 自动检测和删除作为依赖项安装的不需要的软件包(叶子软件包)。

# pkg autoremove

输出应该类似于以下内容:

Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 1 packages:

Installed packages to be REMOVED:
        ca_root_nss-3.83

Number of packages to be removed: 1

The operation will free 723 KiB.

Proceed with deinstalling packages? [y/N]:

作为依赖安装的软件包被称为 自动 软件包。非自动软件包,即明确安装而不是作为其他软件包的依赖项安装的软件包,可以使用以下命令列出:

# pkg prime-list

输出应该类似于以下内容:

nginx
openvpn
sudo

pkg prime-list 是在 /usr/local/etc/pkg.conf 中声明的一个别名命令。系统中还有许多其他命令可以用来查询软件包数据库。例如,命令 pkg prime-origins 可以用来获取上述列表的源 ports 目录。

# pkg prime-origins

输出应该类似于以下内容:

www/nginx
security/openvpn
security/sudo

这个列表可以用于使用构建工具(如 ports-mgmt/poudriereports-mgmt/synth)重新构建系统上安装的所有软件包。

将已安装的软件包标记为自动安装可以使用以下方法:

# pkg set -A 1 devel/cmake

一旦一个包是一个叶子包并且被标记为自动安装,它将被 pkg autoremove 命令选择删除。

将已安装的软件包标记为 自动安装可以使用以下方法:

# pkg set -A 0 devel/cmake

4.4.11. 移除过期的软件包

默认情况下,pkg 将二进制软件包存储在由 pkg.conf(5) 中的 PKG_CACHEDIR 定义的缓存目录中。只保留最新安装的软件包的副本。旧版本的 pkg 会保留所有先前的软件包。要删除这些过时的二进制软件包,请运行:

# pkg clean

可以通过运行以下命令来清除整个缓存:

# pkg clean -a

4.4.12. 锁定和解锁软件包

pkg-lock(8) 用于锁定包,防止重新安装、修改或删除。pkg-unlock(8) 用于解锁指定的包。无论哪种变体,都只对当前已安装的包产生影响。因此,除非安装新包意味着更新已锁定的包,否则无法通过此机制阻止新包的安装。

例如,要锁定 nginx-lite

# pkg lock nginx-lite

要解锁 nginx-lite

# pkg unlock nginx-lite

4.4.13. 修改软件包元数据

FreeBSD Ports Collection 中的软件可能会经历主版本号的更改。为了解决这个问题,pkg 有一个内置命令来更新软件包的来源。这在某些情况下非常有用,例如,如果 lang/python3 被重命名为 lang/python311 ,那么 lang/python3 现在可以表示版本 3.11

要更改上面示例的软件包来源,请运行以下命令:

# pkg set -o lang/python3:lang/python311

另一个例子是,要将 lang/ruby31 更新为 lang/ruby32,运行以下命令:

# pkg set -o lang/ruby31:lang/ruby32

在更改软件包来源时,重要的是重新安装依赖于已修改来源的软件包。要强制重新安装依赖软件包,请运行:

# pkg install -Rf lang/ruby32

4.5. 使用 Ports 集合

Ports Collection 是一组 Makefiles、补丁和描述文件。每组这些文件用于在 FreeBSD 上编译和安装单个应用程序,被称为一个 ports

默认情况下,Ports Collection 本身存储在 /usr/ports 的子目录中。

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

Ports 集合包含了软件类别的目录。每个类别中都有针对个别应用程序的子目录。每个应用程序子目录包含一组文件,告诉 FreeBSD 如何编译和安装该程序,称为 ports skeleton。每个 ports 骨架包括以下文件和目录:

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

  • distinfo:包含构建 ports 所需下载的文件的名称和校验和。

  • files/:这个目录包含了在 FreeBSD 上编译和安装程序所需的补丁文件。这个目录也可能包含其他用于构建 ports 的文件。

  • pkg-descr:提供程序的更详细描述。

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

一些 ports 包括 pkg-message 或其他文件来处理特殊情况。有关这些文件以及 ports 的更多详细信息,请参考 FreeBSD Porter’s Handbook

ports 不包含实际的源代码,也称为 `distfile` 。构建 ports 的提取部分将自动将下载的源代码保存到 `/usr/ports/distfiles`。

4.5.1. 安装 Ports 集合

在使用 ports 编译应用程序之前,必须先安装 ports 集合。如果在安装 FreeBSD 时没有安装它,请使用以下方法之一进行安装:

过程:Git 方法

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

  1. 在使用 Git 检出 ports 树之前,必须先安装 Git 。如果已经存在一个 ports 树的副本,请按照以下方式安装 Git :

    # cd /usr/ports/devel/git
    # make install clean

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

    # pkg install git
  2. 检出 ports 树的 HEAD 分支的副本:

    # git clone https://git.FreeBSD.org/ports.git /usr/ports
  3. 或者,检出一个季度分支的副本:

    # git clone https://git.FreeBSD.org/ports.git -b 2023Q1 /usr/ports
  4. 在初始的 Git 检出之后,根据需要更新 /usr/ports

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

    # git -C /usr/ports switch 2023Q1

4.5.2. 安装 Ports

本节提供了使用 Ports Collection 安装或删除软件的基本说明。有关可用的 make 目标和环境变量的详细描述,请参阅 ports(7)

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

使用 Ports 集合需要一个正常的互联网连接。它还需要超级用户权限。

要编译和安装 ports,请切换到要安装的 ports 的目录,然后在提示符下键入 make install。消息将指示进度:

# cd /usr/ports/sysutils/lsof
# make install
>> lsof_4.88D.freebsd.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
>> Attempting to fetch from ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/.
===>  Extracting for lsof-4.88
...
[extraction output snipped]
...
>> Checksum OK for lsof_4.88D.freebsd.tar.gz.
===>  Patching for lsof-4.88.d,8
===>  Applying FreeBSD patches for lsof-4.88.d,8
===>  Configuring for lsof-4.88.d,8
...
[configure output snipped]
...
===>  Building for lsof-4.88.d,8
...
[compilation output snipped]
...

===>  Installing for lsof-4.88.d,8
...
[installation output snipped]
...
===>   Generating temporary packing list
===>   Compressing manual pages for lsof-4.88.d,8
===>   Registering installation for lsof-4.88.d,8
===>  SECURITY NOTE:
      This port has installed the following binaries which execute with
      increased privileges.
/usr/local/sbin/lsof
#

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

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

在安装过程中,会创建一个工作子目录,其中包含编译过程中使用的所有临时文件。删除此目录可以节省磁盘空间,并在以后升级到新版本的 ports 时最大程度地减少问题的可能性。

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

为了避免这个额外的步骤,编译 ports 时可以使用 make install clean

4.5.2.1. 自定义 ports 安装

一些 ports 提供构建选项,可以用于启用或禁用应用程序组件,提供安全选项或允许其他自定义。示例包括 www/firefoxsecurity/gpgme。如果该 ports 依赖于具有可配置选项的其他 ports,则默认行为是提示用户从菜单中选择选项,因此可能会多次暂停以进行用户交互。为了避免这种情况,并在一个批处理中进行所有配置,请在 ports 骨架中运行 make config-recursive。然后,运行 make install [clean] 来编译和安装该 ports。

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

在构建 ports 后,有几种方法可以重新访问 ports 的构建选项菜单,以添加、删除或更改这些选项。一种方法是进入包含 ports 的目录,然后输入 make config 命令。另一种选择是使用 make showconfig 命令。还可以执行 make rmconfig 命令,该命令将删除所有已选择的选项,并允许您重新开始。所有这些选项以及其他选项都在 ports(7) 中详细解释。

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

对于不能始终连接到互联网的用户,可以在 /usr/ports 目录下运行 make fetch 命令,以获取所有的 distfiles,或者在某个分类目录(例如 /usr/ports/net)或特定的 ports 骨架中运行。请注意,如果一个 ports 有任何依赖项,那么在分类目录或 ports 骨架中运行此命令将不会获取来自其他分类的 ports 的 distfiles。相反,使用 make fetch-recursive 命令也可以获取 ports 的所有依赖项的 distfiles。

在极少数情况下,例如当组织拥有本地的 distfiles 仓库时,MASTER_SITES 变量可以用于覆盖 Makefile 中指定的下载位置。在使用时,请指定替代位置:

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

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

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

将 ports 编译在 /usr/home/example/ports 目录下,并将所有内容安装在 /usr/local 目录下。

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

将 ports 编译在 /usr/ports 中,并将其安装在 /usr/home/example/local 中。并且:

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

将两者合并。

这些也可以设置为环境变量。请参考您所使用的 shell 的手册页面,了解如何设置环境变量的指令。

4.5.3. 移除已安装的 ports

使用 pkg delete 命令可以卸载已安装的 ports。有关使用此命令的示例,请参阅 pkg-delete(8) 手册页。

或者,可以在 ports 的目录中运行 make deinstall 命令:

# cd /usr/ports/sysutils/lsof
# make deinstall
===>  Deinstalling for sysutils/lsof
===>   Deinstalling
Deinstallation has been requested for the following 1 packages:

	lsof-4.88.d,8

The deinstallation will free 229 kB
[1/1] Deleting lsof-4.88.d,8... done

建议在卸载 ports 之前阅读消息。如果该 ports 有任何依赖于它的应用程序,这些信息将被显示,但卸载将继续进行。在这种情况下,重新安装应用程序可能更好,以防止依赖关系破裂。

4.5.4. 升级 ports

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

要确定已安装的 ports 是否有更新版本可用,请确保安装了最新版本的 ports 树,使用在 "Git Method" 中描述的更新命令。以下命令将列出已过时的已安装 ports:

# pkg version -l "<"

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

4.5.4.1. 升级和管理 ports 的工具

Ports Collection 包含多个实际执行升级的实用工具。每个工具都有其优点和缺点。

从历史上看,大多数安装使用的是 Portmaster 或 Portupgrade 。Synth 是一种较新的替代方案。

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

4.5.4.2. 使用 Portmaster 升级 Ports

ports-mgmt/portmaster 是一个非常小的工具,用于升级已安装的 ports。它旨在使用安装在 FreeBSD 基本系统中的工具,而不依赖其他 ports 或数据库。要将此实用程序安装为一个 ports:

# cd /usr/ports/ports-mgmt/portmaster
# make install clean

Portmaster 定义了四个 ports 的分类:

  • Root ports:没有依赖项,也不是任何其他 ports 的依赖项。

  • Trunk ports:没有依赖项,但其他 ports 依赖于它。

  • Branch ports:具有依赖关系,其他 ports 依赖于它。

  • Leaf ports:具有依赖关系,但没有其他 ports 依赖于它。

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

# portmaster -L
===>>> Root ports (No dependencies, not depended on)
===>>> ispell-3.2.06_18
===>>> screen-4.0.3
        ===>>> New version available: screen-4.0.3_1
===>>> tcpflow-0.21_1
===>>> 7 root ports
...
===>>> Branch ports (Have dependencies, are depended on)
===>>> apache22-2.2.3
        ===>>> New version available: apache22-2.2.8
...
===>>> Leaf ports (Have dependencies, not depended on)
===>>> automake-1.9.6_2
===>>> bash-3.1.17
        ===>>> New version available: bash-3.2.33
...
===>>> 32 leaf ports

===>>> 137 total installed ports
        ===>>> 83 have new versions available

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

# portmaster -a

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

如果在升级过程中遇到错误,请在升级和重建所有 ports 时添加 -f

# portmaster -af

Portmaster 还可以用于在系统上安装新的 ports,在构建和安装新的 ports 之前升级所有依赖项。要使用此功能,请指定 Ports Collection 中 ports 的位置:

# portmaster shells/bash

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

4.5.4.3. 使用 Portupgrade 升级 ports

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

# cd /usr/ports/ports-mgmt/portupgrade
# make install clean

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

要升级系统上安装的所有过时 ports,请使用 portupgrade -a。或者,加入 -i 以便在每次单独升级时要求确认:

# portupgrade -ai

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

# portupgrade -R firefox

如果包含了 -P 选项,Portupgrade 会在 PKG_PATH 列出的本地目录中搜索可用的软件包。如果本地没有可用的软件包,它会从远程站点获取软件包。如果无法在本地或远程获取软件包,Portupgrade 将使用 ports。为了完全避免使用 ports,可以指定 -PP 选项。最后一组选项告诉 Portupgrade 如果没有可用的软件包则中止操作。

# portupgrade -PP gnome3

如果指定了 -P,只需获取 ports distfiles 或软件包,而不需要构建或安装任何内容,请使用 -F 。有关所有可用开关的更多信息,请参阅 `portupgrade 的手册页。

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

4.5.5. ports 和磁盘空间

使用 Ports Collection 会随着时间的推移占用磁盘空间。在构建和安装 ports 之后,在 ports 骨架中运行 make clean 将清理临时的 work 目录。如果使用 Portmaster 安装 ports,它会自动删除此目录,除非指定了 -K 选项。如果安装了 Portupgrade,此命令将删除在本地 Ports Collection 副本中找到的所有 work 目录:

# portsclean -C

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

# portsclean -D

Portupgrade 可以删除系统上当前未安装任何 ports 引用的所有 distfiles 文件。

# portsclean -DD

如果已安装 Portmaster,请使用:

# portmaster --clean-distfiles

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

除了这些命令之外,ports-mgmt/pkg_cutleaves 还可以自动化删除不再需要的已安装 ports 的任务。

4.6. 使用 poudriere 构建软件包

poudriere 是一个使用 BSD 许可证的实用工具,用于创建和测试 FreeBSD 软件包。它使用 FreeBSD jails 来设置隔离的编译环境。这些 jails 可以用于为与安装它的系统不同的 FreeBSD 版本构建软件包,也可以用于在主机是 amd64 系统的情况下构建 i386 的软件包。一旦软件包构建完成,它们的布局与官方镜像完全相同。这些软件包可以被 pkg(8) 和其他软件包管理工具使用。

poudriere 是使用 ports-mgmt/poudriere 包或 ports 进行安装的。安装过程中包含一个示例配置文件 /usr/local/etc/poudriere.conf.sample。将此文件复制到 /usr/local/etc/poudriere.conf。编辑复制的文件以适应本地配置。

虽然在运行 poudriere 的系统上不需要 ZFS,但它是有益的。当使用 ZFS 时,必须在 /usr/local/etc/poudriere.conf 中指定 ZPOOL,并将 FREEBSD_HOST 设置为附近的镜像。定义 CCACHE_DIR 可以启用 devel/ccache 来缓存编译并减少频繁编译代码的构建时间。将 poudriere 数据集放在挂载在 /poudriere 的隔离树中可能很方便。其他配置值的默认设置是足够的。

检测到的处理器核心数量用于定义并行运行的构建数量。请提供足够的虚拟内存,可以是 RAM 或者交换空间。如果虚拟内存耗尽,编译环境将停止并被销毁,导致出现奇怪的错误信息。

4.6.1. 初始化 Jails 和 Port Trees

配置完成后,初始化 poudriere,以便安装一个包含所需 FreeBSD 树和 ports 树的 jail。使用 -j 指定 jail 的名称,并使用 -v 指定 FreeBSD 版本。在运行 FreeBSD/amd64 的系统上,可以使用 -a 将架构设置为 i386amd64。默认架构为 uname 显示的架构。

# poudriere jail -c -j 13amd64 -v 13.1-RELEASE
[00:00:00] Creating 13amd64 fs at /poudriere/jails/13amd64... done
[00:00:00] Using pre-distributed MANIFEST for FreeBSD 13.1-RELEASE amd64
[00:00:00] Fetching base for FreeBSD 13.1-RELEASE amd64
/poudriere/jails/13amd64/fromftp/base.txz              125 MB 4110 kBps    31s
[00:00:33] Extracting base... done
[00:00:54] Fetching src for FreeBSD 13.1-RELEASE amd64
/poudriere/jails/13amd64/fromftp/src.txz               154 MB 4178 kBps    38s
[00:01:33] Extracting src... done
[00:02:31] Fetching lib32 for FreeBSD 13.1-RELEASE amd64
/poudriere/jails/13amd64/fromftp/lib32.txz              24 MB 3969 kBps    06s
[00:02:38] Extracting lib32... done
[00:02:42] Cleaning up... done
[00:02:42] Recording filesystem state for clean... done
[00:02:42] Upgrading using ftp
/etc/resolv.conf -> /poudriere/jails/13amd64/etc/resolv.conf
Looking up update.FreeBSD.org mirrors... 3 mirrors found.
Fetching public key from update4.freebsd.org... done.
Fetching metadata signature for 13.1-RELEASE from update4.freebsd.org... done.
Fetching metadata index... done.
Fetching 2 metadata files... done.
Inspecting system... done.
Preparing to download files... done.
Fetching 124 patches.....10....20....30....40....50....60....70....80....90....100....110....120.. done.
Applying patches... done.
Fetching 6 files... done.
The following files will be added as part of updating to
13.1-RELEASE-p1:
/usr/src/contrib/unbound/.github
/usr/src/contrib/unbound/.github/FUNDING.yml
/usr/src/contrib/unbound/contrib/drop2rpz
/usr/src/contrib/unbound/contrib/unbound_portable.service.in
/usr/src/contrib/unbound/services/rpz.c
/usr/src/contrib/unbound/services/rpz.h
/usr/src/lib/libc/tests/gen/spawnp_enoexec.sh
The following files will be updated as part of updating to
13.1-RELEASE-p1:
[…]
Installing updates...Scanning //usr/share/certs/blacklisted for certificates...
Scanning //usr/share/certs/trusted for certificates...
 done.
13.1-RELEASE-p1
[00:04:06] Recording filesystem state for clean... done
[00:04:07] Jail 13amd64 13.1-RELEASE-p1 amd64 is ready to be used
# poudriere ports -c -p local -m git+https
[00:00:00] Creating local fs at /poudriere/ports/local... done
[00:00:00] Checking out the ports tree... done

在一台计算机上,poudriere 可以使用多个配置,在多个 jail 中,从不同的 ports 树构建 ports。这些组合的自定义配置被称为 集合。在安装了 ports-mgmt/poudriereports-mgmt/poudriere-devel 之后,可以查看 poudriere(8) 的 CUSTOMIZATION 部分获取详细信息。

这里显示的基本配置将一个单独的 jail、 port 和 set 特定的 make.conf 放置在 /usr/local/etc/poudriere.d 目录下。在这个示例中,文件名是通过组合 jail 名称、 port 名称和 set 名称创建的:13amd64-local-workstation-make.conf。系统的 make.conf 和这个新文件在构建时会合并,以创建构建 jail 使用的 make.conf 文件。

要构建的软件包应该在 13amd64-local-workstation-pkglist 文件中输入(具有 @FLAVOR 的 FLAVORS 的 ports 可以定义)。

editors/emacs
devel/git
devel/php-composer2@php82
ports-mgmt/pkg
...

已配置指定 ports 的选项和依赖项:

# poudriere options -j 13amd64 -p local -z workstation -f 13amd64-local-workstation-pkglist

最后,构建软件包并创建软件包仓库:

# poudriere bulk -j 13amd64 -p local -z workstation -f 13amd64-local-workstation-pkglist

在运行过程中,按下 Ctrl+t 键可以显示构建的当前状态。poudriere 还会在 /poudriere/logs/bulk/jailname 目录中构建文件,可以与 Web 服务器一起使用以显示构建信息。

完成后,新的软件包现在可以从 poudriere 仓库进行安装。

有关使用 poudriere 的更多信息,请参阅 poudriere(8) 和主要网站 https://github.com/freebsd/poudriere/wiki

4.6.2. 配置 pkg 客户端以使用 poudriere 仓库

虽然可以同时使用自定义仓库和官方仓库,但有时禁用官方仓库是有用的。这可以通过创建一个配置文件来覆盖和禁用官方配置文件来实现。创建 /usr/local/etc/pkg/repos/FreeBSD.conf 文件,其中包含以下内容:

FreeBSD: {
	enabled: no
}

通常,通过 HTTP 将 poudriere 仓库提供给客户机最为简单。设置一个 web 服务器来提供软件包目录,例如: /usr/local/poudriere/data/packages/13amd64,其中 13amd64 是构建的名称。

如果软件包仓库的 URL 是:http://pkg.example.com/13amd64,那么位于 /usr/local/etc/pkg/repos/custom.conf 的仓库配置文件将如下所示:

custom: {
	url: "http://pkg.example.com/13amd64",
	enabled: yes,
}

如果不希望将软件包仓库暴露在互联网上,可以使用 file:// 协议直接指向仓库:

custom: {
	url: "file:///usr/local/poudriere/data/packages/11amd64",
	enabled: yes,
}

4.7. 安装后的考虑事项

无论软件是从二进制包还是 ports 安装的,大多数第三方应用程序在安装后都需要进行一定程度的配置。以下命令和位置可用于帮助确定应用程序安装了什么。

  • 大多数应用程序都会在 /usr/local/etc 目录下安装至少一个默认配置文件。在应用程序有大量配置文件的情况下,会创建一个子目录来存放它们。通常,会安装一些以 .sample 后缀结尾的示例配置文件。应该审查并可能编辑这些配置文件以满足系统的需求。要编辑示例文件,首先将其复制并去掉 .sample 扩展名。

  • 提供文档的应用程序会将文档安装到 /usr/local/share/doc 目录下,许多应用程序还会安装手册页。在继续之前,应该先查阅这些文档。

  • 一些应用程序运行的服务在启动应用程序之前必须添加到 /etc/rc.conf 中。这些应用程序通常会在 /usr/local/etc/rc.d 中安装一个启动脚本。有关更多信息,请参阅 启动服务

    根据设计,应用程序在安装时不会运行启动脚本,也不会在卸载或升级时运行停止脚本。这个决定留给了个别系统管理员来决定。

  • 使用 csh(1) 的用户应该运行 rehash 命令来重新构建 shell 的 PATH 中已知的二进制文件列表。

  • 使用 pkg info 命令来确定应用程序安装了哪些文件、man 页面和二进制文件。

4.8. 处理损坏的 ports

当 ports 无法构建或安装时,请尝试以下操作:

  1. 搜索一下 Problem Report database 中的 ports 是否有待修复的问题报告。如果有的话,实施建议的修复可能会解决这个问题。

  2. 向 ports 的维护者寻求帮助。在 ports 骨架中键入 make maintainer,或者阅读 ports 的 Makefile 以找到维护者的电子邮件地址。记得在发送给维护者的电子邮件中包含错误之前的输出。

    一些 ports 不是由个人维护,而是由一个由邮件列表表示的团队维护者维护。其中许多(但不是全部)地址看起来像 [email protected]。在发送电子邮件时,请考虑这一点。

    特别是,由 [email protected] 维护的 ports 不由特定个人维护。相反,任何修复和支持都来自订阅该邮件列表的广大社区。我们始终需要更多的志愿者!

    如果没有收到邮件回复,请按照 Writing FreeBSD Problem Reports 中的说明,使用 Bugzilla 提交错误报告。

  3. 修复它! Porter’s Handbook 包含了有关 ports 基础设施的详细信息,以便您可以修复偶尔出现的损坏 ports,甚至提交您自己的 ports!

  4. 按照 使用 pkg 进行二进制包管理 中的说明安装软件包,而不是使用 ports。


上次修改时间: September 18, 2024 by fiercex