5.7. 依赖关系
上一页 | 第 5 章 配置 Makefile | 下一页

## 5.7. 依赖关系

许多 ports 会依赖其它 port。 这是包括 FreeBSD 在内的多数 类-Unix 系统的很方便的功能。 这项功能， 可以避免在每个 port 或预编译包中都带上重复的依赖的代码， 而可以以依赖关系的方式去共享它们。 有七个变量用于帮助您确保所需的文件都存在于用户的机器上。 此外， 也提供了用于支持常见情形的依赖关系变量， 以及对依赖关系行为的更多控制。

### 5.7.1. `LIB_DEPENDS` (依赖的函数库/共享库)

这个变量用于指定 port 所依赖的共享库。 其内容是由一系列 `lib`:`dir`[`:target`] 元组构成的表， 其中 `lib` 是共享库的名字， 而 `dir` 则是在找不到时应该从哪里联编和安装， 最后， `target` 用于指定在那个目录中调用的 target。 例如，

LIB_DEPENDS= jpeg.9:${PORTSDIR}/graphics/jpeg

会检测主版本号为 9 的 jpeg 共享库， 如果它不存在， 则会进入到您的 ports 目录中的 `graphics/jpeg` 子目录， 并联编和安装它。 如果您指定的 `target` 就是 `DEPENDS_TARGET` (默认是 `install`)， 则可以略去不写。

### 注意:

`lib` 部分是一个正则表达式， 用于在 `ldconfig -r` 的输出中进行查找。 可以使用类似 `intl.[5-7]` 和 `intl` 这样的值。 前一种模式， 即 `intl.[5-7]`， 能够匹配 `intl.5`、 `intl.6` 和 `intl.7` 中的任意一个。 第二种模式， 即 `intl` 则可以匹配任意版本的 `intl` 库。

依赖关系会被检测两次， 一次是在 `extract` target 中， 而另一次则是在 `install` target。 另外， 依赖关系的名字会放到 package 中， 以便让 pkg_add(1) 能够自动地在用户系统上安装所需的未安装的其它 package。

### 5.7.2. `RUN_DEPENDS` (依赖的运行环境)

这个变量可以用来指定 port 在运行时所需要的可执行文件， 以及资源文件。 它是一系列 `path`:`dir`[`:target`] 元组的列表， 这里， `path` 时所需的可执行， 或者资源文件的名字， `dir` 是在无法找到这些文件或目录时， 去什么地方完成联编和安装以便获得这些文件； 而 `target` 则用来指定在这个目录中所调用的 target 的名字。 假如 `path` 以斜线 (`/`) 开始， 则会当作普通文件， 使用 `test -e` 来测试； 反之， 则系统会假定这是一个可执行文件， 并且用 `which -s` 来检测程序是否存在于搜索路径中。

例如，

RUN_DEPENDS= ${LOCALBASE}/etc/innd:${PORTSDIR}/news/inn \ xmlcatmgr:${PORTSDIR}/textproc/xmlcatmgr

将检查文件， 或者目录 `/usr/local/etc/innd` 是否存在， 如果找不到， 则将从 port 目录的 `news/inn` 子目录加以安装。 系统也会检查是否能够在搜索路径中找到名为 `xmlcatmgr` 的文件， 如果找不到的话， 则会进入 ports 目录中的 `textproc/xmlcatmgr` 子目录， 并进行联编和安装的操作。

### 注意:

这种情况下， `innd` 实际上是一个可执行文件； 如果可执行文件不会出现在搜索路径中， 您就需要指定完整路径了。

### 注意:

ports 联编集群上官方的搜索 `PATH` 是

/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin

这个依赖关系会在 `install` target 的过程中进行检查。 此外， 依赖关系的名字会被放到 package 中， 以便 pkg_add(1) 能够在用户的系统中尚未安装相关软件时自动地安装那些 package。 如果您希望指定一个的 `target` 和默认的 `DEPENDS_TARGET` 相同， 则可以略去不写。

一种比较常见的情形是 `RUN_DEPENDS` 和 `BUILD_DEPENDS` 完全一样， 这种情况在移植的软件是采用脚本语言书写， 或联编环境与运行环境需求相同时尤其普遍。 这种情况可以用下面简单明了的方式直接将其中一个变量赋值给另一个变量：

RUN_DEPENDS= ${BUILD_DEPENDS}

