费多拉

打包指南是一系列常见问题及其严重程度的集合。这些指南不应被忽视,但也不应盲目遵循。如果你认为你的软件包应该豁免指南中的某些部分,请将此问题提交给Fedora包装委员会

这些文档涵盖了可接受的 费多拉打包的详细信息,虽然它们可能包含各种示例,但作为教程不会特别有用。它们也不涉及作为打包者获得 费多拉仓库访问权限的细节和政策,或实际创建和发布作为发行版一部分的软件包的机制。有关涵盖这些问题的文档,请参见以下内容:

包审阅者有责任指出包的具体问题,而打包者有责任处理这些问题。 审阅者和打包者共同确定问题的严重性是否阻止包或在包进入存储库后可以对其进行处理)。请记住,您提交的任何包也必须符合审查指南

这些文档的原作者是汤姆·卡勒韦尽管它们最初基于许多其他文档。 多年来,打包委员会的许多成员已经对它们进行了重大修改。

这些指南中的关键词“必须”、“不得”、“应该”、“不应该”和“可以”应按副本请求2119中的描述进行解释。

反馈这些指南的问题,包括拼写错误在这里

适用性

一般来说,这些指南适用于当前发布的、非生命周期结束的 费多拉和费多拉(生皮)的开发版本。 如果这些指南的特定部分仅与这些版本的子集相关,则会特别注明。 但是,请注意,生皮可能会快速变化,那里的变化是可见的,但这里尚未反映出来。

指南也在一定程度上涵盖了EPEL的软件包,但仅当与EPEL包装指南Fedora包装的变化远比EPEL包装快,因此随着时间的推移,这些指南将进一步偏离任何特定的EPEL版本,而对于较旧的受支持的EPEL版本,差异可能相当显著。这些指南中不适用于EPEL的部分通常不会显示。

一般例外政策

由于这些指南永远无法涵盖所有可能的意外情况,因此总会有需要例外的包。包装商有责任尽可能严格遵守这些指南,并在包装规范文件中明确记录无法遵守的情况,作为注释。

如果在指南中使用了“应该”或“建议”的语言,并且包装不可能符合该指南,则包装商可能会偏离该指南。偏差的性质及其背后的理由必须记录在规范文件中。

如果使用“必须”、“必须”或“需要”等语言,只有在包装委员会批准的情况下,包装商才能偏离指南。请按照包装委员会用于发出这些请求的页面。

允许的程序包

请审阅可以打包的内容以确保要包装的东西在Fedora是允许的。

命名

你应该通过命名原则以确保包的名称正确。

版本和发布

可以找到包含使用版本和发布字段的正确方法的文档在这里.

许可

您应该查看以下信息决定在Fedora允许的许可证以及许可指南以确保您的软件包得到了适当的许可,并且正确地指示了许可。

Fedora商标

包装工不能添加任何Fedora商标资产,包括Fedora徽标、Fedora标识图标或包含Fedora标志的图形。这些资产必须添加到软呢帽徽标包中。您的软件包根据软呢帽徽标软件包安装徽标。如果上游包含您认为使用不当的Fedora商标资产,请发送电子邮件至legal@fedoraproject.org

这是因为Fedora标志是一个商标,它是在不同于代码的法律框架下处理的。它只能根据保护商标的条款进行分发。将Fedora商标单独放在自己的包装中,而不是分散在不同的其他包装中,这也是实现混音的基本做法,必须不使用Fedora商标,而不是使用自己的*-logos包或使用generic-logos包。

库和应用程序

许多特定于语言或域的指南都提到了“库”、“模块”、“插件”或其他特定于语言和域的术语。这对包命名特别重要。有些应用程序可能包括库,有些库可能包括应用程序,因此区别并不总是明确的。

库还是应用程序?

  • 如果包的主要目的是提供用户运行的可执行文件,则应将其打包为应用程序。如果它还包括可能由其他代码导入或链接的库,请参阅多用途软件包如下所示。

  • 如果包的主要目的是提供要导入或加载到其他代码中的库,则将其视为库,并且必须这样打包。如果它包含用户也可以运行的实用程序,请参阅多用途软件包如下所示。

由包装商决定包装的主要用途。通常情况下,上游已经完成了命名选择,而Fedora包装商应该紧随其后。

多用途软件包

许多软件包,无论其主要用途如何,都同时包含应用程序和库。在这种情况下,应将其中一个或两者打包在子包中,以便其他应用程序仅依赖于库,而不依赖于关联的应用程序。安装依赖于库或服务的应用程序时,不应自动拉入与该库或服务关联的其他应用程序。

程序包独立性

在技术上可行的情况下,软件包应该可以独立安装,但如有必要,它们必须指定正确类型的依赖于其他软件包,请参阅依赖项类型如下所示。

除非严格要求,否则桌面应用程序不得依赖于其他桌面应用程序。特别是,包含可见.桌面文件(a.桌面不包含该行的文件NoDisplay=真)不应该有要求,建议,或补充资料直接或间接包含可见桌面文件的任何其他软件包。

例如,视频游戏级别的编辑器需要相关联的视频游戏才能运行,或者应用程序的插件需要相关联的应用程序,这是合理的。但是,碰巧使用数据库库的应用程序依赖于与该库关联的数据库管理套件,或者碰巧使用特定编程语言的应用程序依靠与该编程语言关联的管理工具,这是不合理的。

如果源程序包提供多个图形应用程序,则在可行的情况下,这些应用程序应打包在单独的子程序包中。

等级库文件

spec文件(“spec”)是打包工作流中的基本元素。对包所做的任何更改都将包括对规范的更改。因为Fedora中的包是由打包者社区和自动化工具维护的,所以规范遵循某些约定是很重要的。这些包装指南的大部分内容都涉及到规范中的内容,但这里有一些一般性的项目。

等级库文件命名

规范文件必须命名%{name}.spec。也就是说,如果您的包命名为例子,规范文件必须命名示例.spec.

规范易读性

所有规范文件必须清晰易读,并以包装商社区能够理解和使用的方式进行维护。

为了便于阅读,Fedora软件包中只允许使用Fedora和EPEL的宏和条件。除非Fedora中也存在这些宏和条件,否则不允许在Fedora主存储库中的包的spec文件中为其他发行版(包括Fedora派生)使用宏和条件。

等级库文件编码

除非您需要在ASCII曲目,您无需担心规范文件的编码。如果确实需要非ASCII字符,请将等级库文件保存为UTF-8。如果您对ASCII字符有疑问,请参阅这个图表.

非ASCII文件名

类似地,包含非ASCII字符的文件名必须编码为UTF-8。由于无法注意文件名的编码方式,因此对所有文件名使用相同的编码是确保用户能够正确读取文件名的最佳方法。如果上游提供的文件名不是UTF-8编码的,则可以使用convmv之类的实用程序(来自convmv包)转换%install部分中的文件名。

规范维护和规范性

Fedora的git存储库是Fedora规范文件的标准位置。维护人员必须期望其他维护人员和自动化工具对其软件包进行更改,可能在更改之前不进行沟通(尽管始终鼓励沟通)。如果一些维护人员也试图在外部存储库中保存规范的副本,他们必须准备合并对Fedora存储库中规范所做的更改,并且不得使用外部存储库的副本或使用fedpkg进口.

源文件验证

上游项目发布其发布的OpenPGP签名时,Fedora包应该作为RPM构建过程的一部分,验证该签名。

虽然源文件中的校验和可以证明从lookaside缓存中检索的文件是打包程序上载的文件,但对于该文件是否是上游项目发布的文件,它是沉默的。上游开发人员的签名证明源代码与他们发布的代码相同。作为构建的一部分验证签名可以确保打包人员不会忘记验证它。

获取正确的密钥

验证方法需要一个OpenPGP密钥环文件,其中包含来自上游项目的一个或多个公钥。钥匙圈应包含所有可信的密钥,以证明来源的真实性,以及不能包含任何其他密钥。

理想情况下,上游项目将这样的密钥环发布为可下载的文件。您应该下载该文件,并尽您所能验证其真实性。然后将其未经修改添加到SCM包中,并在规范文件中提供其URL,以便其他人可以验证它必须尽可能使用HTTPS或类似的认证协议。

即使您无法在第一次添加时验证密钥,它仍然可以以一种先信任后使用的方式增强安全性。如果密钥是正确的,它将确保检测到未来的攻击,或者如果使用正确的密钥对未来的版本进行签名,则稍后将检测到当前的攻击。

验证签名

完成源文件验证后必须%准备在执行任何可能受到危害的代码之前。验证必须使用宏完成%{gpgverify},它扩展为一个命令,其参数应为密钥环、签名和签名文件的路径名。生成要求:gnupg2是验证工作所必需的。

任何分离的签名文件(例如foo.tar.gz.asc或foo.tart.gz.sig)必须与源代码一起上传到包查找缓存,而密钥环必须直接提交到包SCM。

必须使用以下格式:

来源0:ftp://ftp.example.com/pub/foo/%{名称}-%{版本}.tar.gz资料来源1:ftp://ftp.example.com/pub/foo/%{名称}-%{版本}.tar.gz.asc资料来源2:https://www.example.com/gpgkey-0123456789ABCDEF0123456789 EF.gpg生成要求:gnupg2%准备%{gpgverify}--密钥环=“%{SOURCE2}”--签名=“%}SOURCE1}”--data=“%{SOURCE0}”

第一个源是实际的tarball,第二个源是来自上游的签名,第三个源是密钥环。

例外情况

如果需要修改包的上游tarball,例如因为它包含禁止的项,则不能在构建过程中验证tarball。在这种情况下,上游OpenPGP密钥环仍必须包含在SCM包中,用于构建strippeddown tarball的指令/脚本需要验证上游源。

如果上游项目没有发布密钥环文件(例如,如果他们只在自己的网站上发布指纹并参考密钥服务器网络下载密钥),那么您可能需要在验证密钥后创建密钥环。在这种情况下,没有指向keyring的上游URL,因此您应该在spec文件的注释中记录如何创建keyring。带有指纹的钥匙的最小钥匙圈7D33D762FD6C35130481347FDB4B54CBA4826A18可以使用以下命令创建:

gpg2--导出--导出选项导出最小7D33D762FD6C35130481347FDB4B54CBA4826A18>gpgkey-7D33D762FD6C35130481347FDB4B54CBA4826A18.gpg

如果上游对tarball进行了不同的签名,例如仅对未压缩的tarball签名,但分发了压缩版本,则必须相应地调整验证步骤,例如:

来源0:ftp://ftp.example.com/pub/foo/%{名称}-%{版本}.tar.xz资料来源1:ftp://ftp.example.com/pub/foo/%{名称}-%{版本}.tar.asc资料来源2:https://www.example.com/gpgkey-0123456789ABCDEF0123456789 EF.gpg构建要求:gnupg2 xz%准备xzcat“%{SOURCE0}”|%{gpgverify}--密钥环=“%{SOURCE2}”--签名=“%}SOURCE1}”--data=-

Fedora引导期间至关重要的软件包可以使用引导标志在构建GnuPG之前跳过验证。

帮助

