Fedora包装指南

包装指南是常见问题的集合以及应该对其施加的严重性。虽然这些指导方针不应被忽视,它们也不应该被盲目遵循。如果您认为您的套餐应免除部分指南,请把这个问题提交给Fedora包装委员会.

这些文件涵盖了可接受的Fedora包装的详细信息虽然它们可能包括各种示例作为教程,它们不会特别有用。他们也没有涵盖细节以及与获取访问权限相关的政策以打包者的身份发送到Fedora仓库,或实际创建和发布包的机制作为分发的一部分。对于涉及这些问题的文件,请参阅以下内容:

文件包审阅者有责任指出文件包的具体问题以及包装商处理这些问题的责任。审核人员和包装人员共同确定问题的严重性(是否阻止包裹或者可以在包位于存储库中后进行操作。)请记住您提交的任何文件包还必须符合审查指南.

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

关键词MUST、MUST NOT、SHOULD、SHOUDL NOT和MAY在这些指南中,应按照副本请求2119.

报告与这些指南有关的问题,包括打字错误,在这里.

适用性

一般来说,这些指南适用于当前发布的,Fedora的非报废版本,以及Fedora(生皮)的开发版本。如果这些指南的特定部分是相关的仅适用于这些版本的子集,这将被特别注意。然而,请注意生皮会迅速变化,有时会出现变化这里还没有反映出来。

该指南也在一定程度上涵盖了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文件必须命名示例.spec.

规范易读性

所有规范文件必须清晰易读,并以这种方式保存包装商社区能够理解并与他们合作。

为了便于阅读,只有Fedora和EPEL的宏和条件允许在Fedora包裹中使用。对其他发行版使用宏和条件,包括Fedora衍生物,不允许出现在Fedora主存储库中包的规范文件中除非这些宏和条件也存在于Fedora中。

等级库文件编码

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

非ASCII文件名

类似地,包含非ASCII字符的文件名必须编码为UTF-8。由于无法记录文件名的编码,对所有文件名使用相同的编码是最好的方法以确保用户能够正确读取文件名。如果上游发货的文件名不是UTF-8编码的您可以使用convmv之类的实用程序(来自convmv包)转换%install节中的文件名。

规范维护和规范性

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

源文件验证

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

虽然源文件中的校验和可以证明从后备缓存中检索的文件是打包者上传的那个,对于该文件是否是上游项目发布的文件,它没有给出答案。上游开发商的签名证明消息来源与他们发布的内容相同。作为构建的一部分验证签名可确保包装商不会忘记验证。

获取正确的密钥

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

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

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

验证签名

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

任何分离的签名文件(例如,foo.tar.gz.asc或foo.tart.gz.sig)必须与源代码一起上传到包lookaside缓存,而密钥环必须直接提交给包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文件的注释中。带有指纹的钥匙的最小钥匙圈7D33D762FD6C35130481347FDB4B54CBA4826A18可以使用以下命令创建:

gpg2--导出--导出选项导出最小值7D33D762FD6C35130481347FDB4B54CBA4826A18>gpgkey-7D33D72FD6C3530481347FDB4 B54CBA3826A18.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,描述包没有编译/构建/使用该架构。然后将错误号放在注释中,在相应的旁边不包括拱门行。在审查过程中,新包将不会有bugzilla条目,所以他们应该把这个描述放在评论中直到包裹获得批准,然后归档bugzilla条目,并用错误号替换冗长的解释。该错误应标记为阻止一个(或多个)用于简化跟踪此类问题的以下错误:

具有未导出依赖项的Noarch

有时您正在处理noarch包只能在不同的位置运行,拱形包构建于。这对于用脚本语言编写的包来说很常见例如,这取决于语言的解释器包。如果包裹所依赖的拱形包裹不可用所有架构上的Fedora(或EPEL)目标您遇到了可能需要排除包裹的情况从某些体系结构的包存储库或者阻止它在构建系统中的特定架构上构建。

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

您可以限制用于构建noarch包的两种架构,以及构建的noarch包将添加到的存储库,通过使用排除建筑:排他性架构:标签:

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

有时,您正在打包的语言运行库将提供宏例如,拱门上有,%{nodejs_arches}.如果它确实存在,那么您可以使用以下内容ExclusiveArch:%{nodejs_arches}noarch在规范文件中。看看语言指南查看是否存在这样的宏。

无特定于电弧的源或补丁