不过， 这种赋值有可能会令运行环境被某些没有在 port 原本的 `BUILD_DEPENDS` 明确定义的依赖关系污染。 导致这种情况的原因是 make(1) 计算变量赋值时默认采用的是延后计算 (lazy evaluation)。 例如， 如果在 `Makefile` 中使用了 `USE_`*`` 变量， 这些变量就会由 `ports/Mk/bsd.*.mk` 处理， 并填写与之对应的联编依赖关系。 例如， `USE_GMAKE=yes` 会把 `devel/gmake` 加入到 `BUILD_DEPENDS`。 如果希望避免这些附加的依赖关系污染 `RUN_DEPENDS`， 在使用赋值的时候就需要小心考虑这类扩展的情况， 例如， 可以在赋值展开之前复制变量的值：

RUN_DEPENDS:= ${BUILD_DEPENDS}

### 5.7.3. `BUILD_DEPENDS` (依赖的联编环境)

此变量用于指定用来联编 port 的可执行文件或资源文件。 与 `RUN_DEPENDS` 类似， 它是一个 `path`:`dir`[`:target`] 元组的列表。 例如，

BUILD_DEPENDS= unzip:${PORTSDIR}/archivers/unzip

将检测名为 `unzip` 的可执行文件是否存在， 如果不存在， 则会进入到您的 ports 目录中的 `archivers/unzip` 并完成联编和安装工作。

### 注意:

这里的 “build” 表示从解压缩到编译的全部过程。 依赖关系是在 `extract` target 的过程中检测的。 假如您要指定的 `target` 和 `DEPENDS_TARGET` 相同， 则可以略去不写。

### 5.7.4. `FETCH_DEPENDS` (依赖的下载环境)

这一变量用于指定 port 在下载时所需的可执行文件或资源文件。 和前两个类似， 它是一组 `path`:`dir`[`:target`] 元组。 例如，

FETCH_DEPENDS= ncftp2:${PORTSDIR}/net/ncftp2

将检测名为 `ncftp2` 的可执行文件是否存在， 如果找不到， 则将进入到您 ports 目录中的 `net/ncftp2` 子目录并加以联编和安装。

这个依赖关系是在 `fetch` target 过程中检查的。 如果与 `DEPENDS_TARGET` 相同， 则可以省略 `target` 部分。

### 5.7.5. `EXTRACT_DEPENDS` (依赖的解压缩环境)

此变量用于指定 port 在解压缩时所需的可执行文件或其它资源文件。 和前一个变量类似， 它是一系列 `path`:`dir`[`:target`] 元组的列表。 例如，

EXTRACT_DEPENDS= unzip:${PORTSDIR}/archivers/unzip

将检查名为 `unzip` 的可执行文件是否存在， 如果不存在， 则会进入到您的 ports 目录中的 `archivers/unzip` 子目录， 予以联编和安装。

这个依赖关系是在 `extract` target 的过程中检查的。 如果与 `DEPENDS_TARGET` 相同， 则可以略去 `target` 部分。

### 注意:

只有在其它方式都不可用 (默认是 `gzip`) 而且无法通过 第 5.7.7 节 “`USE_`*``” 所介绍的 `USE_ZIP` 或 `USE_BZIP2` 都不能达到需要时， 才应使用这个变量。

### 5.7.6. `PATCH_DEPENDS` (依赖的打补丁环境)

这个变量用于指定 port 在进行 patch 操作时所需的可执行文件或其它资源文件。 和前一个变量类似， 它是一组 `path`:`dir`[`:target`] 元组的表。 例如，

PATCH_DEPENDS= ${NONEXISTENT}:${PORTSDIR}/java/jfc:extract

表示进入到您的 ports 目录中的 `java/jfc` 子目录， 并将其解压缩。

这个依赖关系是在 `patch` target 的过程中检查的。 `target` 部分如果和 `DEPENDS_TARGET` 相同， 就可略去不写。

### 5.7.7. `USE_`*``

提供了一系列变量， 用以封装大量 port 都用到的依赖关系。 虽然使用这些变量是可选的， 但它们能显著减少 port 的 `Makefile` 复杂性。 这些变量的共同特征在于， 它们的名字都是 `USE_`*`` 这样的形式。 这些变量的使用， 应严格限制于 port 的 `Makefile` 以及 `ports/Mk/bsd.*.mk`， 而绝不应用于表达用户能够设置的选项 — 这种情况下应采用 `WITH_`*`` 和 `WITHOUT_`*`` 这样的变量。

### 注意:

在 任何 情况下， 都不应在 `/etc/make.conf` 中配置任何 `USE_`*``。 例如， 设置

USE_GCC=3.4

将导致每个 port 都依赖 gcc34， 甚至包括 gcc34 本身！

表 5.2. 常用的 `USE_`*`` 变量

