常见错误

本节包含开发人员在编写 Ebuild 时常犯的一些错误信息。

常见的 Ebuild 编写错误

未加保护的外部调用

在几乎所有情况下,对外部工具的调用都应使用 || die(或使用 assert)进行保护,以便检测失败。请参阅 错误处理

无效使用 static USE 标记

static use-flag 仅用于使二进制文件使用静态链接而不是动态链接。它不应用于使库安装静态库。为此,应使用 static-libs use-flag。

无效使用 ROOT

ROOT 的用法仅用于影响软件包的安装方式(即安装到 ROOT 中)——构建和编译不应依赖于 ROOT。因此,不允许在 src_* 函数中使用 ROOTpkgcheck 现在可以通过其 MisplacedVariable 检查来检测某些此类情况。有关更多信息,请参阅 bug 775191

另请参阅 ROOT

引用可能被压缩的文档文件的完整路径

当向用户打印查找 INSTALL 等文件的位置时,请勿指定完整路径,因为 PORTAGE_COMPRESS 会起作用。该文件可能会使用 gzip、bzip2 或其他一些随机压缩工具进行压缩。因此,不要这样做

elog "They are listed in /usr/share/doc/${PF}/INSTALL.gz"

执行以下操作

elog "They are listed in the INSTALL file in /usr/share/doc/${PF}"

构建日志不详细

编写 Ebuild 时,应始终检查构建日志,因为构建系统可能会忽略 CC/CXX/LD/CFLAGS/LDFLAGS 等或默认添加不需要的标志。为了分析这一点并获得完整的信息,以防有人报告您的软件包的错误,**构建日志必须始终详细**。

根据构建系统,有多种方法可以修复不详细的构建日志

  • 对于基于 cmake 的构建系统,Ebuild 调用 cmake_src_compile 就足够了,它默认获取 cmake.eclass 变量 CMAKE_VERBOSE=1。如果出于某种原因直接调用 emake,则可以执行 emake VERBOSE=1(请注意,'cmake_src_compile' 也接受作为参数传递给 make 的参数)。
  • 对于基于 autotools 的构建系统,econf 会自动将 '--disable-silent-rules' 传递给 ./configure。如有必要,emake V=1 也应该可以工作。请注意,V=1 不是通用参数,因此可能并不总是有效。
  • 对于自定义 Makefile,您通常需要编写补丁。尝试让上游包含类似 'V=1' 的选项以启用完全详细模式。
  • 请注意,当在 eclass 外部手动构建 Go 时,您需要使用 GOFLAGS="-x"。

-Werror 编译器标志未删除

“-Werror” 是一个将所有警告转换为错误的标志,因此如果遇到任何警告,它将中止编译。有关更多信息以及 Gentoo 树中的实际示例/修复,请参阅 bug 260867

基本原理

此标志不建议用于发行版,并且在构建日志中遇到时应始终禁用,因为在许多情况下,它会毫无目的地中断,例如:

  • GCC/glibc 版本升级后出现新的警告,开发人员在编码时并不知情
  • 某些 autoconf 检查将严重失败
  • 库添加已弃用的 API 警告,尽管该 API 仍在工作/受支持
  • 在鲜为人知的架构上,我们可能会得到与常见架构不同的/更多的警告
  • 根据开发人员测试“-Werror” 的发行版/架构/库版本/内核/用户空间,随机中断

通过关闭“-Werror”,我们仍然可以看到警告,但它们没有理由导致编译失败。请注意,Portage 已经发出关于可能导致运行时中断的 GCC 警告的 QA 通知。

如何修复

要修复受影响的构建系统,您应该尝试以下方法

  • 从构建系统中删除编译器标志,例如 Makefile.am 或 configure.ac,甚至提供开关(对于基于 autotools 的构建系统,可以是“--disable-werror”,这有利于向上游发送补丁)
  • 使用append-flags -Wno-error(需要 flag-o-matic.eclass);为了使此方法有效,环境标志必须得到尊重并放置在构建系统标志之后;此方法不被推荐,因为它也将禁用所有“-Werror=specific-warning” 标志,请参阅下一节

始终检查它是否确实已从构建日志中消失。

特定的 -Werror=... 标志

编译器(例如 GCC)可以将任何特定警告转换为错误。例如,特定 -Werror 标志将是“-Werror=implicit-function-declaration”,并且只会影响关于隐式函数声明的警告。将其保持不变通常是安全的,因为它们固定在此问题上,并且不应导致随机的构建时中断。此外,我们可以预期上游有意为之,以避免已知的运行时错误,而不仅仅是为了测试其构建。但是,如果您不确定,您应该自己检查指定的警告或询问其他开发人员。