如果您需要帮助使您的软件包符合本指南,或者如果您不知道如果构建在签名验证中失败了该怎么办,那么您应该在绕过检查之前,在Fedora devel邮件列表上寻求帮助,以确保您没有构建受损的软件。

体系结构支持

所有Fedora软件包必须在至少一个受支持的主体系结构上成功编译并构建成二进制RPM,除非该软件包仅在辅助体系结构(如特定于体系结构的引导实用程序、微代码加载程序或硬件配置工具)上有用。Fedora包装商应尽一切努力支持主要体系结构.

内容、不需要编译或构建的代码以及与体系结构无关的代码(noarch)是显著的例外。

架构(Architecture)构建失败

如果Fedora包不能成功编译、构建或在体系结构上工作,那么这些体系结构应该列在排除Arch。中列出的每个体系结构排除Arch需要在bugzilla中归档一个bug,描述包不能在该架构上编译/构建/工作的原因。然后,应将错误号放在注释中相应的排除Arch行。在审查过程中,新的包不会有bugzilla条目,所以他们应该在批准包之前将此描述放在注释中,然后归档bugzila条目,并用bug号替换长解释。该错误应标记为阻止以下一个(或多个)错误,以简化对此类问题的跟踪:

具有未导出依赖项的Noarch

有时,您正在处理一个noarch包,该包只能在不同的arched包所基于的位置运行。例如,这对于用脚本语言编写的包来说很常见,而脚本语言依赖于该语言的解释器包。如果包所依赖的arched包在Fedora(或EPEL)目标的所有体系结构上都不可用,那么您可能会遇到这样的情况:您可能需要将包从某些体系结构的包存储库中排除,或者阻止它在构建系统中的某些体系结构上构建。

特定于架构的运行时和构建时依赖项

通过使用不包括拱门:独家采购:标签:

BuildArch:noarch#在下面列出依赖包构建的架构ExclusiveArch:%{ix86}%{arm}x86_64 noarch

有时,您正在打包的语言运行库会为其可用的arches提供宏,例如,%{节点js_arches}。如果它确实存在,那么您可以使用以下内容ExclusiveArch:%{nodejs_archs}无搜索在规范文件中。查看该语言的指导原则,看看是否存在这样的宏。

无特定于电弧的源或补丁

包装不得有资料来源:补丁:根据体系结构条件化的标记。例如,禁止这样做:

%ifarch第64页修补程序0:build-fix-for-ppc64.patch%结尾

条件化资料来源:补丁:按体系结构列出的标记会导致源包的内容因用于构建它的体系结构而异。

请注意,这很不幸地阻止了%自动设置当这些补丁中的一些仅应用于某些体系结构时,避免被用于应用补丁。最好的解决方案是编写只适用于所有架构的补丁。如果不可能,那么只需使用%设置并使用%补丁宏以应用每个修补程序%ifarch公司%ifnarch公司视情况而定。例如:

%准备%设置-q%ifarch s390倍%补丁0-p1%结尾

文件系统布局

费多拉遵循文件系统层次结构标准关于文件系统布局,以下列出了例外情况。FHS定义了文件应放在系统中的位置。

例外情况

  • Fedora允许交叉编译器将文件放在/usr/目标.

  • Fedora不允许直接在//用户使用程序未经FPC批准。

Libexecdir公司

这个文件系统层次结构标准不包括libexecdir的任何规定,但Fedora包可能会在其中存储适当的文件。Libexecdir(又名,/usr/libexec(在Fedora系统上)只能用作主要由其他程序而不是用户运行的可执行程序的目录。

Fedora的rpm包含一个用于libexecdir的宏,%{_libexecdir}强烈建议打包程序将libexecdir文件存储在%{_libexecdir},例如%{_libexecdir}/%{name}.

如果上游的构建脚本支持使用%{_libexecdir}那么这是配置它的最合适的位置(例如,传递--libexecdir=%{_libexecdir}/%{name}自动工具配置)。如果上游的构建脚本不支持此功能,%{_libdir}/%{name}是有效的第二选择。如果您必须修补对中使用这些目录之一的支持,那么您应该在LIBEXECDIR中进行修补,最好在构建时进行配置(因此没有/usr/libexec可以将LIBEXECDIR设置为更适合其发行版的另一个目录)。

多实验室免税场所

如果包不受multilib限制,则可以使用%{_prefix}/库而不是%{_libdir}。包含通常安装到中的特定于体系结构的文件的包%{_libexecdir}总是被认为不符合multilib的条件。但是,您应该确保它们所在的(子)包中没有其他被认为符合multilib条件的内容。如果您希望在包中执行此操作的文件不是这样的,或者您只是不确定,请向FESCo请求明确的多库豁免。

/运行

系统服务应将小型易失性运行时数据存储在/运行。这是一个支持tmpfs的目录,在启动任何服务之前(以及/无功功率,无功功率可用)。/var/运行是一个传统符号链接/运行.

下没有文件或目录/开关磁阻电动机,/usr/本地,或/主页/$USER

这个FHS表示:

“…任何程序都不应依赖现有/srv的特定子目录结构或必须存储在/srv中的数据。然而,FHS上应始终存在/srv兼容系统,并应用作此类数据的默认位置。分发版必须注意不要删除这些文件中本地放置的文件没有管理员权限的目录。"

FHS显式处理以下目录结构的控制/开关磁阻电动机发送给系统管理员,而不是分发。因此,任何Fedora软件包都不能在/开关磁阻电动机,已预配置为使用下的特定文件或目录/开关磁阻电动机、删除其中的文件,或以任何方式修改其中的文件。

此外,任何Fedora包都不能包含文件或目录,也不能修改以下目录下的文件:

  • /usr/本地因为FHS中的分发内容不允许使用这些目录

  • /主页/$USER由于用户可以任意修改其主目录中的文件,修改这些文件的rpm包存在破坏用户数据的风险。此外,站点可能正在安装nfs/家在许多不同类型的系统上,甚至在网络上根据需要自动安装它们。在这两种情况下,修改这样配置的主目录中的文件都会产生负面影响。

需要注意的是,一旦用户安装并配置了Fedora包中的软件,就可以使用/开关磁阻电动机作为数据的位置。包装绝对不能开箱即用

有限使用/选择,/等/选项、和/var/opt(变量/选项)

/选择及其相关目录(/等/选项/var/opt(变量/选项))保留给FHS中的供应商使用。我们已经预订了软呢帽名称和拉那纳供我们使用。如果程序包将文件安装到/选择它只能使用/opt/软帽等级制度。Fedora试图通过分配我们的/opt/软帽特定子系统的目录。如果您认为需要使用/opt/软帽请提交FPC票证,以决定是否有效使用/选择以及应该分配给您使用的子目录。

目前,我们已分配/opt/fedora/scls公司,/etc/opt/fedora/scls等、和/var/opt/fedora/scls供使用软件集合.

由于谷歌提供的Chrome软件包为特定于扩展名的文件选择了一个特定的文件位置,如果使用该文件,将与上述指南相冲突,因此包装委员会批准了以下例外:软件包可以将文件安装到/etc/opt/chrome/本机消息主机目录,并且可以创建该目录层次结构,只要整个包也支持Chromium。(Chromium支持可能位于不同的子包中。)如果Chrome将来允许使用更标准的目录来实现此目的,则将删除此例外。

合并的文件系统布局

Fedora已经合并了几个过去是独立的目录。

路径 与合并 RPM宏

/垃圾桶

/usr/bin(用户/二进制)

{间接寻址}

/斯宾

/usr/bin(用户/二进制)

%{绑定}

/usr/sbin

/usr/bin(用户/二进制)

%{绑定}

/利比亚64/图书馆

/usr/lib64/用户/库

%{_libdir}

/图书馆

/用户/库

%{_prefix}/库

例如,最终用户会发现/垃圾桶/桶与相同的文件/usr/bin/sh、和/usr/sbin/sendmail与相同/usr/bin/sendmail.

然而,rpm文件依赖项并不根据文件系统上的内容工作,而是根据rpm中指定的路径工作%文件第节。因此,转速规定:

%文件/垃圾桶/桶

将能够满足的文件依赖性/垃圾桶/桶但不是为了/usr/bin/sh.包装必须使用中的实际文件系统路径%文件第节。如果其他包依赖于解析为同一文件的不同路径,并且不方便将其更新为新路径,则包可以使用虚拟提供列出备用路径。

例如:

提供:/sbin/ifconfig[...]%文件%{绑定}/ifconfig

使用rpm链接

在二进制和源rpm上运行rpmlint,检查它们是否存在常见错误,并修复它们(除非rpmlint也可能出错)。如果您发现rpmlint的输出很神秘-e(电子)切换到它可以用于获得大多数错误和警告的详细描述。请注意,如果给定已安装软件包的名称,rpmlint将执行其他检查。例如,dnf安装foo-1.0-1.f20.x86_64.rpm;rpmlint-i foo将对foo包执行一组测试rpm链接foo-1.0-1.f20.x86_64.rpm不能。可以找到关于rpmlint问题的社区维护页面在这里.

标记和节

  • 这个版权:,包装商:,小贩:先决条件:不得使用标签。

  • 这个生成根目录:标签,组:标签,以及%清洁不应使用节。

  • 不应删除%安装.

  • 这个总结:标记值不应以句点结束。

  • 这个资料来源:tags记录在何处查找包的上游源。在大多数情况下,这应该是上游tarball的完整URL。对于特殊情况,请参阅SourceURL指南.

  • 中的URL网址:,资料来源:补丁:标签应尽可能要求对服务器进行身份验证。这通常意味着写https(https):而不是网址:ftp(英尺/分钟):.

包依赖项

所有包依赖项(构建时或运行时、常规、弱或其他)必须始终在官方Fedora存储库中满足。

RPM可以自动确定大多数编译库和一些脚本语言(如Perl)的依赖性。自动确定的依赖项不得被手动依赖项重复。

但是,必须明确列出生成依赖项,除非您使用的是自动生成依赖项生成器(例如。生锈蟒蛇). 请参阅构建时间依赖项(BuildRequires).

版本依赖项(构建时或运行时)只应在实际需要时使用,以确保包的正确版本存在。如果之前三个Fedora版本中的版本能够满足版本化依赖,那么就不需要版本化依赖,而应该使用常规的未版本化依赖。

具有定义的Epoch的包上的版本依赖项必须包含在该依赖项中。否则,依赖关系将无法按预期运行。

依赖项类型

要求如果软件正常运行需要依赖性,则必须使用。

如果程序包功能正常但容量减少,则建议建议应该使用。如果默认情况下该功能对用户可用,建议应该使用,并且建议否则。或者,反向依赖补充资料增强功能可以在其他包中使用。请参见打包:弱相关性有关使用这些依赖项类型的指南。

特定于体系结构的依赖关系

通过附加宏使依赖项特定于架构%{?isa}到包名称。例如:

需要:foo

变为:

需要:foo%{?_isa}

如果foo-devel包有一个foo-config脚本,您可以尝试执行foo-config--libs和foo-config-cflags,以获得应将哪些包标记为foo需求的强烈提示。例如:

$gtk-config--标记-I/usr/include/gtk-1.2-I/usr/incloude/glib-1.2-I/usl/lib/glib/include-I/usr/X11R6/include$gtk-config--库-L/usr/lib-L/usr/X11R6/lib-lgtk-lgdk-rdynamic-lgmodule-lglib-ldl-lXi-lXext-lX11-lm

这意味着gtk+-devel应该包含

需要:glib-devel%{?_isa}libXi-devel%{吗_isaneneneep libXext-devel%}?_issa}