包装不得有资料来源:补丁:标签这取决于建筑。例如,禁止这样做:

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

条件化资料来源:补丁:按体系结构列出的标签导致源包的内容不同取决于用于构建它的体系结构。

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

%准备%设置-q%ifarch s390x软件%补丁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}/库而不是%{链接目录}.包含体系结构特定文件的包通常安装在%{_libexecdir}总是被认为不符合multilib的条件。但是,您应该确保它们所在的(子)包没有其他被认为符合multilib条件的内容。如果您希望在包中执行此操作的文件不是这样或者你只是不确定,请向FESCo申请明确的多实验室豁免。

/运行

系统服务应将小型易失性运行时数据存储在/运行.这是一个支持tmpfs的目录,在很早的引导中安装,在启动任何服务之前(和之前/无功功率,无功功率可用)。/var/运行是到的遗留符号链接/运行.

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

这个FHS表示:

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

FHS明确地控制目录结构在下面/开关磁阻电动机发送给系统管理员,而不是分发。因此,任何Fedora包都不能在/开关磁阻电动机,进行预配置以使用下的特定文件或目录/开关磁阻电动机,删除那里的文件,或者以任何方式修改那里的文件。

此外,没有Fedora软件包可以包含文件或目录或修改以下目录下的文件:

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

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

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

有限使用/选择,/等/选项,以及/变量/选择

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

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

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

合并的文件系统布局

Fedora已经合并了过去分开。

路径 与合并 RPM宏

/垃圾桶

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

{绑定}

/斯宾

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

%{间接寻址}

/usr/sbin

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

%{绑定}

/库64/图书馆

/usr/lib64/用户/库

%{链接目录}

/图书馆

/用户/库

%{_prefix}/库

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

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

%文件/垃圾桶/桶

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

例如:

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

使用rpmlint公司

在二进制和源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问题的社区维护页面在这里.

标记和节

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

  • 这个BuildRoot:标签,组:标签,以及%清洁部分不应使用。

  • 不应删除构建图中的内容在的第一行%安装.

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

  • 这个资料来源:标记文档的查找位置包的上游源。在大多数情况下,这应该是上游tarball的完整URL。对于特殊情况,请参阅源URL准则.

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

包依赖项

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

RPM可以自动确定大多数编译库的依赖项以及一些脚本语言,如Perl。自动确定的依赖关系不得重复通过手动依赖性。

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

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

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

依赖项类型

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

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

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

通过附加宏,使依赖关系成为特定于拱门的%{?isa}到包名称。例如:

需要:foo

变为:

需要:foo%{?_isa}

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

$gtk配置--cflags-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更改的向后不兼容。这可能导致用户使用旧版本已安装库的,带有新ABI的新版本库是在Fedora构建的并使用该ABI构建了一个应用程序。如果用户只是尝试安装或更新某个应用程序不同时更新库,应用程序安装良好(因为满足了SONAME依赖性)但运行时将失败,因为库已安装系统上缺少所需的功能。

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

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

