分类: BSD
2006-08-08 23:31:21
好了, 也许工作没那么简单, port 需要做些修改才能够在 FreeBSD 上跑起来。 在这一章里, 我们将会一步步举例来介绍应该如何修改来使您的 port 能在 FreeBSD 上面运行。
首先, 这一系列的动作是由用户在您的 port 目录里敲入 make 后发生的。 您也许会发现在另外的一个窗口里阅读一下 bsd.port.mk 将会有助于您的理解。
要是您不是非常明白 bsd.port.mk 是做什么的话, 也不用太担心, 很多人都不知道的... :->
fetch 会首先被执行。 fetch 将检查在本地的 DISTDIR 目录里是否存在 tar 包。 如果 fetch 没有找到就会查找 Makefile 中定义的 MASTER_SITES URL, 还有我们的主 FTP 站点 , 在那里我们备份了所有被认可的 distfile。 假设那个 MASTER_SITES 站点是直接连在 Internet 上的, 就会试着用 FETCH 指定的程序取回 distfile。 如果成功的话, 文件会被保存在DISTDIR 所指定的目录以备稍后使用。
接下来会执行 extract。 它会在 DISTDIR 中寻找您的 tar 包 (通常是用 gzip 压缩的 tar 包),然后解压缩到由 WRKDIR 所指定的临时目录里 (默认为work目录)。
下一步是执行 patch。 首先任何在 PATCHFILES 中定义的补丁都会被打上。 然后, 在由 PATCHDIR 指定的目录 (默认为 files目录) 中发现的patch-*, 它们将会以文件名的字母顺序被先后打上。
configure会被执行。 这一步骤可能会有以下几种情形。
如果存在 scripts/configure, 就会执行它
如果定义了 HAS_CONFIGURE 或者 GNU_CONFIGURE, 就会执行 WRKSRC/configure。
如果定义了USE_IMAGE, 就会执行 XMKMF (默认为: xmkmf -a)。
build会被执行。 这一步将会进入ports的工作目录 (WRKSRC) 然后进行编译。如果定义了USE_GMAKE, 就会使用 GNU make, 反之, 则会使用系统默认的 make。
以上都是系统默认的步骤。 您也可以定义 pre-something 或者 post-something, 或者把以此命名的脚本放到 scripts 目录, 它们会在默认的动作之前或之后被执行。
举个例子, 如果您在您的 Makefile 里定义了post-extract, 并在 script 目录里放了一个 pre-build 脚本, 那么在 tar 包解开之后 post-extract 将被调用, pre-build 脚本会在默认的编译之前被执行。 我们推荐您在 Makefile 定义所有的动作, 如果不是十分复杂的话, 这样, 别人能更容易明白您的 port 需要执行哪些非默认的动作。
默认的行为都是由 bsd.port.mk 定义的 do-something 来表示的。 例如, port 中用来解压缩的命令是由 do-extract 来定义的。 如果您对默认的设置不满意, 可以通过在 Makefile 重新定义 do-someting 来做些改变。
注意: “主” 动作 (例如 extract、 configure, 等等) 仅仅是用来确定所有相应的阶段都完成了, 以及调用真实的动作或脚本, 它们不应被修改。 如果您想要修改解压缩这个动作, 可以修改 do-extract, 但永远都不要改变 extract 的操作!
我们已经介绍了在用户敲入 make 之后会发生哪些事情了。 接下来我们将进行进一步的学习, 来看一看如何创建一个理想的 port。
获取源代码的 tar 包 (通常是 foo.tar.gz 或者 foo.tar.Z) 并把它们放进 DISTDIR。 最好使用 主流 的版本。
您需要设置变量 MASTER_SITES 来指向原始 tar 包的获取位置。 您可以在 bsd.sites.mk 里找到一些速度较快的主流站点。 请使用这些站点 ── 和相关的定义 ── 如果可能的话, 应尽量避免在同一个源代码树里出现大量重复的信息。 这些站点会随着时间而变化, 如果每个人都随意加入的话会使维护变得非常困难。
如果您找不到一个有很好网络连接的 FTP/HTTP 站点, 或者它们使用了非标准的格式, 您也许就会想在您自己的 FTP 或 HTTP 服务器上放上一份副本。
如果您找不到可靠的地方放置 distfiles, 我们也可以提供给您一些空间来保存它。 我们自己的 ftp.FreeBSD.org; 然而这只是一个折衷的办法。 distfile 必须放进某人在 freefall 上的 ~/public_distfiles/ 目录中。 可以要求帮助您 commit port 的人来放这个 distfile, 而这个人也需要把 MASTER_SITES、 MASTER_SITE_LOCAL 以及 MASTER_SITE_SUBDIR 的设置, 改为在 freefall 上的用户名。
如果您的 port 的 distfile 一直在变化, 而作者拒绝改变其版本号, 您可以考虑把 distfiles 放在自己的主页, 并在 MASTER_SITES 里把原作者的列为首选位置。 如果可能, 试着与 port 的作者沟通一下让他不要这么做, 这将有助于建立对源代码的控制。 在您的主页上放置您自己的 distfile 会避免用户得到 “checksum mismatch” 的错误, 而且能减轻我们 FTP 站点维护人员的工作量。 如果您的port只有一个主站点的话, 我们建议您在自己的网站上做一份备份, 并他列为 MASTER_SITES的第2项。
如果您的 port 需要来自网络上的一些补丁, 请把它们放到 DISTDIR里。 不用担心它们跟源代码不是来自同一站点。 我们有办法处理 (参阅下面的 )。
解开 tar 包, 对源代码做出合理的修改使得这个 port 能在最新版本的 FreeBSD 上面运行。 一定要 仔细记录 您所做的每处改动, 包括删除、添加、修改的文件等等, 这些修改以后会在您的 port 中以脚本或补丁的方式出现, 并且能通过运行它们来自动完成您对 port 的改动要求。
如果您的 port 要求用与用户交互/配置来完成编译或安装的话, 您可以看一下 Larry Wall
的经典的 Configure 脚本, 适当地模仿一下。 Port collection
的目的, 就是使每个 port 占用最少的空间, 并做到软件的 “即插即用”。
在您准备制作 port 的过程中, 增加或修改的文件, 都可以通过 来做成补丁。 希望应用到源代码上的每个补丁, 都应保存为单独的文件, 并命名为 patch-*, 其中 * 表示将要修改的文件的完整路径名, 例如 patch-Imakefile 或 patch-src-config.h。 这些文件, 都应保存在 PATCHDIR (通常是 files/), 这里的补丁都会自动应用到源代码上。 所有的补丁必须是相对于 WRKSRC 的 (一般而言, 您的 port 会将其 tarball 解压缩在那里, 并完成余下的工作)。 为了让修正和升级更容易, 您应避免使用多个 patch 去修改同一个文件 (例如, patch-file 以及 patch-file2 都修改 WRKSRC/foobar.c) 这种情况。
只有 [-+._a-zA-Z0-9] 这些字符, 可以出现在补丁的文件名中, 请务必不要使用除这些字符以外的其它字符。 不要把您的补丁命名成 patch-aa 或 patch-ab 等这样的名字, 最好能在补丁名中提到路径和文件名。
不要把 RCS 字符串放进补丁。 我们把文件放进 ports 树的时候, CVS 会损坏它们, 当我们再 check out 出来的时候, 它们就会和原来的不一样, 从而导致打补丁失败。 RCS 字符串 是由美元符号 ($) 围绕的, 通常由 $Id 或 $RCS 开头。
使用
的递归选项(-r
) 很好, 但是请检查一下最后输出的 patch,
确保没有任何的垃圾信息。 特别地, 有 2 种文件不需要 diff, 并且应该删除: 一种是 Makefile, 当您的port使用了Imake, 或者
GNU configure 等等的话。 如果您不得不编辑configure.in 以使 autoconf 去生成 configure, 不要使用 configure 来做 diff
(这常常会有好几千行长!); 请定义 USE_AUTOTOOLS=autoconf:253
并对应 configure.in 来制作 diff。
假如需要删除文件, 则应在 post-extract target, 而不是作为补丁的一部分来完成。
除此之外, port 的 Makefile 还可以通过 in-place 模式的 来直接进行简单的替换操作。 如果补丁需要使用变量值, 这就非常有用了。 例如:
post-patch:
@${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README
@${REINPLACE_CMD} -e 's|-pthread|${PTHREAD_LIBS}|' ${WRKSRC}/configure
往往在移植某些软件的时候会遇到这样一种情况, 特别是这个软件是在 Windows® 上开发的时候, 大多数的源代码都需要进行CR/LF的转换。 这很可能会给以后打补丁带来问题, 还可能触发编译警告, 并给脚本的执行带来麻烦 (/bin/sh^M not found), 等等。 要迅速将所有文件中的 CR/LF 改为只用 LF, 可以在 port 的 Makefile 中加入 USE_DOS2UNIX=yes。 除此之外, 还可以指定一个需要执行这种转换操作的文件列表:
USE_DOS2UNIX= util.c util.h
把任何附加的配置命令加进您的 configure 脚本并把它保存到 scripts 子目录。 如前面提到的那样, 您也能在 Makefile 和/或 使用 pre-configure 或 post-configure 的脚本来做同样的事情。
如果您的 port 要求用户的输入以便配置编译、 或安装配置过程, 就必须在 Makefile 里设置 IS_INTERACTIVE 变量。 如果用户设置了 BATCH 的话, 这将让用户能跳过您的 port 来完成 “通宵编译” (如果用户设置了 INTERACTIVE的话, 那么 只有 那些要求互动的 port 才会被编译) 这将给那些不停编译 ports 的机器省下很多时间。
通常我们还建议, 如果对于那些问题能有合理的缺省答案的话, 应检查一下 PACKAGE_BUILDING 变量, 并根据其设置决定是否执行关闭交互脚本。 这将允许我们为 CDROM 和 FTP 来编译 package。