丰富/布尔依赖项

软件包可以充分利用丰富(或布尔)依赖特性支持RPM。

文件和目录依赖项

RPM使您能够依赖任意文件或目录而不是包。包可能包含以下目录之一内路径的此类依赖项:

  • /usr/bin(用户/二进制)

  • /等

它们还可能依赖于显式提供:。它们不得包含对其他路径的依赖关系,因为这需要启用其他存储库元数据的下载。

请注意,多个包提供同一目录的情况并不少见。目录依赖关系仅用于表示对现有目录的依赖关系,而不是对可能提供该目录的任何其他软件包的任何其他功能的依赖关系。

声明文件和目录依赖项时,安装路径宏喜欢%{绑定}不得使用。%{绑定}提供的包的一些工具可能不同于%{绑定}需要一些工具在这种情况下,BuildRequires:%{_binder}/sometool无法按预期工作。

明确要求

Explicit Requires是由打包程序在规范文件中手动添加的Requires。包中不能包含库上不必要的显式Requires。我们通常依靠rpmbuild自动添加对库SONAME的依赖性。现代的包管理工具能够解决这种依赖关系,从而在许多情况下确定所需的包。然而,当前版本的rpmbuild仅在库SONAMES上添加dep,而不是库的完整版本。如果库在一段时间内添加了一些功能,而没有向后不兼容,这可能会导致SONAMES发生更改,那么这可能是一个问题。这可能会导致这样的情况:用户安装了旧版本的库,在Fedora中构建了带有新ABI的新版本库,并构建了使用该ABI的应用程序。如果用户只是尝试安装或更新某个应用程序,而没有同时更新库,则应用程序将正常安装(因为满足了SONAME依赖关系),但在运行时将失败,因为系统上安装的库缺少它所需的功能。

尽管您确实需要添加显式的库依赖项来防止发生这种情况,但在所有包中手动指定它也有缺点。历史表明,当库/文件从一个包移动到另一个包时,当包被重命名时,当多个替代包中的一个包就足够了,以及当版本控制的显式依赖变得过时和不准确时,这种依赖会增加混淆。此外,在某些情况下,包名称上的旧显式依赖关系需要不必要的更新/重建。例如,Fedora包只需要保留两个完整发布周期的历史供应。

正因为如此,也正因为我们希望在rpmbuild中修复此问题,所以需要注意这一点,但不需要显式地指定需要的库及其版本信息。

当需要显式库Requires时,显式库依赖项通常应该是arch特定的(除非涉及的包是noarch),并且应该有一个规范文件注释来证明这一点:

#对libfubar.so.1的自动依赖性不足,#因为我们严格需要至少修复两个segfault的版本。要求:libfubar%{?_isa}>=0:1.2.3-7

打包程序应该适当地重新访问显式依赖关系,以避免它变得不准确和多余。例如,在上面的示例中,当libfubar<1.2.3-7中没有当前的Fedora版本时,就不再需要列出明确的版本化需求。

筛选自动生成的要求

RPM尝试在构建时自动生成Requires(和Provides),但在某些情况下,自动生成的Requires/Provides不正确或不需要。有关如何筛选出自动生成的Requires或Provides的更多详细信息,请参阅:打包:AutoProvidesAndRequiresFiltering.

构建时间依赖项(BuildRequires)

包使用构建要求:标签。您可能会假设有足够的环境供RPM运行、构建包和执行基本的shell脚本,但您不应该假设任何其他包作为RPM依赖项存在,并且构建系统引入buildroot的任何内容都会随着时间而改变。

构建要求和%{伊萨}

您不得使用拱形BuildRequires。拱门最终位于建成的SRPM中,但SRPM需要独立于架构(architecture)。例如,如果您这样做:

#*不*做什么的示例构建要求:foo%{?_isa}>=3.3

然后,在Fedora中构建的SRPM将具有以下要求之一,具体取决于创建SRPM的构建器:

foo(x86-32)>=3.3#或foo(x86-64)>=3.3

这将阻止使用SRPM要求的yum-builddep或类似工具正常运行。

BuildRequires基于pkg配置

使用的Fedora软件包pkg配置根据它们所依赖的库(例如“foo”)进行构建,应该将其构建依赖关系正确表达为pkgconfig(foo)。有关详细信息,请参阅打包:PkgConfigBuildRequires.

条件构建时间依赖项

如果规范文件包含根据可选项的存在而选择的条件依赖项--有(无)foo参数到重建,构建要使用默认选项提交的源RPM,即,使这些参数都不存在于重建命令行。原因是这些需求被“序列化”到生成的源RPM中,即条件不再适用。

总结和说明

摘要应该是对文件包的简短描述。描述应在此基础上展开。

注意事项

  • 不要以句点结束摘要。

  • 摘要应为80个字符/列或更少。如果您使用的不是ASCII,请查看utf长度函数或类似的函数来计算列数。

  • 确保描述中的行长度不超过80个字符/列。如果您使用的不是ASCII,请查看utf长度函数或类似的函数来计算列数。

  • 说明中不包括安装说明;这不是一本手册。如果软件包需要一些手动配置或有其他重要的用户说明,请让用户参阅软件包中的文档。添加自述。费多拉或者类似的,如果你觉得这是必要的。

  • 为了保持一致,我们在摘要和描述中使用了美式英语拼写和语法规则。软件包可以包含支持的非英语语言的额外翻译摘要/描述(如果可用)。

摘要或说明中的商标

包装商应注意如何在摘要或说明中使用商标。有一些规则需要遵循:

  • 从不使用(TM)(右)(或Unicode等价物™/®)。正确地使用它们是非常复杂的,所以实际上我们完全不使用它们更安全。

  • 以不含糊的方式使用商标。避免使用“类似于”或“喜欢”这样的短语。一些示例:

  • 坏消息:它类似于Adobe Photoshop。

  • 良好:它支持Adobe Photoshop PSD文件

  • 坏消息:Microsoft Office的Linux版本

  • 良好:支持Microsoft Office DOC文件的文字处理器

如果你不确定,问问自己,有没有可能有人会感到困惑,认为这个包裹是商标商品?当有疑问时,尽量去掉商标。

文档

源发行版中包含的任何相关文档都应包含在相应文档目录中的包中。无关文档包括构建说明,无所不在安装包含非Linux系统的通用构建指令或示例以及文档的文件,例如。自述。MSDOS公司。还要注意您在哪个子包中包含文档。例如,API文档属于-开发子包,而不是主包。或者,如果有很多文档,可以考虑将其放在子包中。在这种情况下,建议使用*-文件作为子包名称。

标记a相对的路径具有%文件在中%文件节将导致RPM从中复制引用的文件或目录%_建筑工人到适当的位置进行文档记录。文件也可以放在%_pkgdocdir公司,被打包的软件的构建脚本在调用时可以自动执行此操作%安装。但是,混合使用这些方法是有问题的,可能会导致文件重复或冲突,因此使用%文件具有相对的文件的路径和直接安装到%_pkgdocdir公司禁止在同一源包中。

标记为文档的文件不得导致包引入比没有文档时更多的依赖项。在大多数情况下,确保这一点的一个简单方法是从中的文件中删除所有可执行权限%_pkgdocdir公司.

文件位于%_pkgdocdir公司不得影响打包软件的运行时。如果这些文件被修改、删除或根本没有安装,则软件必须正常运行且功能不变。

尽管许可证文件是文档,但会对它们进行特殊处理(包括使用不同的标记)。请参阅许可指南如何处理它们。

单独的文档包

如果构建文档需要许多其他依赖项,那么您可以选择不在主包中构建它,而是创建一个单独的*-doc源包,该源包只构建文档。此单独打包的文档必须与打包软件的版本相对应。换句话说,如果软件的新版本包括对文档的更改,那么文档包也必须更新。但是,如果新版本的软件不包含文档更改,则您可以选择不更新文档包。

应在主包的Version标签附近添加注释,以提醒维护人员在需要时更新单独的*-doc包。

变更日志

更改日志描述与包用户相关的包更改。这包括新的上游版本、对包构建方式的重要更改、重建以及其他影响结果的更改。变更日志中不应提及仅与包装商相关的变更。这包括规范文件清理、构建错误修复或解决方法,以及对二进制包的内容没有影响的其他更改。

变更日志应该使用%自动更改日志宏:

%变更日志%自动更改日志

提交主题(提交消息的第一行)和一些可选的附加行用于生成变更日志文本。变更日志条目中还使用提交作者姓名、电子邮件地址和提交时间戳。

提交消息中的文本将成为更改日志的一部分,它应该提供与用户相关的更改的简要摘要。提交消息可能包含与打包程序相关的附加信息。

如果特定更改与Bugzilla错误相关,请在更改日志条目中包含错误ID以便于参考,例如。

