Fedora包装指南
适用性
一般例外政策
允许的程序包
命名
版本和发布
许可
Fedora商标
库和应用程序
程序包独立性
等级库文件
源文件验证
获取正确的密钥
验证签名
来源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}”
例外情况
gpg2--导出--导出选项导出最小7D33D762FD6C35130481347FDB4B54CBA4826A18>gpgkey-7D33D762FD6C35130481347FDB4B54CBA4826A18.gpg
来源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=-
体系结构支持
架构(Architecture)构建失败
文件系统布局
Libexecdir公司
多实验室免税场所
下没有文件或目录 /开关磁阻电动机
, /usr/本地
,或 /主页/$USER
“…任何程序都不应依赖现有/srv的特定子目录结构 或必须存储在/srv中的数据。 然而,FHS上应始终存在/srv 兼容系统,并应用作此类数据的默认位置。 分发版必须注意不要删除这些文件中本地放置的文件 没有管理员权限的目录。 "
-
/usr/本地 因为不允许使用这些目录 按FHS中的分配 -
/主页/$USER 因为用户可以任意修改主目录中的文件 修改这些文件的rpm包可能会破坏用户数据。 此外,站点可能正在安装nfs /家 在许多不同类型的系统上 甚至网络自动安装它们。 修改主目录中这样配置的文件 在这两种情况下都会产生负面影响。
有限使用 /选择
, /等/选项
、和 /var/opt(变量/选项)
合并的文件系统布局
%文件 /垃圾桶/桶
提供:/sbin/ifconfig [...] %文件 %{绑定}/ifconfig
使用 rpm链接
标记和节
-
这个 版权: , 包装商: , 小贩: 和 先决条件: 标签 不得使用。 -
这个 生成根目录: 标签, 组: 标签,以及 %清洁 部分 不应使用。 -
不应删除构建图中的内容 在的第一行 %安装 . -
这个 总结: 标记值不应以句点结束。 -
这个 资料来源: 标记文档的查找位置 包的上游源。 在大多数情况下,这应该是上游tarball的完整URL。 对于特殊情况,请参阅 SourceURL指南 . -
中的URL 网址: , 资料来源: 和 补丁: 标签 应尽可能要求对服务器进行身份验证。 这通常意味着写 https(https): 而不是 网址: 或 英尺/小时: .
包依赖项
依赖项类型
特定于体系结构的依赖关系
需要:foo
需要:foo%{?_isa}
$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
丰富/布尔依赖项
文件和目录依赖项
-
/usr/bin(用户/二进制) -
/等
明确要求
#对libfubar.so.1的自动依赖性不足, #因为我们严格需要至少修复两个segfault的版本。 要求:libfubar%{?_isa}>=0:1.2.3-7
筛选自动生成的要求
构建时间依赖项(BuildRequires)
构建要求和 %{伊萨}
#*不*做什么的示例 构建要求:foo%{?_isa}>=3.3
foo(x86-32)>=3.3 #或 foo(x86-64)>=3.3
BuildRequires基于 pkg配置
条件构建时间依赖项
总结和说明
注意事项
-
不要以句点结束摘要。 -
摘要应为80个字符/列或更少。 如果您使用的不是ASCII码 看看utf长度函数或类似的函数 计算列数。 -
请确保说明中没有超过80个字符/列的行。 如果您使用的不是ASCII码 看看utf长度函数或类似的函数 计算列数。 -
说明中不包括安装说明; 这不是一本手册。 如果软件包需要一些手动配置 或者对用户有其他重要指示, 请用户参阅包中的文档。 添加 自述。 费多拉 或者类似的,如果你觉得这是必要的。 -
为了保持一致性, 我们使用美国英语的拼写和语法规则 在总结和描述中。 包可以包含其他翻译的摘要/描述 对于支持的非英语语言, 如果可用。
摘要或说明中的商标
-
从不使用 (TM) 或 (右) (或Unicode等价物™/®)。 正确使用这些非常复杂, 因此,实际上我们完全不使用它们更安全。 -
以不含糊的方式使用商标。 避免使用“类似于”或“喜欢”这样的短语。 一些示例: -
坏消息: 它类似于Adobe Photoshop。 -
良好: 它支持Adobe Photoshop PSD文件 -
坏消息: Microsoft Office的Linux版本 -
良好: 支持Microsoft Office DOC文件的文字处理器
文档
变更日志
%变更日志 %自动更改日志
添加README文件(rhbz#1000042)
例子
$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生成更改日志 *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
手册
%文件 %{手动}/man1/foo.1*
编译器
-
默认编译器无法正确生成包。 -
打包程序需要禁用编译器功能(例如LTO) 以便默认编译器正确编译其包。 -
默认编译器构建包的时间要长得多。 -
默认编译器缺少对包有益的功能。
编译器宏
%全球工具链叮当作响
%bcond_with toolchain_clang(与工具链链接) %bcond_带工具链_gcc
编译器标志
PIE公司
%未定义_硬化_构建
-
你的包裹很长时间了。 这意味着它可能会启动并继续运行 在机器重新启动之前,不要按需启动,而是在空闲时退出。 -
您的包中包含suid二进制文件,或者包含功能的二进制文件。 -
您的程序包以root身份运行。
Debuginfo包
Devel软件包
-
头文件(foo.h),通常位于/usr/include中 -
静态库文件 当包没有提供任何匹配的共享库文件时。 请参阅 打包静态库 有关此场景的更多信息。 -
未版本化的共享系统库文件, 当还存在匹配版本的共享系统库文件时。 例如,如果您的软件包包含:
/usr/lib/libfoo.so.3.0.0 /usr/lib/libfoo.so.3 /usr/lib/libfoo.so
未版本化的共享对象
例外情况
-
编译器通常在主包中包含开发文件 因为编译器本身只用于软件开发, 因此,拆分包模型没有任何意义。
需要基本包
需要:%{name}%{?_isa}=% {版本}- %{发布}
共享库
列出共享库文件
下游 .所以
名称版本控制
libfoobar.so.0.n
SONAME处理
$gcc$CFLAGS-Wl,-soname,libfoo.so.0.n-o libfoo.so.0.n
$objdump-p/path/to/libfoo.so.0.n|grep“SONAME”
打包静态库
打包静态库
-
一般来说,包装商不应该运送静态库。 -
我们希望能够跟踪哪些包正在使用静态库 (因此我们可以找到需要重建的包 例如,如果静态库中的安全漏洞得到修复)。 静态库打包有两种情况: -
静态库和共享库。 在这种情况下,静态库必须放置在 *-静态 分装。 将静态库与其他开发文件分离 在里面 *-开发 允许我们通过检查哪些包来跟踪此使用情况 需要生成 这个 *-静态 包裹。 其目的是只要可能, 包将不再使用这些静态库, 到共享库。 如果 *-静态 子包需要标头或其他文件 从 *-开发 为了有用,它必须要求 *-开发 分装。 -
仅限静态库。 当包只提供静态库时 您可以将所有静态库文件放在 *-开发 分装。 这样做时,您还必须有一个虚拟供应商 对于 *-静态 包裹: %软件包开发 提供:foo-static=% {版本}- %{发布}
-
-
如果(且仅当)包具有共享库 这需要静态库具有功能, 静态库可以包含在 *-开发 分装。 开发子包必须具有虚拟的 *-静态 包裹, 和依赖于它的包必须 需要生成 这个 *-静态 包裹。
系统库的捆绑和复制
当心 rpath(rpath)
%__架构_安装_支柱\ /usr/lib/rpm/checkrpath\ /usr/lib/rpm/check-buildroot
错误0001:文件“/usr/bin/xapia-tcpsrv”在[/usr/lib64]中包含标准rpath“/usr/lib64”
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 RPATH 0x0000000f(RPATH)库RPATH:[/usr/lib/myapp]
|
替代方案 rpath(rpath)
/usr/lib/foo
正在删除 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
配置文件
包管理器的配置
产品配置
系统单元
桌面文件
桌面文件中的图标标记
-
特定图标文件的完整路径:
-
不带文件扩展名的短名称:
.桌面
文件创建
[桌面输入] 名称=滑稽 GenericName=漫画存档阅读器 注释=打开.cbr和.cbz文件 执行=滑稽 图标=滑稽 终端=错误 类型=应用 类别=图形;
桌面文件安装
用法
桌面文件安装\ --目录=%{buildroot}%{datadir}/applications\ %{来源3}
桌面文件安装\ --add-category=“音频视频”\ --删除原始文件\ --目录=%{buildroot}%{datadir}/applications\ %{buildroot}/%{datadir}/applications/foo.desktop
桌面文件验证%{buildroot}/%{datadir}/applications/foo.desktop
AppData文件
宏
-
包必须一致。 对于同一规范中的任何给定路径, 使用硬编码路径或宏,而不是两者的组合。 -
%由于多库,{_libdir}必须始终用于二进制库, 您可能无法替换硬编码路径。
rpm-q--spec文件foo.spec--qf“$(grep-i^源foo.spe)\n”
%自动设置
使用 %{内置程序}
和 %{操作标志}
与 $RPM_BUILD_ROOT($RPM_FUILD_ROOT)
和 $RPM_OPT_FLAGS(美元)
为什么 %制造装置
不应使用宏
-
%制造装置 在“Make install”期间覆盖一组Make变量 并在%{buildroot}路径前面加上前缀, 即它的性能 make prefix=“%{buildroot}%{_prefix}”libdir=“%{buildroot}%{_libdir}…”。 -
它容易出错,可能会产生意想不到的影响 当运行不太完美的Makefiles时, 例如,buildroot路径可能包含在已安装的文件中 其中变量在安装时被替换。 -
在执行“make-install”时,可能会触发不必要的错误重建, 因为Make变量与%build部分的值不同。 -
如果一个包包含libtool档案, 它可能会导致安装损坏的*.la文件。
源RPM构建时宏
模拟--初始化 模拟--复制/ mock—shell bash 转速-ivh cd/builddir/build/SPECS(光盘/构建目录/构建/SPECS) rpmbuild-bs--节点[SRPM] rpm-qpiv/builddir/build/build/SRPMS/[SRPM]
不当使用 %_sourcedir公司
在规范文件内部编写脚本
-
蟒蛇 -
波尔 -
shell编程中使用的标准程序,例如gawk或sed -
Lua(由rpm中的本地Lua解释器支持)
%全球
优先于 %定义
处理区域设置文件
构建要求:gettext
构建要求:qt-level
%find_lang%{name}
%文件-f%{name}.lang %{_bindir}/foobar ...
%find_lang%{name}--带名词
%find_lang%{name}--带-kde
%find_lang%{name}--带-qt
%find_lang%{name}--与man
名称: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?
-
使用的程序包 %{数据目录}/* 在一行中获取所有语言环境文件 还获取locale目录的所有权,这是不允许的。 -
大多数具有区域设置的包都有许多区域设置。 使用 %查找语言 在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 ...
-
随着新的语言环境文件出现在以后的包修订中, %查找语言 将在运行时自动包含它们, 防止您在必要时更新规范。
日志文件
时间标记
平行制造
%建造(_B)
%_smp_mflags-j3
脚本片断
使用单独的用户帐户生成包
可重新定位的软件包
文件和目录所有权
-
共享相同文件所有权的包 由单个SRPM构建。
-
共享相同文件所有权的包 不在依赖链中 (例如,如果包A需要包B, 它们不应包含相同的文件, A或B必须拥有公共文件,但不能同时拥有两者。)
-
拥有的任何目录 文件系统 , 男人 , 或其他显式创建的 -文件系统 包装 -
其他包拥有的任何目录 在包的自然依赖链中
该目录还归实现包所需功能的包所有
pam拥有/etc/pam.d目录 gdm将文件放在/etc/pam.d中 gdm依赖pam正常工作,并且将Require:pam(隐式或显式)与目录所有权分离。
该目录由一个程序包所有,该程序包不需要该程序包才能运行
gtk-doc拥有/usr/share/gtk-doc/目录 evolution将文件放入/usr/share/gtk-doc/ 进化不需要gtk-doc才能正常运行。 evolution的依赖链中没有任何东西拥有/usr/share/gtk-doc/
|
您所依赖的提供目录的包可能会选择在更高版本中拥有不同的目录,并且您的包将在该更高版本下运行,而不会被修改
文件权限
显式列表
-
%{绑定}/* -
%{数据目录}/* -
%{包含目录}/* -
%{手动}/* -
%{文档目录}/*
用户和组
Web应用程序
-
/var应该包含变量数据文件和日志。 /usr/share更适合于此。 -
许多用户已经在/var/www中拥有内容, 我们不想让任何Fedora软件包超越这一点。 -
/文件系统层次结构标准不再指定var/www
修补程序指南
所有补丁都应该有上游错误链接或注释
# 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
应用修补程序
Epochs的使用
版本:1.2 释放:3%{?dist} 时代:1
需要:foo=%{epoch}:% {版本}- %{发布}
符号链接
将Symlink替换为目录或将目录替换为任何类型的文件
tmp文件。 d日
重命名/替换或删除现有包
|
提供:oldpackagename=$provEVR 过时:oldpackagename<$obsEVR
|
|
提供:foo=2:% {版本}- %{发布} #重要提示:我们将Obsoletes版本设置为4,以高于上次构建的foo 过时:foo<2:1.0-4
正在弃用程序包
Cron文件
构建时网络访问
引导
#当我们进行引导时,我们会删除一些依赖项和/或构建时测试。 %bcond_with引导 [...] %如果%{没有引导} #%%检查的依赖项 构建要求:foo %结尾 [...] %如果%{没有引导} %检查 进行检查 %结尾
|
|
%如果%{没有引导} 提供:bar(some_functionality) %结尾
系统加密策略
Shebang线
-
环境价值 , /箱子/环境 和 /usr/bin/env 不得使用。 用于运行打包应用程序的解释器不能依赖于 用户的个人信息 $路径 . -
未作为可执行文件安装的文件不应具有shebang行。 -
特定于语言的指导原则可能有其他限制。
-
分装商可以选择手动修复shebang管线 (使用补丁、通过sed编写脚本或其他类似方法)。 -
打包程序可以从脚本中删除可执行权限 从而不进行检查和修改。
BRP(BuildRoot策略)脚本
#关闭Python字节码编译,因为这是一个Jython #包,我们将生成JVM字节码 %全局__brp_python_bytecompile%{nil}
sed-r-n'/^%__ os_install_post/,/%。? nil/p'/usr/lib/rpm/redhat/macros
rpmbuild--eval“%dump”|&grep“:__brp_”