例外情况

从 configure.ac 中删除“-Werror” 在配置阶段依赖于退出代码的极少数情况下可能会导致中断。请参阅 app-emulation/open-vm-tools 错误。但即使那样,我们也会将其从生成的 Makefile 中删除。

缺少/无效/损坏的头文件

提交 Ebuild 时,头文件必须与 skel.ebuild 中的头文件**完全相同**。

前两行**必须**如下所示

# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

重新定义 P、PV、PN、PF 变量

您永远不应该重新定义这些变量。始终使用 MY_P、MY_PN、MY_PV 等。有关更多信息,请参阅 Portage 中执行此操作的其他 Ebuild。大多数 Ebuild 使用 bash“参数扩展”。请阅读 bash 手册页以了解“参数扩展”的工作原理。

顺便说一句,如果您发现一个重新定义它的软件包,请不要复制它。提交有关该 Ebuild 的错误。

在 SRC_URI 和 S 中包含版本号

您应该尽量不要在 SRC_URI 和 S 中包含版本号。始终尝试使用 ${PV} 或 ${P}。这使得维护 Ebuild 变得更加容易。如果版本号与 tarball/源代码不一致,则使用 MY_P。例如,dev-python/pyopenal 获取名为 PyOpenAL 的 tarball,因此我们将其重新定义为

MY_P=${P/pyopenal/PyOpenAL}
SRC_URI="http://download.gna.org/pyopenal/${MY_P}.tar.gz"
S=${WORKDIR}/${MY_P}

DEPEND 存在语法错误

用户提交的 DEPEND 和 RDEPEND 字段会出错很多。编写依赖项部分时,请遵循以下一些要点。

  • 始终包含 CATEGORY。例如,使用 >=x11-libs/gtk+-2 而不是 >=gtk+-2
  • 不要对 >= 依赖项使用星号 (*)。例如,应为 >=x11-libs/gtk+-2 而不是 >=x11-libs/gtk+-2*
  • GTK 特定。对于 GTK+1 应用程序,始终使用 =x11-libs/gtk+-1.2*。
  • 永远不要依赖元软件包。因此,不要依赖 gnome-base/gnome,始终依赖于特定的库,例如 libgnome。
  • 每行一个依赖项。不要在同一行上放置多个依赖项。这会使阅读变得丑陋且难以理解。

DEPEND 不完整

这是另一个非常常见的错误。Ebuild 提交者提交了一个“正常工作”的 Ebuild,而没有检查依赖项是否正确。以下是一些关于如何找到正确依赖项的提示。

  • 查看 configure.in 或 configure.ac。在此处查找软件包的检查。需要注意的是 pkg-config 检查或检查特定版本的 AM_* 函数。
  • 查看包含的 .spec 文件。查看包含的 .spec 文件以查找相关依赖项是一个很好的依赖项指示。但是,不要认为它们是依赖项的最终完整列表。
  • 查看应用程序/库网站。检查应用程序网站以查找他们建议需要的可能的依赖项。
  • 阅读软件包的 README 和 INSTALL。它们通常还包含有关构建和安装软件包的有用信息。
  • 记住非二进制依赖项,例如 pkg-config、文档生成程序等。构建过程通常需要一些依赖项,例如 intltool、libtool、pkg-config、doxygen、scrollkeeper、gtk-doc 等。确保这些都已明确说明,通常在 BDEPEND 中。

LICENSE 无效

用户在提交 ebuild 时常犯的一个错误是提供无效的许可证。例如,GPL 不是有效的许可证。您需要指定 GPL-1GPL-2LGPL 也一样。请确保您在 LICENSE 字段中使用的许可证在 licenses 目录中存在。作为提示,请检查源代码包中的 COPYING 文件以了解许可证。如果一个软件包没有明确指定它使用 GPL-1GPL-2,那么它很可能使用 GPL-2

如果您提交的软件包的许可证是唯一的,并且不在 licenses/ 目录中,则必须在单独的文件中提交新的许可证。

KEYWORDS 中未经测试的架构

请不要在 KEYWORDS 中添加其他架构,除非该 ebuild 已在该架构上进行过测试。此外,所有新的 ebuild 应该标记为 ~x86 或其所属的架构。确保在您提升版本时,所有稳定的 KEYWORDS 都标记为 ~

未使用的标志和 eclass 继承