添加README文件(rhbz#1000042)

如果特定提交修复了CVE,则也应包含此信息。

其目的是给用户一个提示,告诉他们软件包更新中发生了什么变化,而不会让他们被技术细节淹没。它们绝不能简单地包含源CHANGELOG条目的完整副本。对于需要更多信息的用户,可以输入上游新闻文件或变更日志的链接。

请参见自动更改日志文档有关如何从git提交消息生成changelog的详细信息,以及如何为某些提交创建多行条目或跳过条目。

包装工可以或者使用手动更改日志,而不是%自动更改日志宏。这在中进行了描述手动更改日志.

例子

打包程序将包更新到版本1.0并创建提交

$git节目提交000000000001234567890EF00000000000作者:Joe Packager<joe@example.com>日期:2003年6月14日,星期三版本1.0…(rhbz#1000024)-还修复了rhbz#1000025中报告的减速-上游变更日志:https://example.com/package/NEWS.html#v1.0等级库文件中的空白区域已被清除。diff—git包.spec包.speg索引5c77064c03..efcd53a61c 100644---包装规格+++包装规格@@ -1,5 +1,5 @@名称:包-版本:0.1+版本:0.2释放:%自动释放...

构建包时,将生成适当的更改日志条目。可以使用预览rpmautospec生成噬菌体日志:

$rpmautospec生成更改日志*2003年6月14日星期三Joe Packager<joe@example.com> - 0.2-1-版本1.0(rhbz#1000024)-还修复了rhbz#1000025中报告的减速-上游变更日志:https://example.com/package/NEWS.html#v1.0

请注意,关于空白的句子不包括在变更日志中。

手册

由于手册页是获取Unix系统帮助的传统方法,因此包中应包含所有可执行文件的手册页。如果缺少一些手册页,包装商应与上游合作添加这些手册页。偶尔也可以找到其他发行版创建的页面,或使用帮助2man程序;这些通常是有用的起点。安装手册页时,请注意RPM会将其重新压缩为首选格式。所以%文件章节必须使用考虑到这一点的模式引用手册页:

%文件%{手动}/man1/foo.1*

还请注意,安装在中的文件%{mandir}(_M)由RPM自动标记为文档。因此没有必要使用%文件.

对于本地化的手册页,请使用%find_lang—与man一起如中所述处理区域设置文件.

编译器

如果上游不支持使用gcc构建,Fedora包应默认使用gcc作为编译器(对于gcc支持的所有语言)或clang。然而,如果有很好的技术原因,打包程序可能会选择不使用默认编译器。不使用默认编译器的有效技术原因示例包括但不限于:

  • 默认编译器无法正确生成包。

  • 为了让默认编译器正确编译其包,打包程序需要禁用编译器功能(例如LTO)。

  • 默认编译器构建包的时间要长得多。

  • 默认编译器缺少对包有益的功能。

选择使用非默认编译器的打包程序应在规范文件的注释中记录此决定的原因。

编译器宏

如果使用clang构建包,则打包程序必须将%toolchain宏设置为clang:

%全球工具链叮当作响

这确保了在编译时使用Fedora的特定于clang的编译器标志。

如果打包程序希望在规范文件中使用条件宏,以便在两个不同的编译器之间切换,则应使用以下宏名称:

%bcond_with toolchain_clang(与工具链链接)%bcond_带工具链_gcc

打包程序还可以使用spec文件中的%build_cc、%build_cxx或%build-cpp宏来代替编译器名称的硬编码。通过将%toolchain宏设置为clang或gcc来控制这些变量的值。

编译器标志

用于构建包的编译器必须遵循系统rpm配置中设置的适用编译器标志。遵循意味着该变量的内容被用作编译器在包构建期间实际使用的标志的基础。

对于C、C++和Fortran代码%{optflags}宏包含这些标志。通常不鼓励在性能优化中覆盖这些标志(例如,使用-O3而不是-O2)。如果您可以提供基准测试,以显示此特定代码的显著加速,那么可以逐个案例重新进行讨论。如果有充分的理由,允许添加、覆盖或过滤这些标志的部分;这样做的理由必须记录在规范文件中。

通常允许使用某些与安全相关的标志。这些标志可能会稍微降低性能,但对某些程序来说,增加安全性是值得的。

PIE公司

PIE通过将可执行文件完全由位置无关的代码组成来为其添加安全性。位置相关代码(PIC)是正确执行的机器指令代码,与它在内存中的位置无关。PIE允许Exec Shield使用地址空间布局随机化,以防止攻击者在安全攻击期间使用依赖于知道二进制文件中可执行代码偏移量的漏洞(例如return to libc攻击)知道现有可执行代码的位置。

在Fedora中,默认情况下启用PIE。要在规范中禁用它,请添加:

%未定义_硬化_构建

如果您的程序包符合以下任何条件,则不得禁用PIE编译器标志:

  • 你的包裹很长时间了。这意味着它可能会启动并一直运行,直到机器重新启动,而不是按需启动并在空闲时退出。

  • 您的包中包含suid二进制文件,或者包含功能的二进制文件。

  • 您的程序包以root身份运行。

Debuginfo包

包装应产生有用的-调试信息包,或者在无法生成有用包时显式禁用它们,但rpmbuild无论如何都会这样做。每当-调试信息包被显式禁用,规范文件中需要解释为什么这样做。Debuginfo包将在单独的文档中进行更详细的讨论,包装:Debuginfo.

Devel软件包

Fedora包的设计必须具有文件的逻辑分隔。具体来说,-devel包必须用于包含仅用于开发或仅在构建时需要的文件。这样做是为了最小化用户的安装占用空间。有一些类型的文件几乎总是属于-devel包:

  • 头文件(foo.h),通常位于/usr/include中

  • 包未提供任何匹配的共享库文件时的静态库文件。请参见打包静态库有关此场景的更多信息。

  • 如果还存在匹配的版本化共享系统库文件,则为未版本化共享的系统库文件。例如,如果您的软件包包含:

/usr/lib/libfoo.so.3.0.0/usr/lib/libfoo.so.3/usr/lib/libfoo.so

版本化的共享库文件(/usr/lib/libfoo.so.3.2.0和/usr/lib/libfoo.so.3)是用户运行与libfoo链接的程序所必需的,因此它们属于基本包。另一个未版本化的共享库文件(/usr/lib/libfoo.so)仅用于将libfoo实际链接到正在编译的代码,不需要安装在用户系统上。这意味着它属于-devel包。请注意,在大多数情况下,只有完全版本化的共享库文件(/usr/lib/libfoo.so.3.2.0)才是实际文件,所有其他文件都是指向该文件的符号链接。当共享库文件仅以非版本化格式提供时,打包程序应要求上游考虑提供正确版本化的库文件。然而,在这种情况下,如果用户需要共享库文件来运行链接到它的程序,那么它必须进入基本包。如果上游在将来对共享库文件进行版本控制,则打包人员必须小心移动到上述版本控制布局。

未版本化的共享对象

作为一个额外的复杂性,一些软件生成未版本化的共享对象它们不打算用作系统库。这些文件通常是特定于应用程序的插件或模块化功能,不应位于ld库路径或缓存中。这些类型的未版本化共享对象不需要进入-devel包。它们只在运行时加载,并且应该包含在主包的私有目录中。

有关如何处理这些类型的配电系统运营商的具体详细信息,请参阅未版本化的共享对象以获取详细指导。

例外情况

这种包装模式有一些明显的例外,具体如下:

  • 编译器通常在主包中包含开发文件,因为编译器本身仅用于软件开发,因此,拆分包模型没有任何意义。

当对文件是否属于基本包或in-devel有疑问时,打包人员应考虑该文件是否有必要存在,以便用户正确使用或执行基本包中的功能,或者是否仅用于开发。如果它只是开发所必需的,那么它必须进入-devel包。

与所有Fedora包装指南一样,人们认识到,有一些独特的情况超出了这个模型的边界。如果你遇到这种情况,请用Fedora包装委员会并向我们解释,以便我们能够扩展指南来解决这一问题。

Pkgconfig文件(食品.pc)

pkgconfig(.pc)文件的位置取决于其用例。因为它们几乎总是用于开发目的,所以应该放在-devel包中。一个合理的例外是,主包本身是一个开发工具,没有安装在用户运行时中,例如gcc或gdb。

需要基本包

子包通常是其基本包的扩展,在这种情况下,它们应该需要其基本包。当子包需要基本包时必须使用完全版本化的特定于体系结构的依赖项(对于非noarch包)执行此操作:

需要:%{name}%{?_isa}=%{版本}-%{发布}

Devel包是一个必须使用完全版本依赖项的基本包的包示例-仅包含共享库的libs子包通常不需要显式依赖于其基本包,因为它们通常不需要基本包成为功能库。

如果您最终遇到主包依赖于子包和主包上的子包的情况,您应该仔细考虑为什么主包中没有所有内容。

共享库

只要可能(并且可行),包含库的Fedora包都应该将它们构建为共享库。没有必要打电话ld配置安装共享库时。

列出共享库文件

直接安装到中的共享库%{_libdir} 不应该列在%文件通过使用glob来隐藏文件名的重要部分(例如。libfoo.so文件*),因为更改了SONAME公司在大多数情况下,还会导致文件名更改。

否则,当库遇到SONAME公司作为更新的一部分,此更改可能会被忽略,并导致诸如断开依赖关系之类的问题(请参阅相关的更新策略部分了解更多信息)。

然而,如果包装商认为globs的使用有用,例如,如果Y(Y)Z名为的库的部分libfoo.so.X.Y.Z经常更改,使用类似libfoo.so.X{,.*}相反,建议使用,因为依赖包通常不必为此类更改重新构建。

下游.所以名称版本控制

在上游船舶未版本化的情况下图书馆(因此插件、驱动程序等不需要这样做),打包程序必须尝试说服上游开始对其进行版本控制。

如果由于上游不情愿或无响应而失败,则打包者可能会开始下游版本控制,但必须谨慎操作,最好只在极少数情况下进行。我们不想创建一个可能与上游冲突的库,如果他们稍后开始提供版本化的共享库。在任何情况下,都不应在Fedora中运送未版本化的库。

对于下游版本控制,名称应如下所示:

libfoobar.so.0.n

这个n个最初应该是一个小整数(例如,“1”)。我们在这里使用两个数字(“0.n”),因为上游的常见做法是在这里只使用一个数字。使用多个数字有助于我们避免未来潜在的冲突。不要忘记将SONAME字段(参见下文)添加到库中。

发布库的新版本时,应使用ABI比较工具检查构建的共享库中的ABI差异。如果检测到任何不兼容,请将n个数字乘以一。

SONAME处理

当使用SONAME字段运行链接到共享对象的可执行文件时,动态链接器会检查此字段而不是文件名,以确定它应该链接到的对象。这允许开发人员简单地链接到未版本化的库符号链接,动态链接器将链接到正确的对象。

请记住,尽管文件名通常是库的SONAME加上一个递增的次要版本,但并没有任何内在联系。ldconfig使用SONAME作为指向实际文件名的符号链接的值。然后,动态链接器使用该符号链接查找库,而不考虑实际的文件名。动态链接器只对字段进行简单的相等性检查,不检查ABI不兼容或类似问题。这是使用ABI比较工具并增加SONAME。

链接器使用(至少在以下情况下)将SONAME字段写入共享对象ld个)的-soname soname公司旗帜。这可以作为选项传递给海湾合作委员会这样地:

$gcc$CFLAGS-Wl,-soname,libfoo.so.0.n-o libfoo.so.0.n

如果要检查是否设置了SONAME字段以及它的值,请使用反汇编命令(来自binutils公司):

$objdump-p/path/to/libfoo.so.0.n|grep“SONAME”

打包静态库

包含库的包应尽可能排除静态库(例如,通过配置--禁用静态). 与库链接的应用程序应该与共享库链接,而不是静态版本。

Libtool档案,食物.la文件,不应包括在内。默认情况下,使用libtool的软件包将安装这些软件,即使您使用配置--禁用静态,因此可能需要在包装前将其移除。由于libtool旧版本中的错误或使用它的程序中的错误,有时不可能在不修改程序的情况下删除*.la文件。在大多数情况下,与上游合作解决这些问题相当容易。请注意,如果您正在稳定版本(而不是devel)中更新库,并且包中已经包含*.la文件,那么删除*.la文件应该被视为API/ABI更改-即,删除它们会更改库提供给世界其他地方的接口,因此必须遵循Fedora政策,以进行可能会破坏稳定的更新。

打包静态库

  • 一般来说,包装商不应该运送静态库。

  • 我们希望能够跟踪哪些包正在使用静态库(例如,如果修复了静态库中的安全缺陷,那么我们可以找到需要重建哪些包)。静态库打包有两种情况:

    1. 静态库和共享库。在这种情况下,静态库必须放置在*-静态分装。将静态库与其他开发文件分离在里面*-开发允许我们通过检查哪些包来跟踪此使用情况需要生成这个*-静态包裹。其目的是只要可能,包将不再使用这些静态库,到共享库。如果*-静态子包需要标头或其他文件*-开发为了有用,它必须要求*-开发分装。

    2. 仅限静态库。当包只提供静态库时您可以将所有静态库文件放在*-开发分装。这样做时,您还必须有一个虚拟供应商对于*-静态包裹:

      %软件包开发提供:foo-static=%{版本}-%{发布}

明确需要链接到静态版本的包必须BuildRequire:食品静态,以便可以跟踪使用情况。

  • 如果(并且仅当)包具有需要静态库才能正常工作的共享库,则可以将静态库包含在*-开发分装。开发子包必须具有虚拟的*-静态包及其依赖的包必须需要生成这个*-静态包裹。

打包仅标头库

某些库,尤其是一些C++模板库,是仅标头库。因为代码是在编译时生成的,所以它们的行为就像静态库一样,需要这样处理。

将所有头文件放在*-开发子包,然后必须为*-静态包裹:

%软件包开发提供:foo-static=%{版本}-%{发布}

使用头库的包必须BuildRequire:食品静态,以便可以跟踪使用情况。

仅在子包中使用noarch

头库的基本包不得标记为noarch。这样可以确保在所有体系结构上运行任何测试,并可以检测构建或安装过程是否基于构建体系结构修改了标头。

当子包的内容,包括-开发包,实际上是架构依赖的,它们可能仍然被标记为noarch。由于头库的基本包通常没有%文件列表中,这可能会产生一个只构建noarch-rpms的arched包。这可能需要添加%全局调试包%{nil}到spec文件,以避免为空调试源文件.list问题。

静态链接可执行文件

不应将可执行文件和库与来自其他包的库静态链接。(当然,在包的构建过程中生成的文件可以静态链接到.a个作为构建过程的一部分生成的文件。)

如果需要链接到.a个来自不同包的文件,对-静态包(不仅仅是-开发提供这些文件的软件包)必须存在,以便可以跟踪使用情况。

系统库的捆绑和复制

Fedora包应尽一切努力避免将多个独立的上游项目捆绑在一个包中。

所有上游允许根据系统库构建的包都必须根据系统库进行构建。在这种情况下,捆绑库(和/或其源代码)必须在%准备。可能需要修补生成脚本以处理此情况。只要可能,补丁应该限制捆绑库的使用,以便可以将补丁发送到上游以供考虑。

所有上游没有针对系统库构建机制的软件包都可以选择使用捆绑库,但如果使用,则必须包含捆绑库的指示。这提供了一种使用捆绑代码定位库的机制,例如,它可以帮助定位可能具有特定安全漏洞的包。

要指示绑定实例,请首先确定绑定库的名称和版本:

  • 如果捆绑包也单独存在于分发中,请使用该包的名称。否则请咨询命名原则确定库的适当名称,就像它作为单独的包进入分发版一样。

  • 使用版本控制指南以确定库的适当版本(如果可能)。如果库是从上游派生的,请使用最近合并或重新基于的上游版本,或原始库在派生时携带的版本。

然后在规范中的适当位置添加提供:捆绑(<libname>)=<version>哪里<libname><版本>是您在上面确定的名称和版本。如果无法确定版本,请使用提供:捆绑(<libname>)而不是。

除了以这种方式指示捆绑外,对于上游没有针对系统库构建机制的包,必须公开联系以获取支持系统库的路径。如果上游拒绝,则必须将其记录在规范文件中,可以是放在上面“提供:”旁边的注释中,也可以是检入SCM并由放置在提供:以上。

避免在其他软件包中捆绑字体

通用格式的字体,如Type1、OpenType TT(TTF)或OpenType CFF(OTF),应遵守特定的包装准则(包装/字体政策),并且应该始终打包在系统范围的字体存储库中,而不是私有应用程序目录中。有关详细信息,请参阅:包装/字体政策.

当心rpath(rpath)

有时,在链接二进制文件时,代码会硬编码特定的库路径(使用-rpath或-R标志)。这通常被称为rpath。通常,动态链接器和加载程序(ld.so)解决可执行文件对共享库的依赖性,并加载所需的内容。然而,当使用-rpath或-R时,位置信息将硬编码到二进制文件中,并在执行开始时由ld.so检查。由于Linux动态链接器通常比硬编码路径更智能,因此我们通常不允许在Fedora中使用rpath。

有一种工具叫做检查路径包含在rpmdevtools工具包裹。将其添加到%__架构_安装_支柱~/.rpmmacro公司配置文件:

%__架构_安装_支柱\/usr/lib/rpm/checkrpath\/usr/lib/rpm/check-buildroot

什么时候?检查路径运行时,您可能会看到如下输出:

错误0001:文件“/usr/bin/xapia-tcpsrv”在[/usr/lib64]中包含标准rpath“/usr/lib64”

检查路径标记的任何rpath必须被删除。

rpath(rpath)用于内部库

当程序安装内部库时,它们通常不会安装在系统路径中。这些内部库仅用于包中存在的程序(例如,用于排除可执行文件通用的代码)。这些库不打算在包外使用。发生这种情况时,包中的程序可以使用rpath来查找这些库。

例子:

#myapp的内部库位于:%{_libdir}/我的应用程序/%{_libdir}/myapp/libmyapp.so.0.3.4%{_libdir}/myapp/libmyapp.so#myapp具有%{_libdir}/myapp的rpath/readelf-d/usr/bin/myapp|grep RPATH0x0000000f(RPATH)库RPATH:[/usr/lib/myapp]
非内部库:当程序不在包内时应该链接到图书馆,最好使用Rpath的替代方案或者只需将库移动到%{_libdir}而不是。这样,动态链接器可以找到库无需使用rpath链接所有程序。

替代方案rpath(rpath)

通常使用rpath是因为二进制文件正在非标准位置查找库(标准位置是/lib、/usr/lib、/lib64、/usl/lib64)。如果要将库存储在非标准位置(例如/usr/lib/foo/),则应在/etc/ld.so.conf.d/中包含自定义配置文件。例如,如果我将32位libfoo库放在/usr/lib/foo中,我想在/etc/ld.so.conf.d/中创建一个名为“foo32.conf”的文件,其中包含以下内容:

/usr/lib/foo

确保您也制作了该文件的64位版本(例如foo64.conf)(当然,除非该包对64位体系结构禁用)。

正在删除rpath(rpath)

有几种不同的方法可以修复rpath问题:

  • 如果应用程序使用configure,请尝试传递--禁用路径要配置的标志。

  • 如果应用程序使用libtool的本地副本,请在%configure之后将以下行添加到规范中:

%配置sed-i的|^hardde_ibdir_flag_spec=.*|hardde_libdir_fag_spec=“”|g'库工具sed-i的|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g'库工具
  • 有时,可以修补代码/生成文件以删除-rpath(rpath)-R(右)标记不被调用。然而,这样做并不总是容易或明智的。

  • 作为最后的手段,Fedora有一个名为chrpath公司。安装此包后,可以运行chrpath—删除包含rpath的文件。因此,在前面的示例中,我们将运行:

chrpath—删除$RPM_BUILD_ROOT%{_bindir}/xapani-tcpsrv

确保记住添加构建要求:chrpath如果你最终使用这种方法。

配置文件

配置文件必须在包中进行标记。

根据经验,使用%配置(noreplace)而不是普通的%配置除非你最好的、有根据的猜测是,这样做会破坏一切。换言之,在升级包时覆盖配置文件中的本地更改之前,请仔细考虑。以下情况的示例使用诺雷普莱斯是指包的配置文件发生更改,导致新的包版本无法与以前包版本的配置文件一起使用。只要是普通的%配置如果使用,请在规范文件中添加简短注释,解释原因。

不要在/usr下使用%config或%config(noreplace)/usr被认为不包含Fedora中的配置文件。

包管理器的配置

软件包不得安装违反第三方存储库策略,除非这些文件安装在%{文档目录}.

产品配置

在Fedora.next世界中,我们将有一套精选的Fedora产品以及经典Fedora的可用性。从历史上看,我们为所有Fedora安装维护了一组默认配置,但不同的目标用例有不同的需求。请参阅产品配置指南获取有关如何创建需要在Fedora.next产品之间表现不同的包的说明。

起始程序

Fedora中禁止使用SystemV样式的initscripts。必须使用系统装置。

系统单元

打包系统单元和系统管理服务的详细指南如下在这里.

桌面文件

如果一个包包含GUI应用程序,那么它还需要包含一个正确安装的.desktop文件。出于这些准则的目的,GUI应用程序被定义为绘制窗口并从该窗口中运行的任何应用程序。已安装。桌面文件必须遵循台式机-规格,特别注意验证Name、GenericName的正确用法,类别,启动通知条目。

桌面文件中的图标标记

可以通过两种方式指定图标标记:

  • 特定图标文件的完整路径:

图标=/usr/share/pixmaps/comical.png

  • 不带文件扩展名的短名称:

图标=滑稽

首选不带文件扩展名的短名称,因为它允许图标主题化(默认情况下假定为.png,然后尝试.svg,最后尝试.xpm),但这两种方法都可以接受。

.桌面文件创建

如果包中还没有包含并安装自己的.desktop文件,那么您需要创建自己的。您可以通过包含创建为源的.desktop文件(例如Source3:%{name}.desktop:)或在规范文件中生成它来实现这一点。以下是示例.desktop文件(comical.desktop)的内容:

[桌面输入]名称=滑稽GenericName=漫画存档阅读器注释=打开.cbr和.cbz文件执行=滑稽图标=滑稽端子=假类型=应用类别=图形;

桌面文件安装用法

仅仅在包中包含.desktop文件是不够的,必须运行桌面文件安装(英寸%安装)或桌面文件验证(英寸%检查%安装)并且有BuildRequires:桌面文件,以帮助确保.desktop文件的安全性和规范合规性。桌面文件安装如果软件包未安装文件或对.desktop文件进行了所需的更改(例如添加/删除类别等),则必须使用。桌面文件验证如果.tdesktop文件的内容/位置不需要修改,则可以使用。以下是一些用法示例:

桌面文件安装\--目录=%{buildroot}%{datadir}/applications\%{来源3}
桌面文件安装\--add-category=“音频视频”\--删除原始文件\--目录=%{buildroot}%{datadir}/applications\%{buildroot}/%{datadir}/applications/foo.desktop
桌面文件验证%{buildroot}/%{datadir}/applications/foo.desktop

将供应商标记应用于.desktop文件(使用--vendor)。

AppData文件

包含图形应用程序的包应包含AppData文件。请参见打包:AppData相关指南。

强烈建议打包程序使用宏而不是硬编码目录名(请参阅RPM宏). 然而,在宏比它所代表的路径长的情况下,或者在打包程序觉得使用实际路径更干净的情况下。打包程序可以使用实际路径而不是宏。这种方法有几个注意事项:

  • 包必须一致。对于同一规范中的任何给定路径,请使用硬编码路径或宏,而不是两者的组合。

  • %{libdir}必须始终用于二进制库,因为有多个库,您不能替换硬编码路径。

名称以下划线开头的宏通常被视为RPM及其相关宏包内部的实现细节,不应在规范文件中引用,除非设置其值以影响RPM行为。这意味着不应使用系统可执行文件的宏形式。例如,rm(毫米)应优先使用%{__rm}然而,在某些情况下,所需的数据根本不在没有下划线前缀的名称下提供。如果是这种情况,可以使用带前导下划线的宏。建议宏包的作者在命名要在规范文件中使用的宏时避免使用前导下划线(与设置相反)。

在Source:或Patch:行中包含宏是一个风格问题。有些人喜欢没有宏的源代码行的可读性。其他人更喜欢在使用宏时轻松更新新版本。在所有情况下,请记住在规范文件中保持一致,并验证列出的URL是否有效。spectool(来自rpmdevtools包)可以帮助您检查URL是否包含宏。

如果需要确定包含宏的实际字符串,可以使用rpm。例如,要确定实际Source:值,可以运行:

rpm-q--spec文件foo.spec--qf“$(grep-i^源foo.spe)\n”

%自动设置

作为常规的替代方案%设置%自动设置可以使用。除了正常的%设置任务外,它将自动应用规范中定义的所有修补程序#项。它还能够处理VCS格式的修补程序文件,但这需要额外的BuildRequires,并且假设全部的规范中的补丁文件是为单个VCS类型格式化的。因此,建议您不要使用%自动设置。有关正确使用的更多详细信息%自动设置,请参阅RPM文档.

使用%{内置程序}%{操作标志}$RPM_BUILD_ROOT($RPM_FUILD_ROOT)$RPM_OPT_FLAGS(美元)

在等级库文件中定义rpm Build Root和Optimization Flags有两种样式:

宏样式

可变样式

生成根目录

%{内置程序}

$RPM_BUILD_ROOT($RPM_FUILD_ROOT)

选择。旗帜

%{操作标志}

$RPM_OPT_FLAGS(美元)

选择一种样式而不是另一种样式没有什么价值,因为它们在所有场景中都会解析为相同的值。你应该选择一种风格,并在整个包装中始终如一地使用它。

混合这两种风格虽然有效,但从QA和可用性的角度来看是不好的,不应该在Fedora包中进行。

为什么%制造装置不应使用宏

Fedora的RPM包括%制造装置宏,但必须不是当make-install-DESTDIR=%{buildroot}工作时使用。%makeinstall是一个笨蛋,可以与不使用DESTDIR变量的Makefiles一起使用,但它有以下潜在问题:

  • %制造装置在“Make-install”期间重写一组Make变量,并在%{buildroot}路径前面加上前缀,即它执行Make-prefix=“%{buillroot}%{_prefix}”libdir=“%}buildroot}%{_libdir}…”。

  • 它很容易出错,在针对不太完美的Makefiles运行时可能会产生意外影响,例如,buildroot路径可能包含在安装时替换变量的已安装文件中。

  • 在执行“makeinstall”时,它可能会触发不必要的错误重建,因为make变量与%build部分的值不同。

  • 如果包中包含libtool存档,则可能会导致安装损坏的*.la文件。