当需要显式库Requires时,显式库依赖项通常应该是特定于体系结构的(除非涉及的包裹是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和%{_isa}

您不得使用拱形BuildRequires。拱门在建成的SRPM中结束但SRPM需要独立于体系结构。例如,如果您这样做:

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

那么在Fedora中构建的SRPM将具有以下需求之一根据创建SRPM的构建器:

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

这将阻止yum-builddep或使用SRPM要求的类似工具无法正确操作。

BuildRequires基于pkg配置

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

条件构建时间依赖项

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

总结和说明

摘要应该是对文件包的简短描述。描述对此进行了扩展。说明中不包括安装说明;这不是一本手册。如果软件包需要一些手动配置或者对用户有其他重要指示,请用户参阅包中的文档。添加自述。费多拉或类似的,如果你觉得这是必要的。此外,请确保描述中没有行长度超过80个字符。

请把个人偏好放在一边并在摘要和描述中使用美式英语拼写。包可以包含其他翻译的摘要/描述对于支持的非英语语言,如果可用。

摘要或说明中的商标

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

  • 从不使用(TM)(右)(或Unicode等价物™/®)。正确使用这些非常复杂,因此,实际上我们完全不使用它们更安全。

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

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

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

  • 坏消息:Microsoft Office的Linux版本

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

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

文档

源分发中包含的任何相关文档应包含在适当的文档目录中的包中。无关文档包括构建说明、,无所不在的安装包含通用构建指令的文件,或示例,和非Linux系统的文档,例如。自述。世界末日.还要注意在哪个子包中包含文档。例如,API文档属于-开发子包,不是主要的。或者如果有很多文档,考虑把它放在一个子包中。在这种情况下,建议使用*-文件作为子包名称。

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

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

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

尽管许可文件是文档,他们受到特殊对待(包括使用不同的标签)。请参阅许可指南如何处理它们。

单独的文档包

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

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

变更日志

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

变更日志应该从git提交日志自动生成使用%自动更改日志宏:

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

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

提交消息中的文本将成为更改日志的一部分应提供与用户相关的更改的简要摘要。提交消息可能包含相关的其他信息分装商。

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

添加自述文件(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软件包.spec索引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*

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

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

编译器

Fedora包应默认使用gcc作为编译器(适用于gcc支持的所有语言)如果上游不支持gcc建筑,则会发出叮当声。然而,如果有一个好的技术原因,打包程序可以选择不使用默认编译器。不使用默认编译器的有效技术原因的示例,包括但不限于:

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

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

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

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

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

编译器宏

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

%全球工具链叮当作响

这样可以确保使用Fedora特定于clang的编译器标志编译时。

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

%bcond_with toolchain_clang(与工具链链接)%用工具链连接gcc

打包程序也可以使用%build_cc、%buile_cxx或%build_cpp宏在spec文件中代替编译器名称的硬编码。通过设置%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库路径或缓存中。这意味着它们不直接位于/usr/lib或/usr/lib64中,或在/etc/ld.so.conf中作为库路径列出的目录中(或/etc/ld.so.conf.d/config文件)。通常,可以找到这些未版本化的共享对象在/usr/lib或/usr/lib64下的专用子目录中(例如,/usr/lib/purple-2/是插件目录用于libpurple应用程序)。在这些情况下,未版本化的共享对象不需要放在-devel包中。

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

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

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

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

Pkgconfig文件(食品.pc)

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

需要基本包

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

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

Devel包是包的一个示例这必须要求它们的基本包使用完全版本化的依赖项。-仅包含共享库的libs子包通常不需要显式依赖其基本包因为它们通常不需要将基本包作为函数库。

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

共享库

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

列出共享库文件

直接安装到中的共享库%{_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”)因为upstream的常见做法是这里只使用一个数字。使用多个数字有助于我们避免未来潜在的冲突。不要忘记将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. 仅限静态库。当包只提供静态库时您可以将所有静态库文件放在*-发展分装。进行此操作时,您还必须有一个虚拟Provide对于*-静态包裹:

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

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

  • 如果(并且仅当)包具有共享库这需要静态库具有功能,静态库可以包含在*-开发分装。开发子包必须具有虚拟的*-静态包裹,和依赖于它的包必须需要生成这个*-静态包裹。

打包仅标头库

某些库,尤其是一些C++模板库,是仅包含标头的库。由于代码是在编译时生成的,它们的行为就像静态库一样,需要被当作静态库来对待。

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

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

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

仅在子包中使用noarch

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

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

静态链接可执行文件

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

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

系统库的捆绑和复制

Fedora包裹应尽一切努力避免多个独立的上游项目打包在一起。

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

上游没有针对系统库构建机制的所有包可能会选择捆绑图书馆,但如果他们这样做,他们必须包括一个他们捆绑的指示。这提供了一种使用捆绑代码定位库的机制,可以,例如,协助定位包裹可能具有特定的安全漏洞。

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

  • 如果集束包装也单独存在于配送中,使用该包的名称。否则请咨询命名原则确定库的适当名称好像它是作为一个单独的包进入发行版的。

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

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

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

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

通用格式的字体,如类型1、OpenType TT(TTF)或OpenType CFF(OTF)受特定包装指南的约束(包装/字体政策),并应始终打包在系统范围的字体库中而不是私有应用程序目录。有关详细信息,请参阅:包装/字体政策.

当心rpath(rpath)

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

有一种工具叫做检查rpath其中包括在中rpmdevtools工具包裹。将其添加到%__arch_安装_主机在您的~/.rpmmacro公司配置文件:

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

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

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

检查rpath标记的任何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的替代方案或者只需将库移动到%{链接目录}而不是。这样,动态链接器可以找到库而不必将所有程序与rpath链接。

替代方案rpath(rpath)

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

/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如果你最终使用这种方法。

配置文件

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

根据经验,使用%配置(无位置)而不是普通的%配置除非你最好的、有根据的猜测是这样做会破坏一切。换句话说,在覆盖本地更改之前要仔细考虑在配置文件中有n个包升级。以下情况的示例使用无位置包的配置文件更改时这样新的软件包修订版就不起作用了使用上一版本包中的配置文件。只要是普通的%配置使用,在spec文件中添加简短注释,解释原因。

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

包管理器的配置

软件包不得安装违反以下要求的存储库配置文件这个第三方存储库策略,除非这些文件安装在%{文档目录}.

产品配置

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

起始程序

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

系统单元

包装系统单位的详细指南和系统管理服务在这里.

桌面文件

如果包中包含GUI应用程序,那么它还需要包含一个正确安装的.desktop文件。在本指南中,GUI应用程序定义为绘制窗口的任何应用程序从窗户里跑出来。已安装的.desktop文件必须遵循台式机-规格,特别注意验证名称,通用名称,类别,启动通知条目。

桌面文件中的图标标记

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

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

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

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

图标=滑稽

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

.桌面文件创建

如果包中还没有包含并安装自己的.desktop文件,你需要自己做。您可以通过包含创建为源的.desktop文件来完成此操作:(例如Source3:%{name}.desktop)或在spec文件中生成。以下是示例.desktop文件(comical.desktop)的内容:

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

桌面文件安装用法

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

桌面文件安装\--目录=%{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类型。因此,不建议您指定VCS具有%自动设置.有关正确使用的更多详细信息%自动设置,请参阅RPM文档.

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

定义rpm构建根和优化标记有两种风格在等级库文件中:

宏样式

可变样式

生成根目录

%{内置程序}

$RPM_BUILD_ROOT($RPM_FUILD_ROOT)

选择。旗帜

%{操作标志}

$RPM_OPT_FLAGS(美元)

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

将这两种风格混合在一起,虽然有效,从QA和可用性的角度来看是不好的,并且不应在Fedora软件包中完成。

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

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

  • %制造装置在“Make install”期间覆盖一组Make变量并在%{buildroot}路径前面加上前缀,即它的性能make prefix=“%{buildroot}%{_prefix}”libdir=“%}buildrot}%{_libdir}…”。

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

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

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

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

源RPM构建时宏

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

模拟--初始化模拟--复制/mock—shell bash转速-ivhcd/builddir/build/SPECSrpmbuild-bs--节点[SRPM]rpm-qpiv/builddir/build/SRPMS/[SRPM]

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

不当使用%_sourcedir公司

使用列为源#文件的文件的包,必须通过他们的来源#宏名称,并且不得使用$RPM_SOURCE_DIR(源代码)%{源目录}以引用这些文件。请参见打包:RPM_Source_Dir了解详细信息。

软件集合宏

软件集合保持包装与主流包装分开类似于如何MingW包被管理。

过去,允许存在SCL宏如果不使用主流软件包的话。由于我们现在正在建立SCL,我们现在正在实施严格的分离。包装必须更新以限制SCL宏仅适用于SCL中特别批准的包。

其他RPM宏的打包

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

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

在规范文件内部编写脚本

有时需要写一个简短的脚本(可能是一句话)%准备,%建造,或%安装等级库文件的节以获取有关构建环境的一些信息。为了简化依赖关系图,为此,规范文件应仅使用以下语言:

  • 蟒蛇

  • 波尔

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

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

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

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

%全球优先于%定义

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

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

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

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

处理区域设置文件

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

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

构建要求:gettext

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

构建要求:qt-level

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

%find_lang%{name}

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

%文件-f%{name}.lang%{绑定}/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在航站楼。

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

下面是正确使用%查找语言,在里面foo.spec公司“foo”应用程序本地化使用名为“bar”而非“foo”的gettext和手册页:

名称: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?

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

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

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

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

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

日志文件

生成日志文件的包应写出其日志文件在包特定(和包所有)目录中在%{localstatedir}/log下。除非正在打包的软件轮换自己的日志,它还必须提供一个logrotate配置文件来旋转其日志文件。

轮替配置文件

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

因为这些是配置文件,它们必须在%files列表中标记为%config(noreplace)。

示例Minimal轮替配置文件

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

时间标记

当在规范文件中添加文件复制命令时,考虑使用保留文件时间戳的命令,例如。,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或rpmbuild进程设置的%{_tmppath})根据以下矩阵

