5.5 使用 Ports 以源代码方式安装软件

Ports 与 Port 概述

Ports 历史

Ports 是一种简单的从源代码(也支持闭源的二进制包)构建软件的框架。由 Jordan K. Hubbard([email protected])创建,最初在公众面前出现于 1994 年 8 月。

root@ykla:/usr/ports # git log --reverse --max-parents=0 --pretty=format:"commit: %h%nAuthor: %an%nDate: %ci%n%n%B" # 打印第一次提交
commit: d27f048e966a
Author: Jordan K. Hubbard
Date: 1994-08-21 13:12:57 +0000

Commit my new ports make macros.  Still not 100% complete yet by any means
but fairly usable at this stage.
Submitted by:   jkh

“提交了我为 ports 编写的新 Make 宏。虽然还远未完全完善,但目前已经可以较为正常的使用了。”

技巧

我们可以看到:对于一个开源项目,无论使用的何种版本控制系统,保留完整的提交记录,是多么地重要。读者慢慢就会发现,这不仅仅是考古上的意义。

NetBSD 和 OpenBSD 也使用 Ports(不通用)。

参考文献

Ports 与 Port 释义

一款软件的相关文件或文件夹的(补丁文件、校验码、Makefile 等)集合(表现为一个文件夹)为一个 Port,所有 Port(移植软件)的集合即 Ports Collection 或 Ports Tree,即 Ports。

  • /usr/ports 这个文件夹整体称作 Ports,包括几十种不同的分类目录,每个目录下有若干 Port。

  • /usr/ports/databases/postgresql18-server 这个文件夹整体称作一个 Port,由 distinfo(校验和文件)、pkg-descr(软件描述文件)、Makefile(主文件,里面有构建方法和版本号及下载方式等)pkg-plist(安装的每个文件的列表清单文件及文件权限属组等)files(一般是补丁,该 Port 下为安装后的说明文件 pkg-message)等文件构成。

之所以叫做“Ports Collection”,移植集合(不应理解为端口集合,参见 What does 'port' mean in 'develop a port of BSD'?,注:此来源不可信,请求其他来源)是因为这些软件绝大部分都不由 FreeBSD 控制、管理、和维护,Port 提交者主要做的事情是将 FreeBSD 上 Port 更新到上游开发者提供的最新版本,删除上游不再维护的软件 Port。在上游不接受 BSD 特有的 PR 补丁或难以直接通过既有 Ports 框架实现构建的情况下,Port 维护者也需要自行复刻一个分支出来维护(如 editors/vscode)。

Ports 构建 pkg 软件包的流程

注意

ports 和 pkg 可以同时使用,而且大部分人也是这么用的。但是要注意 pkg 的源必须是 latest,否则会存在一些依赖上的问题(比如 ssl)。latest 的源也比 main 上的 ports 要出来的晚(是从 main 编译出来的),因此即使是 latset 源也可能会出现上述问题,总之有问题出现时就卸载那个 pkg 安装的包,重新使用 ports 编译即可。

警告

需要对上面的“注意”进行补充说明的是:一旦你使用了 make config 修改了 Port 的默认构建参数(进行了自定义),那么如果你仍然想保留该设置,后续的软件更新是不能通过 pkg 进行管理的,否则通过 pkg 安装的软件包会完全取代之前自定义的 Port(即 Port 开发者默认设定的构建参数将覆盖你自定义的 Port 参数)。

Ports 流程图

技巧

ports 下载路径是 /usr/ports/distfiles/

使用 ports 压缩包

使用压缩包成功地规避了先有鸡还是先有蛋的哲学问题(要安装 Git 但是没有 Ports 也不想用 pkg 的话)。

下载 ports 压缩包

  • NJU:

  • 或 USTC

  • 又或 FreeBSD 官方

解压 ports 压缩包

使用 Git 获取 Ports

安装 Git

  • 使用 pkg 安装:

拉取 Ports 存储库(USTC)浅克隆

拉取 Ports 存储库(FreeBSD 官方)浅克隆