相反,Fedora软件包应使用:%make_install(安装)(注意“_”!),使DESTDIR=%{buildroot}安装使DESTDIR=$RPM_BUILD_ROOT安装所有这些都做同样的事情。

源RPM构建时宏

中的所有宏总结:%描述需要在srpm构建时可扩展。由于SRPM是在未安装包的BuildRequires的情况下构建的,因此根据在规范文件外部定义的宏,很容易导致未展开的宏显示在构建的SRPM中。检查的一种方法是创建一个最小的chroot并构建srpm:

模拟--初始化模拟--复制/mock—shell bash转速-ivhcd/builddir/build/SPECS(光盘/构建目录/构建/SPECS)rpmbuild-bs--节点[SRPM]rpm-qpiv/builddir/build/build/SRPMS/[SRPM]

检查每分钟转数未展开宏的输出(%{foo})或缺少信息(当`%{?foo}`展开为空字符串时)。更简单的方法是在总结:%描述除非它们在当前规范文件中定义。

不当使用%_sourcedir公司

使用列为Source#文件的文件的程序包必须通过其引用这些文件来源#宏名称,不能使用$RPM_SOURCE_DIR(源代码)%{源代码}以引用这些文件。请参见打包:RPM_Source_Dir了解详细信息。

软件集合宏