有时过时的 USE 标志会保留在 IUSE 中,尽管它们没有任何功能,例如,一个依赖项可能已成为强制性的,但 USE 标志仍然保留在 IUSE 和 *DEPEND 中。类似地,由于 ebuild 的更改或新的 EAPI,eclass 经常变得冗余,例如,eutils.eclass 在现代 EAPI 中应该已经过时了。请记住删除这些过时的部分。

缺少 SLOT

请确保您的 ebuild 中包含 SLOT 变量。如果您不打算使用它,请不要删除它。请设置

SLOT="0"

错误的 DESCRIPTION 和 HOMEPAGE

请确保 DESCRIPTION 不要过长。好的描述会在一句话中描述软件包的主要功能。

请检查 HOMEPAGE 变量是否正确,以及如果用户想要了解更多关于软件包的信息,它是否会引导他们到正确的页面。如果软件包没有主页,请将 HOMEPAGE 变量设置为 https://wiki.gentoo.org/wiki/No_homepage。此外,请尽量测试 HOMEPAGE 中使用的网站的 HTTPS 支持。

错误地使用空格代替制表符

由于提交者没有遵循使用制表符而不是空格的指南,重新格式化 ebuild 的行并不是一件有趣的事情。所以,使用制表符!

尾随空格

请记住在您的 ebuild 上运行 pkgcheck,以便它可以告诉您行尾或空行是否存在尾随空格。

添加冗余的 S=${WORKDIR}/${P}

如果 S=${WORKDIR}/${P},则您不应该将其添加到您的 ebuild 中。这是隐含的,只有当它不是 ${WORKDIR}/${P} 时,您才应该添加它。

缺少文档

如果您的软件包有文档,请确保您使用 dodoc 或在 /usr/share/doc/${PF} 中安装它。请记住在运行 dodoc/doins 时检查错误。

如果软件包文档很大或需要额外的依赖项来构建,则应使用 doc USE 标志将其设为可选。如果文档很小并且不需要额外的依赖项(例如,README 文件),则无条件安装它。

屏蔽不支持/损坏的 USE 标志

在极少数情况下,软件包可能有一个不支持/损坏的 USE 标志(这可能发生在vanillacustom-cflags 中)。然后必须为该 ebuild 屏蔽 USE 标志(通常在profiles/base/package.use.mask 中),至少当 ebuild 进入稳定分支时。

未使用最新的 EAPI

通常,用户提交的 ebuild 没有使用最新的 EAPI,甚至可能落后几个版本。EAPI 带来了新的辅助函数和改进的方法来完成常见任务。建议提交的 ebuild 使用尽可能最新的 EAPI(受 eclass 约束),以提高 ebuild 的质量并简化审查过程。

直接调用 pkg-config

您不应该在 ebuild 中直接调用 pkg-config,因为这对于交叉编译等操作来说是有问题的。正确的辅助函数会尊重 ${PKG_CONFIG}。相反,请使用 toolchain-funcs.eclass 中的 tc-getPKG_CONFIG,例如:

sed -i -e "s:-lncurses:$($(tc-getPKG_CONFIG) --libs ncurses):" || die

然后不要忘记将 virtual/pkgconfig 添加到 BDEPEND 中!

Ebuild 提交常见错误

简介

请按照 添加新 ebuild 教程正确提交 ebuild。

打包 ebuild

请不要将 ebuild 或补丁作为 tarball 附加。这可以避免在审查时进行额外的操作。

内联 ebuild

不要将 ebuild 粘贴到 bugzilla 的评论字段中。

没有描述软件包是什么

请告诉我们软件包是什么,并填写应用程序主页的 URL(如果存在)。

更新软件包而没有解释更改的内容

如果您提交软件包更新,请确保解释您对 ebuild 做出的更改。例如,如果软件包引入了新功能/选项并且您使用了 USE 标志,请在您的 bug 中列出它。不要让我们去寻找它。

明智的做法是提交软件包更新的差异而不是整个 ebuild。生成它的最佳方法是

$ diff -u some-package-0.1.0.ebuild some-package-0.2.0.ebuild > ~/some-package-0.2.0.patch

提交版本提升时未更改的 ebuild

如果您正在为 Portage 中的软件包提交新版本,请确保现有的 ebuild 可以工作,并确保新 ebuild 中包含更改(例如添加的文档)。如果与先前版本相比,ebuild 没有需要更改的地方,则不要附加 ebuild。只需在 bug 报告中说明您复制了 ebuild 并验证了软件包可以正常工作并安装即可。