完全拉取 Ports 存储库(FreeBSD 官方)并指定分支

查看所有分支:

切换到 2025Q1 分支:

查看本地分支:

已经切换成功。

同步更新 Ports Git

如果提示本地已经修改,放弃本地修改,再更新:

附录:时间错误导致的证书无效

先检查时间:

时间错误。校对时间:

检查时间:

使用 whereis 查询软件路径

将输出

查看依赖

已经安装:

未安装:

看看 python 的 ports 在哪

安装 python3

其中 BATCH=yes 意味着使用默认参数进行构建。

如何设置全部所需的依赖

如何使用 pkg 安装依赖

不使用 Ports 来编译依赖,仅使用 Ports 来编译软件包本体:

chinese/fcitx 为示例:

如何删除当前 port 及其依赖的配置文件

如何一次性下载所有需要的软件包

ports 编译的软件也可以转换为 pkg 包

更新 FreeBSD 软件包/Port

先同步更新 Ports Git。

然后列出过时 Port 软件:

下边分别列出 2 种 FreeBSD 手册中提及的升级工具:

① portmaster(推荐)

  • 更新:

如果不想回答问题解决依赖,可使用类似 BATCH=yes 的选项 -a -G --no-confirm

查看依赖关系

② portupgrade

参考资料

FreeBSD USE

  • 如何全局屏蔽 mysql

完整的列表见 https://cgit.freebsd.org/ports/tree/Mk/bsd.default-versions.mk

FreeBSD ports 多线程编译

将以下内容写入 /etc/make.conf,没有就 touch 新建一个。

Linux 如 Gentoo 上一般是直接 -jx 或者 jx+1, x 为核心数。

4 是处理器核心数(还是线程数?)。

可以通过命令查询:

或者:

输出值即为 MAKE_JOBS_NUMBER 值。

英特尔的处理器搜索 CPU 型号+ARK 转跳英特尔官网可查询线程数。

  • 个别情况下可以设置别名加速编译:(非永久设置,FreeBSD 14 无须设置默认即生效)

参考资料

设置内存为 tmp

写入:

reboot 重启即可。

参考资料

ccache

警告

使用 ccache 可能会导致编译失败!只在重复编译时起效果,首次编译不仅不会加速还会慢上一些。是一种以空间换时间的行为。

ccache3

使用 pkg 安装:

  • 使用 Ports 安装:

  • 查看软链接情况:


  • 修改 /etc/make.conf,加入下面一行:

  • 设置编译缓存最大为 10GB:

  • 在 Ports 编译一段时间后:

ccache4

目前最新版本是 ccache4:

使用 pkg 安装:

或使用 Ports 安装:

  • 查看软链接情况:


  • 修改 /etc/make.conf,加入下面一行:

  • 设置编译缓存最大为 20GB:

  • 在 Ports 编译一段时间后,查看编译缓存:

查看当前配置文件:

参考文献

多线程下载

axel

安装:

或者

新建或者编辑 /etc/make.conf 文件,写入以下几行:

wget2

新建或者编辑 /etc/make.conf 文件,写入以下几行:

  • -c 断点续传;

  • -t 3 重试次数 3;

  • -o 10 启用 10 个线程进行下载。

技巧

10 这个参数可能过于保守。但是要注意很多服务器不支持较多线程同时下载。同时会给服务器带来较大压力。

参考文献

故障排除与未竟事宜

autoconf-2.72 Invalid perl5 version 5.42.

也可以理解为“xxx-yy Invalid zz version aa”式报错。

实例,在使用 Ports 安装 openjdk21 时报错如下:

观察整个流程可以发现,openjdk21 依赖 autoconf,但系统中没有。于是递归查找 autoconf 的依赖,发现 autoconf 依赖 perl5;结合 ② 可以发现系统中已有 perl5,但是报错“Invalid version”,即 perl5 的版本不对。

此问题,一般需要先更新 Ports,然后再通过 pkg install -f perl5pkg upgrade 来更新一下 perl5 的版本即可解决。

参考文献

最后更新于

这有帮助吗?