软件集合将保留以将包与主流包分开,类似于MingW包被管理。

过去,如果不使用SCL宏,则允许它们出现在主流包中。由于我们现在正在建立SCL,我们现在正在实施严格的分离。包装必须更新以将SCL宏仅限于那些特别批准作为SCL一部分的包。

其他RPM宏的打包

其他RPM宏必须存储在%{_rpmacrodir}中。它们必须使用语法“macros.$PACKAGE”命名(例如macros.perl)。

通常,这些文件打包在-devel子包中,因为它们通常只用于构建其他包。然而,在某些情况下,这并不总是理想的,我们鼓励打包人员在为这些文件确定合适的包时使用他们的最佳判断。RPM宏文件不得标记为%配置.

在规范文件内部编写脚本

有时需要编写一个简短的脚本(可能是一行),该脚本在%准备,%建造,或%安装spec文件的部分,以获取有关构建环境的一些信息。为了简化依存关系图,等级库文件应仅使用以下语言:

  • 蟒蛇

  • 波尔

  • shell编程中使用的标准程序,例如gawk或sed

  • Lua(由rpm中的本地Lua解释器支持)

此外,如果您的包在没有特定脚本语言(如Ruby或Tcl)的情况下无法构建,并且因此已经在该语言上有了BuildRequires,则也可以从规范文件中调用它。

注意:如果在规范文件中调用Perl或Python(并且它还不是包的BuildRequires),则需要显式地为Perl或Python添加BuildRequires。

%全球优先于%定义

使用%全球而不是%定义,除非在其他宏定义中确实只需要本地定义的子宏(这种情况非常罕见)。

理由:当两个宏定义语句处于rpm嵌套级别的顶层时,它们的行为相同。