/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(usr/share/gnucash)目录

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

例如:

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

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

该目录由一个程序包拥有,而您的程序包不需要该程序包才能运行

一些包创建并拥有目录为了允许其他包存储适当的文件,但其他的包不需要原始包为了正常工作而在场。

例如:

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

解决方案:进化包应该拥有/usr/share/gtk-doc目录。无需在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包保证它将拥有/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-线程多只要它与5.8.8版兼容,但未来的升级珍珠-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之外,非配置文件和非状态文件应该归root:root所有,通用可读(适当时可执行)除非情况另有要求。

默认文件模式为0644或0755。目录应为模式0755。大多数行为良好的构建脚本和rpm将使用这些默认值。如果目录需要组可写,它还应该设置setgid位所以写在那里的文件归该组所有。这些目录应具有模式2775。

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

显式列表

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

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

  • %{绑定}/*

  • %{数据目录}/*

  • %{_includedir}/*

  • %{手动}/*

  • %{文档目录}/*

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

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

用户和组

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

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

Web应用程序

Fedora中打包的Web应用程序应将其内容放入/usr/share/%{name}和NOT进入/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回购通常通过fedpkg访问)。以这种方式存储文件允许人们使用标准工具可视化文件修订之间的更改和跟踪添加和删除没有间接层(就像把它们放到lookaside中一样)。

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

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

Epochs的使用

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

例子:

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

具有这些定义的包将被视为大于具有更高版本或更高版本的软件包。因为纪元让人困惑(一旦使用,就不能从包装中取出),只能在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一起使用时,绝对符号链接可能会中断。

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

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

测试套件

如果包的源代码提供了测试套件,它应该在%检查第节,只要切实可行。

binfmt.d、sysctl.d和tmpfiles。d日

如果您安装了sysctl配置片段foobar.conf到%{_sysctldir}(/usr/lib/sysctl.d/)您必须在%post部分中调用%sysctl_apply:

%sysctl_apply foobar.conf

如果安装binfmt配置片段waldo.conf到%{_binfmtdir}(/usr/lib/binfmt.d/)必须在%post节中调用%binfmt_apply:

%binfmt_apply waldo.conf文件

这些具有进行适当更改的效果包装安装后立即而不需要重新启动或手动激活。

有处理tmpfiles.d的具体指南配置和目录(在/run和/run/lock中):Tmp文件。d日.

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

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

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

如果在没有任何功能更改的情况下重命名包,或是现有软件包的兼容全面替代(其中“足够”意味着它只包括幅度的变化常见于版本升级更改中),提供干净的升级路径并与以下各项兼容:

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

$provEVR引用(Epoch-)版本释放元组原来没有改变的包裹如果它的版本或发布被取消。您通常在这里使用宏,因为提供的EVR应该继续上升随着重命名包在版本和发行版方面的进步。$obsEVR是(Epoch-)版本释放元组安排为有一个干净的升级路径但不会无端地向上污染版本空间。通常不使用宏进行此操作因为您只是试图超越上一个已知版本以旧名字命名。

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

Take(获取)%{?分布}计入帐户:在决定$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}宏添加到“提供”中文本字符串的末尾(例如。提供:foo%{?_isa}=2:%{版本}-%{发布}).明确提供可使用内容的包以拱门相关的方式(例如,那些家属不需要属于同一拱门的人)无需应用此宏。在某些情况下,一个包将提供多个元素,其中一些只能由同一拱门的家属使用还有一些可能被任何拱门的家属所消耗。在这种情况下,特定于体系结构和依赖于体系结构的Provides:都是有保证的。

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

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

对于通常不拉入的包裹通过使用包名称作为依赖项例如仅库程序包(通过图书馆的soname dependencies拉入),通常不需要添加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)%结尾

请注意,预构建二进制文件的使用in-bootstrap仍然需要包装委员会的例外如中所述一般例外政策.

系统加密策略

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

Shebang线

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

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

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

  • 特定语言的指导方针可能有额外的限制。

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

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

  • 分装商可以选择手动修复shebang管线(使用补丁、通过sed编写脚本或其他类似方法)。

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

如果(且仅当)脚本需要保持可执行状态并且不能修改以通过检查,则维护人员可以选择禁用检查和修改。也可以禁用特定路径的功能或通过设置特定的shebang线%__brp_mangle_shebangs_exclude_from%__brp_mangle_shebangs_exclude,分别使用与中描述的设置相同的语法包装:自动提供和要求筛选.也可以完全禁用该功能通过添加%取消定义__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包装指南了解更多信息。