变量 | 含义
--- | ---
`USE_BZIP2` | 此 port 的源码包是使用 `bzip2` 压缩的。
`USE_ZIP` | 此 port 的源码包是用 `zip` 压缩的。
`USE_BISON` | 此 port 在联编时使用 `bison`。
`USE_CDRTOOLS` | 此 port 需要使用 cdrecord， 根据用户的喜好， 可能是 `sysutils/cdrtools` 或 `sysutils/cdrtools-cjk`。
`USE_GCC` | 此 port 需要使用某一特定版本的 `gcc` 才能完成编译。 可以使用类似 `3.4` 这样的值来精确指定版本。 如果希望使用不低于某一版本的编译器， 则可以用 `3.4+` 这样的形式。 如果与所希望的版本吻合， 则将使用基本系统中所提供的 `gcc`， 反之， 系统会从 ports 中安装所希望版本的 `gcc`， 并调整 `CC` 以及 `CXX` 变量的设置。

与 gmake 和 `configure` 脚本有关的变量在 第 6.3 节 “联编机制” 中进行了介绍， 而 autoconf、 automake 以及 libtool 的介绍则可以在 第 6.4 节 “利用 GNU autotools” 找到。 第 6.6 节 “使用 `perl`” 介绍了与 Perl 有关的的变量。 第 6.7 节 “使用 X11” 中列出了关于 X11 的变量。 关于 GNOME 的变量在 第 6.8 节 “使用 GNOME”， 而关于 KDE 的则在 第 6.10 节 “使用 KDE”。 第 6.11 节 “使用 Java” 讲述了和 Java 有关的变量， 而 第 6.12 节 “Web 应用， Apache 和 PHP” 则包含了关于 Apache、 PHP 以及 PEAR 的介绍性信息。 关于 Python， 在 第 6.13 节 “使用 Python” 进行了讨论， 而关于 Ruby 的介绍， 则可以在 第 6.16 节 “使用 Ruby” 中找到。 第 6.17 节 “使用 SDL” 提供了用于 SDL 应用程序的变量介绍， 最后， 第 6.20 节 “使用 Xfce” 包含了关于 Xfce 的信息。

### 5.7.8. 在依赖关系中指定最低版本

在依赖某个其他 port 时， 可以采用下面的句法， 通过除 `LIB_DEPENDS` 之外的 `*_DEPENDS` 变量来指定最低版本：

p5-Spiffy>=0.26:${PORTSDIR}/devel/p5-Spiffy

第一个字段指明了所依赖 package 的名字， 用以与 package 数据库中的某项匹配， 然后是比较算符， 以及 package 的版本号。 前面的例子中， 如果系统中安装了 p5-Spiffy-0.26 则认为满足了依赖条件。

### 5.7.9. 关于依赖关系的补充说明

如前面所提到的那样， 在需要某一依赖的 port 时， 将调用 `DEPENDS_TARGET` 所指定的 target。 这一变量的默认值是 `install`。 这不是一个用户变量， 它不应在 port 的 `Makefile` 中予以定义。 如果您的 port 需要使用特殊的 target 来处理依赖关系， 应使用 `*_DEPENDS` 的 `:target` 部分， 而不是重定义 `DEPENDS_TARGET` 来完成。

当您输入 `make clean` 时， 其依赖的 port 也会自动进行清理。 如果您不希望如此， 应定义环境变量 `NOCLEANDEPENDS`。 如果 port 依赖一些重新联编需要花费很长时间的 port 时， 例如 KDE， GNOME 或 Mozilla 时， 这一方法会非常有用。

要无条件地依赖某个 port， 可以使用 `${NONEXISTENT}` 作为 `BUILD_DEPENDS` 或 `RUN_DEPENDS` 的第一部分。 只有在您需要使用其它 port 提供的源代码时才应这样做。 通常也可以通过这样指定来缩短编译所需的时间。 例如

BUILD_DEPENDS= ${NONEXISTENT}:${PORTSDIR}/graphics/jpeg:extract

表示依赖 `jpeg` port 并将其解压缩。

### 5.7.10. 循环的依赖关系是致命的

### 重要:

不要在 ports tree 中引入任何循环依赖关系!

ports 联编技术不能够容忍循环依赖关系。 如果您引入了这样的关系， 就一定会有人安装的 FreeBSD 会因此而损坏， 而且这种现象会越来越多。 这些情形很难检测； 如果有疑虑， 在进行这样的修改之前， 务必执行： `cd /usr/ports; make index`。 这个过程在旧的机器上会很慢， 但能够让大量的用户 — 也包括您自己 — 拯救于由这种问题所造成的困惑之中。

上一页 | 上一级 | 下一页
5.6. `COMMENT` (一句话说明) | 起始页 | 5.8. `MASTERDIR` (主 port 所在的目录)

本文档和其它文档可从这里下载： ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读 文档，如不能解决再联系 <questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.