这里列出了一些常见的注意事项和禁忌,这些在移植过程中经常遇到。将port与此列表进行对比,但也请检查 PR 数据库中他人提交的ports。按照“Bug Reports and General Commentary”中的描述提交任何关于ports的评论。检查 PR 数据库中的ports,这将使我们更快地提交它们,并证明你知道自己在做什么。
WRKDIR
不要向 WRKDIR 外的文件写入任何内容。 WRKDIR 是port构建过程中唯一保证可写的地方(参见从 CDROM 安装ports来了解从只读树构建ports的示例)。pkg-*文件可以通过重新定义变量而不是覆盖文件来修改。
WRKDIRPREFIX
确保port遵循 WRKDIRPREFIX 。大多数ports不必担心这一点。特别是,当引用另一个port的 WRKDIR 时,注意正确的位置是${WRKDIRPREFIX}${PORTSDIR}/subdir/name/work,而不是${PORTSDIR}/subdir/name/work 或${.CURDIR}/../../subdir/name/work 或其他类似的地方。
一些代码需要根据运行在哪个版本的 FreeBSD Unix 进行修改或条件编译。 区分 FreeBSD 版本的首选方法是在 sys/param.h 中定义的 __FreeBSD_version 和 FreeBSD 宏。如果没有包含此文件,请在.c 文件的适当位置添加代码,
到适当位置在.c 文件中。
FreeBSD 定义在所有版本的 FreeBSD 中作为它们的主要版本号。例如,在 FreeBSD 9.x 中, FreeBSD 被定义为 9 。
__FreeBSD_version 值的完整列表可在 _ _FreeBSD_version Values 中获得。
不要在 .include <bsd.port.mk> 行之后写任何内容。通常可以通过在 Makefile 的中间某处包含 bsd.port.pre.mk 来避免这种情况,然后在最后加上 bsd.port.post.mk。
bsd.port.pre.mk 只定义了一些变量,可以在 Makefile 中的测试中使用,bsd.port.post.mk 定义了其余部分。
这里是在 bsd.port.pre.mk 中定义的一些重要变量(这不是完整列表,请阅读 bsd.port.mk 获取完整列表)。
这里是一些可以在 bsd.port.pre.mk 之后添加的示例:
在 BROKEN= 之后始终使用制表符而不是空格。
如果port安装了一个shell脚本,其目的是启动另一个程序,并且如果启动该程序是脚本执行的最后一个操作,请确保使用 exec 语句启动该程序,例如:
exec 语句将shell进程替换为指定的程序。如果省略 exec ,则在程序执行时shell进程仍保留在内存中,并且会不必要地消耗系统资源。
Makefile 应该以简单和合理的方式做事。让它变得更短或更易读总是更好的。例如,使用 make .if 结构代替 shell if 结构,如果重新定义 EXTRACT* 足够的话不重新定义 do-extract ,并使用 GNU_CONFIGURE 而不是 CONFIGURE_ARGS += --prefix=${PREFIX} 。
如果需要大量新代码来做某事,可能已经在 bsd.port.mk 中有其实现。虽然难以阅读,但似乎有许多看似困难的问题,而 bsd.port.mk 已经提供了一个简便的解决方案。
port必须尊重 CC 和 CXX 。我们的意思是port不能绝对设置这些变量的值,覆盖现有的值;相反,它可以向现有值添加所需的值。这样可以全局设置影响所有ports的构建选项。
如果port不尊重这些变量,请将 NO_PACKAGE=ignores either cc or cxx 添加到 Makefile 中。
这是一个尊重 CC 和 CXX 的 Makefile 示例。请注意 ?= :
这是一个既不尊重 CC 也不尊重 CXX 的示例:
在 FreeBSD 系统上,可以在 /etc/make.conf 中定义 CC 和 CXX 。第一个示例在未在 /etc/make.conf 中先前设置值时定义一个值,保留任何系统范围的定义。第二个示例会覆盖之前定义的任何内容。
必须尊重 CFLAGS 。我们的意思是,port 不得绝对设置此变量的值,覆盖现有值。相反,它可以向现有值追加所需的任何值。这样可以全局设置影响所有 ports 的构建选项。
如果没有,请将 NO_PACKAGE=ignores cflags 添加到 Makefile。
这里是尊重 CFLAGS 的一个示例的 Makefile。请注意 += :
这是一个不尊重 CFLAGS 的示例:
CFLAGS 在 FreeBSD 系统中在 /etc/make.conf 中被定义。第一个示例将附加额外的标志到 CFLAGS ,保留任何系统范围的定义。第二个示例将覆盖先前定义的任何内容。
从第三方 Makefile 中删除优化标志。该系统 CFLAGS 包含全局系统优化标志。未修改的 Makefile 示例:
使用系统优化标志,Makefile 将类似于此示例:
使 port 构建系统在构建阶段显示所有执行的命令。完整的构建日志对调试 port 问题至关重要。
非信息性构建日志示例(不好):
冗长的构建日志示例(好):
一些构建系统,如 CMake、ninja 和 GNU configure,已经为ports框架设置了详细日志记录。在其他情况下,ports可能需要单独的调整。
请向上游维护者发送适用的更改和补丁,以便包含在下一个版本的代码发布中。这样做将使更新到下一个版本变得更加容易。
README.html 不属于port的一部分,而是由 make readme 生成的。在补丁或提交中不要包括此文件。
在某些情况下,必须阻止用户安装port。 可以在port的 Makefile 中使用几个变量,告诉用户port无法安装。 这些 make 变量的值将是向用户显示port拒绝安装自身的原因。 请使用正确的 make 变量。 每个变量都传达着截然不同的含义,既对用户,也对依赖于 Makefiles 的自动化系统,如ports构建集群和 FreshPorts。
BROKEN 保留给目前无法正确编译、安装、卸载或运行的 ports。用于被认为是暂时性问题的 ports。如果指示,构建集群仍将尝试构建它们,以查看潜在问题是否已解决。(但是,通常情况下,集群运行时不会这样做。) 例如,当 port:
无法编译时使用 {{0}}
在配置或安装过程中失败
在${PREFIX}之外安装文件
在卸载时未完全清理所有文件(但是,允许且希望port保留用户修改的文件)
在应该正常运行的系统上存在运行时问题。
FORBIDDEN 用于包含安全漏洞或引起对 FreeBSD 系统安全性产生严重关注的ports(例如,一个声誉不佳的不安全程序或提供易受攻击服务的程序)。一旦某个软件存在漏洞且没有发布升级版本,立即将ports 标记为 FORBIDDEN 。理想情况下,在发现安全漏洞时尽快升级ports,以减少易受攻击的 FreeBSD 主机数量(我们希望以安全著称),但有时漏洞披露和受影响软件更新发布之间会有明显的时间差。不要因其他原因而将port 标记为 FORBIDDEN ,只能基于安全性原因标记。
IGNORE 保留给因某些其他原因而不得构建的ports。在认为问题是结构性的ports中使用它。构建集群绝对不会构建标记为 IGNORE 的ports。例如,当port时使用 IGNORE :
定制安装版本的 FreeBSD 上不起作用
由于许可限制,可能无法自动获取 distfile
与当前安装的某些其他port不兼容(例如,port依赖于 www/drupal7,但安装了 www/drupal8)||如果port与当前安装的port发生冲突(例如,如果它们在执行不同功能的相同位置安装文件),请改用 CONFLICTS 。 CONFLICTS 将自行设置 IGNORE 。| | --| ----------------------------------------------------------------------------------------------------------------------------------------------|
不要引用 BROKEN , IGNORE 和相关变量的值。由于向用户显示信息的方式,每个变量的消息措辞不同:
从 make describe 导致此输出:
FreeBSD 运行在许多不仅仅是众所周知的基于 x86 的处理架构上。某些ports有特定于其中一个或多个这些架构的约束条件。
要查看支持的架构列表,请运行:
值显示为 TARGET / TARGET_ARCH 。ports只读的 Makevar ARCH 是基于 TARGET_ARCH 的值设定的。Port的 Makefile 应该测试这个 Makevar 的值。
没有任何架构相关文件或要求的 Ports 通过设置 NO_ARCH=yes 进行识别。
从这类 ports 构建的软件包,其架构字符串以 :* 结尾(通配符架构),而不是例如 freebsd:13:x86:64 (amd64 架构)。
要将 port 标记为仅在某些架构上被 IGNORE ,有两个其他方便的变量将自动设置 IGNORE : ONLY_FOR_ARCHS 和 NOT_FOR_ARCHS 。示例:
自定义 IGNORE 消息可使用 ONLY_FOR_ARCHS_REASON 和 NOT_FOR_ARCHS_REASON 进行设置。使用 ONLY_FOR_ARCHS_REASON_ARCH 和 NOT_FOR_ARCHS_REASON_ARCH 可以实现按体系结构的条目。
如果port获取 i386 二进制文件并安装它们,则设置 IA32_BINARY_PORT 。如果设置了此变量,则 IA32 版本的库必须存在/usr/lib32,并且内核必须支持 IA32 兼容性。如果这两个依赖关系中的一个未满足,则 IGNORE 将被自动设置。
有些ports会尝试通过向编译器指定 -march=native 来调整到正在构建的准确机器。这应该避免:要么将其列在关闭默认选项下,要么完全删除它。否则,构建集群生成的默认软件包可能无法在该 ARCH 的每台机器上运行。
请记住, BROKEN 和 FORBIDDEN 应作为暂时的资源,如果一个port无法正常工作。永久损坏的ports将被完全从树中移除。
当有必要时,可以使用 DEPRECATED 和 EXPIRATION_DATE 提醒用户即将port。前者是一个字符串,解释为什么计划移除port;后者是一个符合 ISO 8601 格式(YYYY-MM-DD)的字符串。这两者将展示给用户。
可以设置 DEPRECATED 而不必有 EXPIRATION_DATE (例如,推荐port的更新版本),但反过来却毫无意义。
没有关于给予多少通知的固定政策。 目前的做法似乎是对与安全相关问题给予一个月的通知期,对于构建问题则为两个月。 这也给任何感兴趣的贡献者一些时间来修复问题。
Makefile 向用户表明由于某些外部因素(例如,用户已经指定了一组非法的构建选项组合)无法安装 port 的正确方式是将一个非空值设置为 IGNORE 。 这个值将由 make install 格式化并显示给用户。
使用 .error 于此目的是一个常见错误。这样做的问题在于许多与 ports 树相关的自动化工具在这种情况下将失败。最常见的情况是在尝试构建 /usr/ports/INDEX 时发生(请查看运行 make describe )。然而,即使是更琐碎的命令例如 make maintainer 在这种情况下也会失败。这是不可接受的。
示例 1. 如何避免使用 .error
下面两个 Makefile 片段中的第一个将导致 make index 失败,而第二个将不会:
除了在目标中使用外,不推荐使用 sysctl。这是因为像在 make index 中使用时,任何 makevar 命令的评估都必须运行该命令,进一步减慢该过程。
只能通过 SYSCTL 使用 sysctl(8) ,因为它包含完全合格的路径,并且可以被覆盖,如果有特殊需要的话。
有时软件作者会更改已发布的 distfiles 的内容,而不更改文件的名称。验证更改是否是官方的,并已由作者执行。过去曾经发生过,在下载服务器上悄悄更改了 distfile,意图是造成损害或 comprom 动最终用户的安全性。
将旧的 distfile 放在一边,下载新的 distfile,解压它们并使用 diff(1) 比较内容。如果没有可疑之处,就更新 distinfo。
联系软件的作者,并与他们确认更改。
FreeBSD ports 通常期望符合 POSIX。一些软件和构建系统基于特定操作系统或环境做出假设,可能在 port 中使用时会导致问题。
如果有其他获取信息的方式,请不要使用 /proc。例如,在 main() 中使用 setprogname(argv[0]) ,然后使用 getprogname(3) 来获取可执行文件名。
不要依赖 POSIX 未记录的行为。
不记录应用程序关键路径中的时间戳,如果应用程序没有时间戳也能正常工作。获取时间戳可能会很慢,这取决于操作系统中时间戳的准确性。如果确实需要时间戳,确定它们必须精确到什么程度,并使用一个文档记录为提供所需精度的 API。
在 Linux® 上,许多简单的系统调用(例如 gettimeofday(2),getpid(2))比其他任何操作系统都快得多,这是由于缓存和 vsyscall 性能优化。在性能关键的应用程序中,不要指望它们的性能低廉。一般来说,尽量避免系统调用,如果可能的话。
不要依赖于 Linux® 特定的套接字行为。特别是,默认的套接字缓冲区大小是不同的(使用 setsockopt(2)调用 SO_SNDBUF 和 SO_RCVBUF ),并且当套接字缓冲区已满时,Linux® 的 send(2) 会阻塞,而 FreeBSD 的则会失败并在 errno 中设置 ENOBUFS 。
如果需要依赖非标准行为,请将其正确封装到一个通用的 API 中,在配置阶段检查该行为,如果缺失则停止。
检查 man 手册,查看使用的函数是否是 POSIX 接口(在 man 手册的 "STANDARDS" 部分)。
不要假设 /bin/sh 就是 bash。确保传递给 system(3) 的命令行与 POSIX 兼容。
一个常见的 bashism 列表在这里。
检查头部是否以 POSIX 或 man 页推荐的方式包含。例如,sys/types.h 经常被遗忘,这对 Linux®来说不是那么大的问题,但对 FreeBSD 来说是一个问题。
要始终仔细检查 pkg-descr 和 pkg-plist。如果正在审核一个port并且可以达到更好的措辞,请这样做。
请注意任何法律问题!不要让我们非法分发软件!
变量 | 描述 |
---|---|
ARCH
由 uname -m 返回的架构(例如, i386 )
OPSYS
操作系统类型,由 uname -s 返回(例如, FreeBSD )
OSREL
操作系统的发行版本(例如, 2.1.5 或 2.2.7 )
OSVERSION
操作系统的数字版本;与 __FreeBSD_version 相同。
LOCALBASE
“本地”树的基础(例如, /usr/local )
PREFIX
port 安装自身的位置(请参阅更多关于 PREFIX 的信息)。