但当它们用于嵌套宏展开时(如%{!?foo:…}构造,%定义理论上只持续到端撑(局部范围),而%全球定义具有全局范围。

请注意,%define和%global的区别不仅仅在于作用域:%defined宏的主体是延迟展开的(即在使用时),而%globol的主体是在定义时展开的。可以使用%%-转义来强制%global的惰性扩展。

处理区域设置文件

翻译文件可以由不同的程序针对不同的框架来处理。确保为正确的包添加BuildRequires:,否则包可能无法在buildroot中生成翻译文件。

如果包使用gettext进行翻译,请添加

构建要求:gettext

对于使用Linguist工具链的基于Qt的包,对于本地化实用程序,添加

构建要求:qt-level

如果您的区域设置文件足够少,可以将它们全部放在一个包中,则可以使用%查找语言宏。(如果您需要将软件包拆分为单独的语言包,请参阅langpack指南.)此宏将定位属于您的包的所有文件(按名称),并将此列表放入文件中。然后可以使用该文件来包含所有区域设置。%查找语言在所有文件都安装到buildroot之后,应该在spec文件的%install部分中运行。的正确语法%查找语言通常是:

%find_lang%{name}

在某些情况下,应用程序可能会对其区域设置使用不同的“名称”。您可能需要查看区域设置文件并查看它们的名称。如果他们被命名我的app.mo,那么你需要通过米亚普%查找语言而不是%{名称}.之后%查找语言如果运行,它将在活动目录(默认情况下,源目录的顶层)中生成一个文件。此文件将根据您作为选项传递给%查找语言宏。通常,它会被命名为%{name}.lang(名称)。然后应在%文件列表以包含检测到的区域设置%查找语言。为此,您应该将其与-f参数一起包含到%文件.

%文件-f%{name}.lang%{_bindir}/foobar...

请注意%查找语言默认情况下搜索gettext区域设置,但它也可以处理Qt翻译、本地化的手册页和帮助文件。

处理放入的GNOME帮助文件/usr/share/gnome/help/使用

%find_lang%{name}--带名词

处理放入的KDE帮助文件/usr/share/doc/HTML/使用

%find_lang%{name}--带-kde

处理Qt.qm(平方米)二进制翻译文件使用

%find_lang%{name}--带-qt

要处理本地化的手册页(不包括默认的非本地化手册页),请使用

%find_lang%{name}--与man

要查看所有选项,请运行/usr/lib/rpm/find-lang.sh在航站楼。

名称不同于%{名称}(例如,多个手册页)必须通过单独调用来处理%查找语言.

下面是正确使用%查找语言,英寸食品规格使用gettext和名为“bar”而不是“foo”的手册页本地化“foo“应用程序:

名称:foo...%准备%设置-q%建造%配置--带目录制作%{?_smp_mflags}%安装使DESTDIR=%{buildroot}安装%find_lang%{name}%find_lang栏--with-man%文件-f%{name}.lang-f bar.lang%许可证许可证%文档自述文件%{绑定}/%{名称}%{曼迪尔}/man1/bar.1*%变更日志*2012年1月13日星期五Karel Volny<kvolny@redhat.com> 0.1-2-添加手册页示例*2006年5月4日星期四Tom“spot”Callaway<tcallawa@redhat.com> 0.1-1-使用%%find_lang的示例规范

为什么需要使用%find_lang?

使用%查找语言有助于使规范文件保持简单,并有助于避免其他几个打包错误。

  • 使用的程序包%{数据目录}/*要在一行中获取所有语言环境文件,还需要获取语言环境目录的所有权,这是不允许的。

  • 大多数具有区域设置的包都有许多区域设置。使用%查找语言在spec文件中比必须执行以下操作要容易得多:

%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo%{_datadir}/locale/be/LC_MESSAGES/%{name}.mo%{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo%{_datadir}/locae/de/LC_MESSAGES/%{name}.mo%{_datadir}/locale/es/LC_MESSAGES/%{name}.mo...
  • 随着新的语言环境文件出现在以后的包修订中,%查找语言在运行时会自动包含它们,从而避免您必须更新规范。

请记住%查找语言在包含区域设置的包中是必须的,除非将区域设置文件分解为语言包。在这种情况下,您应该遵循langpack指南.

日志文件

生成日志文件的包应在%{_localstatedir}/log下的包特定(和包拥有的)目录中写出其日志文件。除非要打包的软件旋转其自己的日志,否则它还必须附带一个logrotate配置文件来旋转其日志文件。

轮替配置文件

Logrotate配置文件的命名方式应与生成日志的守护程序/软件相匹配,通常(尽管并不总是)与包的名称相同。如果不确定,请使用“%{name}.conf”。这些文件必须放在%{_sysconfdir}/logrotate.d中,并且应该使用标准文件权限(0644)和所有权(root:root)。

由于这些是配置文件,因此必须在%文件列表中将其标记为%config(noreplace)。

示例Minimal轮替配置文件

/var/log/example/*log{missingok#如果日志文件丢失,则继续执行下一个日志文件,而不发出错误消息notifempty#如果日志文件为空,则不执行任何旋转compress#使用gzip压缩旧文件delaycompress#不压缩昨天的文件}

时间标记

在spec文件中添加文件复制命令时,请考虑使用保留文件时间戳的命令,例如。,cp-p安装-p.

下载源代码、补丁等时,请考虑使用保留上游时间戳的客户端。例如wget-N(宽)卷曲-R。要使wget的更改具有全局性,请将其添加到您的~/.wgetrc:时间戳=开对于卷发,添加到您的~/.curlrc:-R(右).

平行制造

只要可能,调用制作应按照

%建造(_B)

这通常会加快构建速度,尤其是在SMP机器上。

但是,请确保包以这种方式干净地构建,因为某些make文件不支持并行构建。因此,您应该考虑添加

%_smp_mflags-j3

到您的~/.rpmmacro公司文件(甚至在UP机器上),因为这将暴露大多数错误。

脚本片断

在Fedora包中使用scriptlet时应格外小心。如果使用了scriptlet,那么这些scriptlet必须是健全的。记录了一些常见的scriptlet在这里.

脚本只允许写入某些目录

包的生成脚本(%prep、%Build、%install、%check和%clean)只能根据以下矩阵更改%{buildroot}、%{_builddir}下的文件(创建、修改、删除)和有效的临时位置,如/tmp、/var/tmp(或$TMPDIR或%{_tmppath},由rpmbuild进程设置)

/tmp、/var/tmp、$TMPDIR、%{_tmppath}

%{构建程序}

%{内置程序}

%准备

%建造

%安装

%检查

%清洁

进一步澄清:无论构建者的uid如何,这都应该是正确的。

使用单独的用户帐户生成包

在构建尚未进行全面安全审计的软件时,请在单独的用户帐户中保护敏感数据,如GPG私钥。

这同样适用于评审员/测试人员。在无权访问任何敏感数据的单独帐户中重建src.rpms。

可重新定位的软件包

强烈反对使用RPM的设施生成可重定位的包。很难正常工作,无法从安装程序或yum使用,如果遵循其他打包准则,通常也不需要。然而,如果您有充分的理由使包可重新定位,那么在不太可能的情况下,您必须在包审查请求中说明这一意图和理由。

文件和目录所有权

您的软件包应该拥有作为%install过程一部分安装的所有文件。

在大多数情况下,不需要多个包包含同一文件的相同副本。但是,如果有必要,只要满足以下要求,多个包可能包含同一文件的相同副本:

  • 共享相同文件所有权的包是从单个SRPM构建的。

  • 共享相同文件所有权的包不在依赖链中(例如,如果包a需要包B,它们不应同时包含相同的文件,a或B必须拥有公共文件,但不能同时拥有两者。)

此外,相同的文件被定义为在每个包中的文件系统上的内容、校验和、权限和位置始终相同的文件。

一种值得注意的文件类型是许可证文本,它通常在子包之间以相同的方式共享。在某些情况下,需要跨包中的多个%files节复制许可证文本。有关更多详细信息,请参阅子包许可.

目录所有权比文件所有权稍微复杂一些。包必须拥有其放置文件的所有目录,但以下目录除外:

  • 拥有的任何目录文件系统,男人,或其他显式创建的-文件系统包装

  • 包的自然依赖链中其他包拥有的任何目录

在这种情况下,包的“自然依赖链”被定义为该包正常运行所必需的包集。具体地说,您不需要仅因为包拥有放置文件的目录而需要包。如果您的包由于其他原因已经需要该包,那么您的包不应该也拥有该目录。

在所有情况下,我们都会防止系统中出现无主目录。请参阅打包:未拥有的目录了解详细信息。

当共享目录时,您必须确保目录的所有权和权限在所有拥有它的包中匹配。

以下是描述如何处理大多数目录所有权情况的示例。

该目录完全包含在包中,或者涉及包的核心功能

例如:

gnucash将许多文件放在/usr/share/gnucash目录下

解决方案:格努卡什包应该拥有/usr/share/gnucash目录

该目录还归实现包所需功能的包所有

例如:

pam拥有/etc/pam.d目录gdm将文件放在/etc/pam.d中gdm依赖pam正常工作,并且将Require:pam(隐式或显式)与目录所有权分离。

解决方案:聚丙烯酰胺包应该拥有/等/pam。d日目录,和全球数据管理应该要求:这个聚丙烯酰胺包裹。

该目录由一个程序包所有,该程序包不需要该程序包才能运行

一些包创建和拥有目录的目的是允许其他包存储适当的文件,但这些其他包不需要原始包才能正常运行。

例如:

gtk-doc拥有/usr/share/gtk-doc/目录evolution将文件放入/usr/share/gtk-doc/进化不需要gtk-doc才能正常运行。evolution的依赖链中没有任何东西拥有/usr/share/gtk-doc/

解决方案:进化包应该拥有/usr/share/gtk文档目录。没有必要仅为目录所有权在gtk-doc上添加显式Requires。

有时,这样的目录最好由“人工文件系统”包拥有,例如mozilla-files系统。当其他包在其目录中存储文件时,这些包被设计为显式需要,因此,在这种情况下,这些包应显式要求使用人工文件系统包,而不是乘法拥有这些目录。在决定是否创建人工文件系统包时,打包者应该考虑受影响的目录和包的数量,并使用自己的最佳判断来确定是否有必要这样做。

经验法则:确定此例外是否适用时,包装商和审核人员应提出以下问题:这个公共目录中的文件增强了吗或向另一个软件包添加功能,不需要其他包裹这个包的主要功能是什么?

您所依赖的提供目录的包可能会选择在更高版本中拥有不同的目录,并且您的包将在该更高版本下运行,而不会被修改

涉及Perl模块的示例:

假设perl-A-B型取决于珍珠-A并将文件安装到/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B中。基本perl包保证只要与5.8.8版兼容,它就会拥有/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-threadmulti,但珍珠-A包可以安装到(并因此拥有)/usr/lib/perl5/vendor_perl/5.9.0/i386-linux-thread-multi/A中perl-A-B型软件包需要拥有/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A以及/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B,以便保持适当的所有权。

文件权限

必须正确设置文件的权限。在/usr内部,文件应该归root:root所有,除非出于安全考虑需要更具体的用户或组。它们必须是通用可读的(如果合适,也可以执行)。在/usr/r之外,非配置文件和非状态文件应该由root:root所有,通用可读(如果合适,可以执行),除非情况另有要求。

默认文件模式为0644或0755。目录应为模式0755。大多数表现良好的构建脚本和rpm都会使用这些默认值。如果目录需要组可写,那么它还应该设置setgid位,以便在其中写入的文件属于该组。这些目录应具有模式2775。

只应在设置非默认值时使用%文件列表中的%defattr指令,或在设置了非默认值后重置为默认值。

显式列表

包装工不应该只需在共享目录下对所有内容进行全局访问。

特别是以下内容不应该用于%文件:

  • %{绑定}/*

  • %{数据目录}/*

  • %{包含目录}/*

  • %{手动}/*

  • %{文档目录}/*

这条规则用于检查常见错误,否则很难检测到这些错误。它确实限制了一些自动化的可能性。

此规则防止的最常见错误是在上游添加新命令%{绑定}/*。您应该随时检查此类更改冲突,并保持此类文件的列表明确且可审核。

用户和组

一些软件包需要专用的运行时用户和/或组帐户,或从中受益。处理这些情况的指南见单独的文件.

请注意,为Fedora打包的系统服务不得作为没有人但必须分配自己的系统用户。

Web应用程序

打包在Fedora中的Web应用程序应该将其内容放在/usr/share/%{name}中,而不是放在/var/www/中。这样做是因为:

  • /var应该包含变量数据文件和日志/usr/share更适合于此。

  • 许多用户已经在/var/www中有了内容,我们不希望任何Fedora软件包超出此范围。

  • /文件系统层次结构标准不再指定var/www

冲突

只要有可能,Fedora包应该避免相互冲突。不幸的是,这并不总是可能的。有关Fedora冲突政策的详细信息,请参阅:冲突.

替代方案和环境模块等工具也可以帮助防止包冲突。

选择

“替代”工具提供了一种并行安装软件包的方法,这些软件包通过维护符号链接集来提供相同的功能。有关如何正确使用替代品的完整详细信息,请参阅选择.

环境模块

当存在多个变体,每个变体都满足某些用户的需求,因此必须同时供用户使用时,替代系统是不够的,因为它是全系统的。在这种情况下,使用环境模块可以避免冲突。有关如何正确使用环境模块的完整详细信息,请参阅环境模块.

修补程序指南

Fedora规范文件中的所有补丁应该请在上面对他们的上游状态发表评论。任何时候创建补丁时,最好将其归档到上游漏洞跟踪器中,并在补丁上方的注释中包含链接。例如:

# https://bugzilla.gnome.org/show_bug.cgi?id=12345补丁:gnome-panel-fix frobnicator.Patch

上述情况完全可以接受;但如果您愿意,可以简要介绍一下上述补丁的功能:

#不要使用frobnicator applet崩溃# https://bugzilla.gnome.org/show_bug.cgi?id=12345补丁:gnome-panel-fix frobnicator.Patch

向上游发送补丁并添加此评论将有助于确保Fedora是一个优秀的FLOSS公民(靠近上游项目). 它将通过了解新的上游版本中可能出现的补丁来帮助其他人(甚至您)进行软件包维护。

如果上游没有bug跟踪器

您可以指示已向上游发送修补程序以及任何已知状态:

#通过电子邮件发送至上游20080407补丁:foobar-fix-the-bar.Patch
#上游已将其应用于SVN中继补丁:foobar-fix-the-baz.Patch

Fedora特定(或拒绝的上游)补丁

可能有些补丁确实是Fedora特有的;在这种情况下,请这样说:

#在OpenJDK中实现长期System.loadLibrary修复之前,此修补程序是临时的修补程序:jna-jni-path.Patch

应用修补程序

通常,软件包的补丁应列在补丁号:标记,并使用%patch或%autosetup宏应用。然后必须将这些文件检入Fedora Package版本控制系统(目前是pkgs.fedoraproject.org上的git repo,通常通过fedpkg访问)。以这种方式存储文件允许人们使用标准工具来可视化文件修订之间的更改,并跟踪添加和删除操作,而无需使用间接层(就像将它们放在lookaside中一样)。

不允许直接从RPM_SOURCE_DIR应用修补程序。请参阅打包:RPM_Source_Dir了解完整的基本原理。

当包的上游提供了一个非常大的补丁或针对基本版本的补丁包时,维护人员可能会偏离此规则。在这种情况下,补丁的tarball可能被列为资料来源:行,然后使用常规的/usr/bin/patch命令应用分布式补丁。软件包的附加补丁(例如,由Fedora维护者生成以修复错误)仍必须列在补丁号:行,并在应用tarball中的补丁后由%patch宏应用。维护人员和审查人员在执行此例外时应谨慎,因为作为补丁集发送更新可能表明补丁集不是来自实际的上游,或者应该审查补丁的正确性,而不是简单地将其作为上游代码库。

Epochs的使用

RPM支持一个名为“Epoch:”的字段,这是一个数字字段,如果设置了该字段,则会为RPM添加另一个限定符,以用于进行包比较。具体来说,如果设置了,包的纪元胜过所有其他比较(除了更大的纪元)。如果Epoch未在包中设置,则RPM将其视为与设置为0相同。

例子:

版本:1.2释放:3%{?dist}时代:1

具有这些定义的包将被视为大于具有更高版本或更高版本的包。由于Epoch让人困惑(并且一旦使用就无法从包装中移除),因此它只能在Fedora中使用作为最后的手段解决软件包的升级顺序问题,应尽可能避免。

此外,Epoch使正常的包装指南复杂化。如果软件包使用Epoch,则必须在以下任何地方引用它%{版本}-%{发布}使用。例如,如果依赖的包有一个Epoch,则在添加版本依赖项时必须列出:

需要:foo=%{epoch}:%{版本}-%{发布}

来自第三方存储库的Epochs

如果要导入的包现在或以前存在于可公开访问的存储库中,则打包程序可以选择包含与第三方包的最新版本相同的Epoch标记。

有两种制作符号链接的方法,一种是相对链接,另一种是绝对链接。在Fedora中,这两种方法都不需要。在决定哪种符号链接创建方法合适时,打包者应该使用他们的最佳判断。

相对符号链接是指向相对于符号链接位置的文件或目录的符号链接。例如,此命令将创建一个相对符号链接:

ln-s../..%{_binder}/foo%{buildroot}%{_bindir}/bar

赞成的意见:

  • 相对符号链接将指向chroot内部或外部的同一文件。

欺骗:

  • 创建比绝对符号链接复杂得多

  • 当文件系统的一部分安装到自定义位置时,相对符号链接可能会中断或出现意外行为。

  • 绑定装入或符号链接目录时,相对符号链接可能会断开。

  • 相对符号链接可能会使使用rpm系统宏更加困难。

绝对符号链接是指指向绝对文件或目录路径的符号链接。例如,此命令将创建一个绝对符号链接:

ln-s%{_binder}/foo%{buildroot}%{_bunder}/bar

赞成的意见:

  • 创建符号链接比创建相对符号链接容易得多。

  • 绑定装入或符号链接目录时,绝对符号链接可以正常工作。

  • 绝对符号链接适用于rpm系统宏。

欺骗:

  • 与chroot一起使用时,绝对符号链接可能会中断。

在某些情况下,替换目录的符号链接需要特殊处理。用任何类型的文件替换目录总是需要特殊处理。

请参见打包:目录替换获取有关执行此操作的信息。

测试套件

如果包的源代码提供了测试套件,则应在%检查部分,只要可行。

tmp文件。d日

有处理tmpfiles.d配置和目录(在/run和/run/lock中)的特定准则:Tmp文件。d日.

重命名/替换或删除现有包

包重命名过程重命名现有包时应遵循。

如果需要重命名或替换现有包,新包应使更改在适用范围内对最终用户透明。

如果在没有任何功能更改的情况下重命名软件包,或者是对现有软件包的兼容-彻底替换(其中“足够”意味着它只包括版本升级更改中常见的重大更改),请提供干净的升级路径并与以下内容兼容:

提供:oldpackagename=$provEVR过时:oldpackagename<$obsEVR

$provEVR引用了一个(Epoch-)Version-Release元组,该元组是原始未更改的包在版本或发布被中断时所具有的元组。您通常在这里使用宏,因为提供的EVR应该随着重命名包的版本和发行版的进展而继续升级$obsEVR是一个(Epoch-)版本释放元组,它的安排使得有一个干净的升级路径,但不会无端地污染向上的版本空间。您通常不会使用宏来实现这一点,因为您只是试图超越以旧名称命名的上一个已知版本。

如果一个包取代/替换了一个现有的包,而不是上述定义的充分兼容的替换,则只使用过时:行。

采取%{?分布}计入帐户:在决定$obsEVR应该是什么时,记住,它需要比以前高发布:,包括%{?分布}后缀。示例:如果包以前的发布标签为-4.fcNN公司,$obsEVR中指定的版本应至少为5。
如果更换的包使用rpmautospec公司,或者查看构建的包(例如在koji中)以找到最新构建的实际发布标签,或者使用rpmautospec计算发布只计算发布数量。

如果退役的软件包需要从最终用户机器中删除,因为它们会导致影响升级或其他有害的依赖性问题,则软件包管理员应要求过时:被添加到软呢帽过时包装。只需提交bugzilla票据在这里。请包括需要淘汰哪些软件包的信息,需要淘汰的确切版本,以及不允许继续安装的原因。

如果过时的软件包有一个Epoch集合,则必须将其保存在提供:过时:例如,假设foo被重命名为bar,bar与foo兼容,最后一个foo包版本是foo-1.0-3.fcNN具有时代:2。应将以下内容添加到条形图中(如适用,所有子包装也应如此):

提供:foo=2:%{版本}-%{发布}#重要提示:我们将Obsoletes版本设置为4,以高于上次构建的foo过时:foo<2:1.0-4

明确的提供:需要知道包是否提供了可以在架构依赖或特定于架构的方式中使用的东西。对于非noarch的软件包,提供:应通过应用%{?isa}宏添加到Provides中文本字符串的末尾(例如。提供:foo%{?_isa}=2:%{版本}-%{发布}). 显式提供可以以arch-independent方式使用的内容的包(例如,那些依赖项不需要属于同一arch的包)不需要应用此宏。在某些情况下,一个包将提供多个元素,其中一些元素可能仅由同一拱门的附属元素消耗,而另一些元素可能由任何拱门的附属元素消耗。在这种情况下,特定于体系结构和依赖于体系结构的Provides:都是有保证的。

只应显式提供特定于体系结构的包的示例提供:包括本机代码库或插件及其关联的-devel包。只应显式提供arch-independent的包提供:包括大多数独立程序(除所有noarch软件包外)。尽管这些程序本身可能是特定于arch的,但在大多数情况下,运行它们的客户不应该关心它们的arch。例如,显式提供本机代码库和该库的解释语言接口的包应同时具有特定于体系结构(对于本机代码库客户端)和依赖于体系结构的(对于解释语言接口客户端)provides:。

如果没有软件包的标准命名或与重命名相关的其他长期命名兼容性要求,则应假定Provides已弃用且寿命较短,并在下一个发行版之后的发行版中删除(即,如果在FC-X中引入,则保留发行版FC-X和FC-(X+1)的所有后续软件包修订版,放在FC-(X+2)中),以及计划将其放在其中的发行版,记录在规范文件的注释中。应通知并鼓励受影响包裹的维护人员改用新名称。向前兼容性提供:在较旧的发行版中,可以考虑使用分支,以便包维护人员可以在分支之间保留相同的简单规范文件,但仍可以切换到较新的名称。

对于通常不通过使用包名称作为依赖项来拉入的包,例如仅库包(通过库名称依赖项拉入),通常不需要添加Provides。但是请注意,lib包的-devel子包是使用包名称作为构建依赖项拉入的,因此在其中添加Provides通常是合适的。

正在弃用程序包

存在一个过程,用于指示某个包已被弃用,并可能在将来离开分发版。请参见正在弃用程序包.

网络支持

如果应用程序包含对IPv4和IPv6的本机和稳定支持,并且对IPv6的支持不会对IPv4产生负面影响,则必须在Fedora包中启用这两种支持。

Cron文件

有关如何打包cron文件的详细信息,请参阅:Cron文件.

解决已知CVE问题的安全更新

如果包的更新解决了已知的安全问题(在更新时),并为其分配了常见漏洞和暴露(CVE)编号,则应在RPM更改日志条目中提及CVE编号。

构建时网络访问

Fedora构建系统中的包是在模拟chroot中构建的,无法访问互联网。软件包不得依赖或使用它们自己没有创建的任何网络资源(即用于测试)。在任何情况下,都不能从任何外部源下载源代码,只能从lookaside缓存和/或Fedora-git存储库下载。

引导

如果包引入了构建时循环依赖项,则应使用此宏引导包:

#当我们进行引导时,我们会删除一些依赖项和/或构建时测试。%bcond_with引导[...]%如果%{没有引导}#%%检查的依赖项构建要求:foo%结尾[...]%如果%{没有引导}%检查进行检查%结尾
自Fedora 30以来,作为一个好的副作用,启用引导模式时,这个~引导后缀被附加到dist标记。这避免了通气释放的需要在引导和最终构建之间。您可以通过提交临时启用引导,发生了哪些变化%bcond_with引导%bcond_without引导然后恢复提交以进行最终构建。
自费多拉31日以来,您可以禁用自动添加后缀通过指定%全局__bootstrap%{nil}在规范文件中。

如果您的包显式地提供:引导时缺少的一些功能提供:应如下所示:

%如果%{没有引导}提供:bar(some_functionality)%结尾

请注意,如中所述,在引导程序中使用预先构建的二进制文件仍然需要包装委员会的例外一般例外政策.

系统加密策略

使用SSL或TLS加密协议的应用程序必须遵循加密策略.

Shebang线

打包脚本文件时,在脚本的第一行(shebang行)中指定要使用的解释器#!,适用以下规则:

  • 环境价值,/箱子/环境/usr/bin/env不得使用。用于运行打包应用程序的解释器不能依赖于用户的个人信息$路径.

  • 未作为可执行文件安装的文件不应具有shebang行。

  • 特定于语言的指导原则可能有其他限制。

自动修改可执行脚本的Shebang行以将调用转换为环境价值直接使用中适当的可执行文件/usr/bin(用户/二进制)还应用了各种检查来验证shebang行是否有效,并且构建过程可能因此而失败。最后,还可以进行其他特定于语言的修改。因此,通常不需要手动修改可执行脚本来修复环境价值只要启用此功能即可使用。

如果自动检查和修改破坏了包,则有两个主要选项:

  • 打包程序可以选择手动修复shebang行(使用补丁、通过sed编写脚本或其他类似方法)。

  • 打包程序可以从脚本中删除可执行权限,以便不进行检查和修改。

如果(并且仅当)脚本需要保持可执行状态并且无法修改以通过检查,则维护人员可以选择禁用检查和修改。也可以通过设置%__brp_mangle_shebangs_exclude_from%__brp_mangle_shebangs_exclude分别使用与中描述的设置相同的语法打包:AutoProvidesAndRequiresFiltering。也可以通过添加%取消定义__brp_mangle_shebangs靠近规范文件的开头。

BRP(BuildRoot策略)脚本

BRP脚本在%安装(通过%__os安装后宏)并对安装在构建根目录中的文件执行一些自动健全性检查或调整。

所有包都应该始终受制于所有BRP脚本,但有时包需要选择退出某些脚本。只需定义相应的变量即可禁用任何BRP脚本%{无}。例如,要禁用brp-python字节编译脚本:

#关闭Python字节码编译,因为这是一个Jython#包,我们将生成JVM字节码%全局__brp_python_bytecompile%{nil}

任何以这种方式禁用BRP脚本的程序包都必须在附带的注释中注明原因。要查看默认运行的BRP脚本列表,请调用:

sed-r-n'/^%__os_install_post/,/%。?nil/p'/usr/lib/rpm/redhat/macros

要查看所有BRP脚本的列表,请调用:

rpmbuild--eval“%dump”|&grep“:__brp_”

消除构建不可复制性的常见来源

默认情况下调用的BRP脚本之一是%__os安装成本构建再现性。其目的是通过删除不需要的嵌入式元数据来规范已安装的文件,这些元数据依赖于生成环境,并可能导致来自同一源的不同生成不可复制。

请参见/usr/lib/rpm/macros.d/macros.build-replicability有关如何配置它的详细信息。

EPEL包装

在大多数情况下,这些指南和以下特定于应用程序的指南涵盖了Fedora和EPEL的包装。然而,必然存在一些差异。包装EPEL时,请同时咨询EPEL包装指南了解更多信息。