RedHat软件包管理工具-RPM


RPM Package Manager (RPM) 是一个强大的命令行驱动的软件包管理工具,用来安装、卸载、校验、查询和更新 Linux 系统上的软件包。RPM 是许多 Linux 发行版中用于打包、安装和管理软件的工具,广泛应用于 Red Hat Enterprise Linux 及其衍生版本,比如 AlmaLinux、Rocky Linux 和 Oracle Linux,当然也包括 Fedora 和 CentOS Stream。
一、准备工作
1.要打包套件,必须先安装 rpm-build 套件
sudo yum install rpm-build
2.建立打包套件的环境
在 FC5 后,并不建议用 root 来打包套件,所以请改用一般的使用者身分来打包套件
首先要安装 fedora-rpmdevtools 这个套件
sudo yum install fedora-rpmdevtools
接著执行 fedora-buildrpmtree 来建立打包的环境
fedora-buildrpmtree
执行完后,在 Home 目录底下就产生 rpmbuild 的目录
在 rpmbuild 目录底下又有 BUILD RPMS SOURCES SPECS SRPMS 五个子目录
BUILD 编译时所用的暂存目录
RPMS 放置打包好的套件
SOURCES 放置套件的原始码及修补档等等
SPECS 放置 .spec 档
SRPMS 放置 Source RPMS (.src.rpm)
-bp 只作准备 (解压与打补丁)
-bc 准备并编译
-bi 编译并安装
-bl 检验文件是否齐全
-ba 编译后做成*.rpm和src.rpm
-bb 编译后做成*.rpm
-bs 只做成*.src.rpm
-tc -ti -ta -tb -ts 的功能类似,只是所需参数由spec文件变成tar包。
3.建立 ~/.rpmmacros 档案
编辑 ~/.rpmmacros,主要是设定 %packager 及 %vendor 等等:
%_topdir %(echo $HOME)/rpmbuild
%_smp_mflags -j3
%__arch_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot
%packager Chung-Yen Chang
%vendor Chinese Linux Extensions
如果有 GPG Key 可以加上类似底下几行,到时候要 GPG Sign 时会用到:
%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name Chung-Yen Chang (candyz)
%_gpgbin /usr/bin/gpg
二、建立 spec 档案
我以打包 pcmanfm-0.3.0-beta3.tar.gz 为例
假设这个套件没有人打包过,因此必须自行建立 pcmanfm.spec 档案
先进到 ~/rpmbuild/SPECS 目录底下:
cd ~/rpmbuild/SPECS
1.利用 fedora-newrpmspec 工具程式来产生一个 spec 档的样本,然后再慢慢来修改
fedora-newrpmspec pcmanfm
执行完后,就会产生 pcmanfm.spec
spec 档的命名规则为 %{name}.spec
spec 档的 Encoding 必须为 UTF-8
2.编辑 pcmanfm.spec
2.1.Version、Release 及 Summary
Version: 0.3.0
Release: 0.1.beta3%{?dist}
Summary: PCMan File Manager
Version Tag 及 Release Tag 的命名规则,请参考:
http://fedoraproject.org/wiki/Packaging/NamingGuidelines
Version Tag 要是数字才行
pcmanfm-0.3.0-beta3 算是 Pre-release packages
(Version 中包含 “alpha”, “beta”, “rc”, “cvs”)
我们不能直接用在 Version 中,beta3 的部份要改放到 Release 中
Release Tag for Pre-Release Packages:
格式: 0.%{X}.%{alphatag}
0 不变
%{X} 从 1 开始递增
%{alphatag} 来自於 Version Tag 中的字串
所以 pcmanfm-0.3.0-beta3 的 Release Tag 就是 0.1.beta3
至於后面的 Dist Tag (%{?dist}) 则是给 mock build 时用的
Dist Tag 请参考: http://fedoraproject.org/wiki/Packaging/DistTag
2.2.Group、License、URL、Source、Patch 及 BuildRoot
Group: Applications/System
License: GPL
URL: http://pcmanfm.sourceforge.net
Source0: http://jaist.dl.sourceforge.net/sourceforge/pcmanfm/pcmanfm-0.3.0-beta3.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Group 部份请参考:
/usr/share/doc/rpm-*/GROUPS 或是 http://fedoraproject.org/wiki/RPMGroups
Source 部份,最好是包含整个网址,而不要只有档名而已
若有好几个 Source 则用 Source0 Source1 Source2 … 依此类推
若有 Patch 档就需要用到 (例: Patch0: pcmanfm-0.3.0-beta3-Makefile.patch)
若有好几个 Pacth 则用 Patch0 Patch1 Patch2 … 依此类推
必要时需要自己制作 patch 档案,例:
cd ~/rpmbuild/BUILD/pcmanfm-0.3.0-beta3
cp Makefile Makefile.orig
然后修改 Makefile
cd ~/rpmbuild/BUILD
gendiff pcmanfm-0.3.0-beta3 .Makefile < ../SOURCES/pcmanfm-0.3.0-beta3-Makefile.patch
2.3.BuildRequires 及 Requires
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel
Requires: gtk2 >= 2.6, gamin
BuildRequires 及 Requires 的部份就要看原作者是否有提到需要哪些套件
不然,就得从 mock build 时的 build.log 中
慢慢去找出所需要的 BuildRequires 及 Requires
2.4.%description
%description
PCMan File Manager
An extremly fast and lightweight file manager which features tabbed browsing
and user-friendly interface
Features:
Extremly fast and lightweight
Can be started in one second on normal machine
Tabbed browsing (Similar to Firefox)
Drag & Drop support
Files can be dragged among tabs
Load large directories in reasonable time
File association support (Default application)
Basic thumbnail support
Bookmarks support
Handles non-UTF-8 encoded filenames correctly
Provide icon view and detailed list view
Standard compliant (Follows FreeDesktop.org)
Clean and user-friendly interface (GTK+ 2)
%description 要注意的是,每一行最长不要超过 79 个字元
2.5.%changelog
%changelog
* Fri Aug 18 2006 Chung-Yen Chang - 0.3.0-0.1.beta3
- Initial RPM release
%changelog 部份,就是日期、打包者的姓名及 E-mail 等等
最后面则是要包含这次的 %{version}-%{release}
若有使用 Epoch Tag 则是 %{Epoch}:%{version}-%{release}
2.6.%prep
%prep
%setup -q -n pcmanfm-0.3.0-beta3
%setup macro 会把 source code tarball 解开并自动进到 %{name}-%{version} 的目录中
因为我们把 Version Tag 0.3.0-beta3 的 beta3 拆到 Release Tag 去
Version Tag 变成 0.3.0,所以 %setup 在 rpmbuild 时会出问题
rpmbuild 会解开 pcmanfm-0.3.0-beta3.tar.gz 并试著进到 pcmanfm-0.3.0 (%{name}-%{version}) 的目录中
但实际上应该是要进到 pcmanfm-0.3.0-beta3 的目录才对
因此,我们必须加上 -n pcmanfm-0.3.0-beta3 来解决这个问题
若有 Source2 Source5 等等的 tarball 同时也要解开时,可以使用 -a 参数来指定 (例: %setup -q -a 2 -a 5)
若有 Patch 档则同样在这里做处理 (例: %patch1 -p1 -b .bak)
其他一些在正式 build (make) 前要做的特殊处理,都可以在这里做
(例: find . -name \*.h -o -name \*.c | xargs chmod ugo-x)
2.7.%build
%build
%configure
make %{?_smp_mflags}
若有需要加 configure 的参数,可以加在 %configure 后面
(例: %configure –prefix=%{_prefix})
若还有其他的编译指令需要执行时,都可以加在这里
2.8.%install
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%find_lang %{name}
desktop-file-install \
--delete-original \
--vendor fedora \
--dir ${RPM_BUILD_ROOT}/%{_datadir}/applications \
--add-category X-Fedora \
${RPM_BUILD_ROOT}/%{_datadir}/applications/pcmanfm.desktop
若还有其他相关的安装指令都可以加在这里
至於 locale mo 档的部份,则是要改用 %find_lang macro 来处理
另外,关於 desktop 档的部份,要在 %install 中使用 desktop-file-install 来处理
然后在 %files 中加入一行:
%{_datadir}/applications/fedora-pcmanfm.desktop
BuildRequires 的部份也要加入 desktop-file-utils:
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils
另外还要加入:
Requires(post): desktop-file-utils
Requires(postun): desktop-file-utils
%post 及 %postun 的部份也要做处理
Desktop files 请参考: http://fedoraproject.org/wiki/Packaging/Guidelines#desktop
2.9.%clean
%clean
rm -rf $RPM_BUILD_ROOT
2.10.%files
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_datadir}/applications/fedora-pcmanfm.desktop
%files 后面的 -f %{name}.lang 则是跟 %find_lang macro 搭配
用来处理 locale mo 档
%doc 部份,则是放 AUTHORS COPYING ChangeLog INSTALL NEWS README TODO 等文件
至少要放版权的部份 (如 License: GPL 则 COPYING 的内容就是放 GPL 版权的内容)
若不知道还会安装哪些档案也没关系,之后可以利用 rpmbuild -bi 的 log 来查询
2.11.%post
%post
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :
用来处理套件安装完成后要执行的指令
例如 update-desktop-database 那行就是在处理 Desktop files 部份
2.12.%postun
%postun
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :
用来处理套件移除后要执行的指令
例如 update-desktop-database 那行就是在处理 Desktop files 部份
2.13.%pre
用来处理套件安装前要执行的指令
在本例中没有用到
2.14.%preun
用来处理套件移除前要执行的指令
在本例中没有用到
三、测试打包
除了 %files 的部份还没完全处理完外,其他部份大致上都没问题了
1.rpmbuild -bc
rpmbuild -bc 会从一开始一直做到 %build 为止
用来检查到 %build 为止是否还有问题
若有发现任何错误,如 command not found 等等
就要去 check required package 然后加到 Requires/BuildRequires 中
rpmbuild -bc pcmanfm.spec
像我一执行时就出现错误:
checking for PACKAGE... configure: error: Package requirements (gtk+-2.0 >= 2.6.
0 gthread-2.0 libstartup-notification-1.0) were not met:
No package 'libstartup-notification-1.0' found
查了一下,所需要的套件是 startup-notification-devel
[candyz@candyz:~/rpmbuild/SPECS] locate libstartup-notification-1.0
/usr/lib/pkgconfig/libstartup-notification-1.0.pc
[candyz@candyz:~/rpmbuild/SPECS] rpm -qf /usr/lib/pkgconfig/libstartup-notification-1.0.pc
startup-notification-devel-0.8-3.2.1
因此,修改 BuildRequires 如下:
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils, gettext, startup-notification-devel
加进了 startup-notification-devel
而多加了 gettext 则是给 mock build 用的
因为在 mock build 时会去 check 是否有 gettext,有才会去执行 %find_lang macro
2.rpmbuild -bi
rpmbuild -bi 会从一开始一直做到 %install 为止
rpmbuild -bi pcmanfm.spec
例如我执行完的结果,看到以下的警告讯息:
warning: Installed (but unpackaged) file(s) found:
/usr/bin/pcmanfm
/usr/share/applications/pcmanfm.desktop
/usr/share/locale/ca/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/de/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/es/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/fr/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/hu/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/it/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/pl/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/pt_BR/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/ru/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/sv_SE/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_CN/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_TW/LC_MESSAGES/pcmanfm.mo
因此,可以得知,%files 中还少了 /usr/bin/pcmanfm
至於 locale 的 mo 档部份,可以不用管,改交给 %find_lang macro 去处理了
而 /usr/share/applications/pcmanfm.desktop 则改由 desktop-file-install 处理
因此,修改后的 %files 部份如下:
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_bindir}/pcmanfm
%{_datadir}/applications/fedora-pcmanfm.desktop
相关的 macros 可以在 http://fedoraproject.org/wiki/Extras/RPMMacros 查询到
常见的如:
%{_sysconfdir} /etc
%{_initrddir} %{_sysconfdir}/rc.d/init.d
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_lib} lib
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} %{_prefix}/com
%{_datadir} %{_prefix}/share
%{_includedir} %{_prefix}/include
%{_oldincludedir} /usr/include
%{_var} /var
%{_tmppath} %{_var}/tmp
请尽量改用 macros 来取代 /etc /usr/bin /usr/lib 的写法
3.rpmbuild -bs、rpmbuild -bb and rpmbuild -ba
若 rpmbuild -bi 都没错误,接下来就可以开始打包套件了
3.1.用 rpmbuild -bs 来产生 SRPMS
rpmbuild -bs pcmanfm.spec
3.2.用 rpmbuild -bb 来产生 RPMS
rpmbuild -bb pcmanfm.spec
3.3.用 rpmbuild -ba 来同时产生 SRPMS 及 RPMS
rpmbuild -ba pcmanfm.spec
四、使用 rpmlint 来检查 SRPMS RPMS
rpmlint -i ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm
rpmlint -i ~/rpmbuild/RPMS/i386/pcmanfm-*.rpm
rpmlint 的错误讯息请参考:
http://fedoraproject.org/wiki/ParagNemade/CommonRpmlintErrors
及 http://fedoraproject.org/wiki/Packaging/CommonRpmlintIssues
五、使用 mock 来 chroot build
mock 是一个 Chroot Build Tools
关於 mock 的安装、设定及使用请参考: http://blog.candyz.org/20060818/1307
mock -r fedora-5-i386-core.cfg ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm
六、其他进阶部份
1.devel subpackage
所有的可执行档及 *.so.* 要放在 main package
而所有的 headers, static libraries, libtool archives, *.so files, autotools,
and pkgconfig files 则要放在 -devel subpackage.
若套件有包含一些不重要的 examples 时,可以在 %install 最后的地方删除掉
把 examples 改放到 -devel 的 %doc 中
请参考:
http://fedoraproject.org/wiki/Docs/Drafts/BuildingPackagesGuide 的范例
2.不需要加到 BuildRequires 中的 Exceptions
bash
bzip2
coreutils
cpio
diffutils
fedora-release (and/or redhat-release)
gcc
gcc-c++
gzip
make
patch
perl
redhat-rpm-config
rpm-build
sed
tar
unzip
which
详细清单请参考: http://fedoraproject.org/wiki/Extras/FullExceptionList
3.Documentation
若有相关的说明文件,可以独立成 -doc subpackage
并以 Documentation 当作 Group Tag
4.Configuration files
设定档请使用 %config(noreplace) 来代替 %config
只有当设定档有变时,才改用 %config 来覆盖掉旧的
5.Macros
详细的 Macros 请参考: http://fedoraproject.org/wiki/Extras/RPMMacros
6.不要使用 %makeinstall macro
直接用:
make DESTDIR=$RPM_BUILD_ROOT install
7.Fedora RPM Development Tools
fedora-rpmdevtools,请参考: http://fedoraproject.org/wiki/fedora-rpmdevtools
8.RPM scriptlet recipes
关於 %pre %post %preun %postun 的用法及注意事项,请参考:
http://fedoraproject.org/wiki/Packaging/ScriptletSnippets
七、GPG Sign
1.rpmbuild –sign
在执行 rpmbuild 时加上 –sign 的参数
2.rpm -addsign
若在 rpmbuild 时没有使用 –sign 参数,也可以事后再用 rpm –addsign 来 Sign 套件
八、参考文件
http://www.rpm.org/max-rpm/
http://fedoraproject.org/wiki/Packaging/Guidelines
http://fedoraproject.org/wiki/ParagNemade/PackagingNotes
http://fedoraproject.org/wiki/Docs/Drafts/BuildingPackagesGuide
http://koti.welho.com/vskytta/packagers-handbook/packagers-handbook.html
九、最新版本
2020年10月1日,RPM 4.16.0 已经发布,此版本更新亮点包括:
数据库后端:
NDB 后端升级到稳定状态
新的基于 sqlite 的后端
新的实验性只读 BDB 后端
BDB 数据库后端已弃用
强大的宏和 %if 表达式,包括三元运算符和原生版本比较
可选的基于 MIME 类型的文件分类
通过参数宏生成依赖项
C 和 Python 新版本解析和比较 API
并行测试套件执行
更多详情查看更新说明。
2024年10月中旬发布了v4.20版本。其主要新特性如下:
声明式构建系统支持
在 RPM 4.20 中,最大的亮点之一就是引入了 声明式构建系统支持。这意味着开发者可以更轻松地指定使用哪种构建系统(如 Autotools 或 CMake),而 RPM 将根据这些构建系统的最佳实践,自动准备、编译和安装源代码。
好处是什么
单来说,这个功能大大减少了繁琐的模板代码,优化了软件包的构建流程,使其更加高效,也更符合不同 Linux 发行版的需求。
动态 spec 文件的改进
在 RPM 4.20 中,动态 spec 文件 也得到了进一步优化。这些文件定义了如何构建 RPM 包,现在开发者可以在不影响实际构建过程的前提下,添加新指令,增强了模块化和可维护性。这意味着开发者在创建和维护 spec 文件时,会有更大的灵活性和控制力。
提升构建流程的工具与安全性
独立构建目录
每个软件包现在都有一个由 RPM 自动管理的独立构建目录。这不仅有助于简化软件包的构建流程,还能防止多个软件包同时构建时可能产生的冲突问题,使构建更加有序和高效。
新增 unshare 插件:隔离脚本执行
v4.20 还推出了 unshare 插件,专为提高安全性设计。通常在安装软件包前后会执行一些脚本命令,而 unshare 插件通过隔离这些脚本,确保它们无法意外访问系统的文件或网络,从而有效避免潜在的安全问题,增加了一层保护。
更好的用户体验与新功能
密钥管理与包签名增强
在可用性方面,RPM 4.20 对密钥管理工具进行了改进。现在,rpmkeys 命令新增了列出和删除加密密钥的选项,方便用户更灵活地管理密钥。此外,rpmsign 现在支持使用 ECDSA 密钥 进行包签名,为加密提供了更多选择和灵活性。
现代数据格式支持:JSON 输出
为了满足现代数据处理需求,RPM 4.20 还支持将查询结果以 JSON 格式 输出。相较于传统的 XML 格式,JSON 更加简洁、易读,并且便于与其他工具集成,这对开发者和系统管理员来说是一个非常友好的改进。
新工具 rpm2archive
RPM 4.20 还引入了 rpm2archive 工具,这是一个用于将 RPM 包转换为存档格式的实用程序。新版本支持 CPIO 文件格式,提高了与旧版系统的兼容性。老的 rpm2cpio 命令现在只是这个新工具的一个符号链接。
为开发者提供的好消息
公共插件 API 正式发布
开发者们会特别高兴听到,RPM 的 公共插件 API 现在正式发布了。这为扩展 RPM 的功能开辟了新的可能性,开发者可以更加轻松地定制 RPM 的行为,创建新的插件,满足不同场景的需求。
加速依赖生成
此外,新增的多文件协议 使得依赖项生成的速度大幅提升。这不仅让构建过程更加流畅,也为所有 Linux 用户带来了更好的软件管理体验。
可重现构建支持进一步增强
RPM 4.20 也对 可重现构建 做了进一步优化。这是现代软件开发中的重要需求,确保软件包无论在何时何地构建,都能生成一致的结果。为此,RPM 现在提供了一个新的宏 %build_mtime_policy,开发者可以选择将时间戳固定为源代码日期或构建时间,从而提高构建的一致性。
其他改进与错误修复
最后,RPM 4.20 还包含了多项错误修复和性能改进。例如,RPM 现在不再尝试处理某些非可执行文件(如 Ruby、Python 或 JavaScript 文件),这加快了处理速度。此外,spec 文件中的注释和缩进语法也得到了清理,使文件更加简洁、易读、便于维护。
何时可以使用 RPM v4.20
Fedora 工程指导委员会(FESCo)已经批准将 v4.20 纳入即将发布的 Fedora 41 版本中,预计会在2024年11月初发布。
RPM v4.20 的发布带来了许多全新的功能和优化,从声明式构建系统支持,到增强的安全性和可用性工具,再到针对开发者的全新 API 及插件支持。这个版本不仅提高了 RPM 的易用性,还使构建过程更加灵活高效,满足了现代 Linux 生态系统的多种需求。如果你是软件开发者、系统管理员,或者只是对 Linux 包管理感兴趣,那么 RPM 4.20 将会是一个令人期待的工具升级。想了解更多技术细节,请查阅 RPM 4.20 的发行说明。
一、准备工作
1.要打包套件,必须先安装 rpm-build 套件
sudo yum install rpm-build
2.建立打包套件的环境
在 FC5 后,并不建议用 root 来打包套件,所以请改用一般的使用者身分来打包套件
首先要安装 fedora-rpmdevtools 这个套件
sudo yum install fedora-rpmdevtools
接著执行 fedora-buildrpmtree 来建立打包的环境
fedora-buildrpmtree
执行完后,在 Home 目录底下就产生 rpmbuild 的目录
在 rpmbuild 目录底下又有 BUILD RPMS SOURCES SPECS SRPMS 五个子目录
BUILD 编译时所用的暂存目录
RPMS 放置打包好的套件
SOURCES 放置套件的原始码及修补档等等
SPECS 放置 .spec 档
SRPMS 放置 Source RPMS (.src.rpm)
-bp 只作准备 (解压与打补丁)
-bc 准备并编译
-bi 编译并安装
-bl 检验文件是否齐全
-ba 编译后做成*.rpm和src.rpm
-bb 编译后做成*.rpm
-bs 只做成*.src.rpm
-tc -ti -ta -tb -ts 的功能类似,只是所需参数由spec文件变成tar包。
3.建立 ~/.rpmmacros 档案
编辑 ~/.rpmmacros,主要是设定 %packager 及 %vendor 等等:
%_topdir %(echo $HOME)/rpmbuild
%_smp_mflags -j3
%__arch_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot
%packager Chung-Yen Chang
%vendor Chinese Linux Extensions
如果有 GPG Key 可以加上类似底下几行,到时候要 GPG Sign 时会用到:
%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name Chung-Yen Chang (candyz)
%_gpgbin /usr/bin/gpg
二、建立 spec 档案
我以打包 pcmanfm-0.3.0-beta3.tar.gz 为例
假设这个套件没有人打包过,因此必须自行建立 pcmanfm.spec 档案
先进到 ~/rpmbuild/SPECS 目录底下:
cd ~/rpmbuild/SPECS
1.利用 fedora-newrpmspec 工具程式来产生一个 spec 档的样本,然后再慢慢来修改
fedora-newrpmspec pcmanfm
执行完后,就会产生 pcmanfm.spec
spec 档的命名规则为 %{name}.spec
spec 档的 Encoding 必须为 UTF-8
2.编辑 pcmanfm.spec
2.1.Version、Release 及 Summary
Version: 0.3.0
Release: 0.1.beta3%{?dist}
Summary: PCMan File Manager
Version Tag 及 Release Tag 的命名规则,请参考:
http://fedoraproject.org/wiki/Packaging/NamingGuidelines
Version Tag 要是数字才行
pcmanfm-0.3.0-beta3 算是 Pre-release packages
(Version 中包含 “alpha”, “beta”, “rc”, “cvs”)
我们不能直接用在 Version 中,beta3 的部份要改放到 Release 中
Release Tag for Pre-Release Packages:
格式: 0.%{X}.%{alphatag}
0 不变
%{X} 从 1 开始递增
%{alphatag} 来自於 Version Tag 中的字串
所以 pcmanfm-0.3.0-beta3 的 Release Tag 就是 0.1.beta3
至於后面的 Dist Tag (%{?dist}) 则是给 mock build 时用的
Dist Tag 请参考: http://fedoraproject.org/wiki/Packaging/DistTag
2.2.Group、License、URL、Source、Patch 及 BuildRoot
Group: Applications/System
License: GPL
URL: http://pcmanfm.sourceforge.net
Source0: http://jaist.dl.sourceforge.net/sourceforge/pcmanfm/pcmanfm-0.3.0-beta3.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Group 部份请参考:
/usr/share/doc/rpm-*/GROUPS 或是 http://fedoraproject.org/wiki/RPMGroups
Source 部份,最好是包含整个网址,而不要只有档名而已
若有好几个 Source 则用 Source0 Source1 Source2 … 依此类推
若有 Patch 档就需要用到 (例: Patch0: pcmanfm-0.3.0-beta3-Makefile.patch)
若有好几个 Pacth 则用 Patch0 Patch1 Patch2 … 依此类推
必要时需要自己制作 patch 档案,例:
cd ~/rpmbuild/BUILD/pcmanfm-0.3.0-beta3
cp Makefile Makefile.orig
然后修改 Makefile
cd ~/rpmbuild/BUILD
gendiff pcmanfm-0.3.0-beta3 .Makefile < ../SOURCES/pcmanfm-0.3.0-beta3-Makefile.patch
2.3.BuildRequires 及 Requires
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel
Requires: gtk2 >= 2.6, gamin
BuildRequires 及 Requires 的部份就要看原作者是否有提到需要哪些套件
不然,就得从 mock build 时的 build.log 中
慢慢去找出所需要的 BuildRequires 及 Requires
2.4.%description
%description
PCMan File Manager
An extremly fast and lightweight file manager which features tabbed browsing
and user-friendly interface
Features:
Extremly fast and lightweight
Can be started in one second on normal machine
Tabbed browsing (Similar to Firefox)
Drag & Drop support
Files can be dragged among tabs
Load large directories in reasonable time
File association support (Default application)
Basic thumbnail support
Bookmarks support
Handles non-UTF-8 encoded filenames correctly
Provide icon view and detailed list view
Standard compliant (Follows FreeDesktop.org)
Clean and user-friendly interface (GTK+ 2)
%description 要注意的是,每一行最长不要超过 79 个字元
2.5.%changelog
%changelog
* Fri Aug 18 2006 Chung-Yen Chang - 0.3.0-0.1.beta3
- Initial RPM release
%changelog 部份,就是日期、打包者的姓名及 E-mail 等等
最后面则是要包含这次的 %{version}-%{release}
若有使用 Epoch Tag 则是 %{Epoch}:%{version}-%{release}
2.6.%prep
%prep
%setup -q -n pcmanfm-0.3.0-beta3
%setup macro 会把 source code tarball 解开并自动进到 %{name}-%{version} 的目录中
因为我们把 Version Tag 0.3.0-beta3 的 beta3 拆到 Release Tag 去
Version Tag 变成 0.3.0,所以 %setup 在 rpmbuild 时会出问题
rpmbuild 会解开 pcmanfm-0.3.0-beta3.tar.gz 并试著进到 pcmanfm-0.3.0 (%{name}-%{version}) 的目录中
但实际上应该是要进到 pcmanfm-0.3.0-beta3 的目录才对
因此,我们必须加上 -n pcmanfm-0.3.0-beta3 来解决这个问题
若有 Source2 Source5 等等的 tarball 同时也要解开时,可以使用 -a 参数来指定 (例: %setup -q -a 2 -a 5)
若有 Patch 档则同样在这里做处理 (例: %patch1 -p1 -b .bak)
其他一些在正式 build (make) 前要做的特殊处理,都可以在这里做
(例: find . -name \*.h -o -name \*.c | xargs chmod ugo-x)
2.7.%build
%build
%configure
make %{?_smp_mflags}
若有需要加 configure 的参数,可以加在 %configure 后面
(例: %configure –prefix=%{_prefix})
若还有其他的编译指令需要执行时,都可以加在这里
2.8.%install
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%find_lang %{name}
desktop-file-install \
--delete-original \
--vendor fedora \
--dir ${RPM_BUILD_ROOT}/%{_datadir}/applications \
--add-category X-Fedora \
${RPM_BUILD_ROOT}/%{_datadir}/applications/pcmanfm.desktop
若还有其他相关的安装指令都可以加在这里
至於 locale mo 档的部份,则是要改用 %find_lang macro 来处理
另外,关於 desktop 档的部份,要在 %install 中使用 desktop-file-install 来处理
然后在 %files 中加入一行:
%{_datadir}/applications/fedora-pcmanfm.desktop
BuildRequires 的部份也要加入 desktop-file-utils:
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils
另外还要加入:
Requires(post): desktop-file-utils
Requires(postun): desktop-file-utils
%post 及 %postun 的部份也要做处理
Desktop files 请参考: http://fedoraproject.org/wiki/Packaging/Guidelines#desktop
2.9.%clean
%clean
rm -rf $RPM_BUILD_ROOT
2.10.%files
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_datadir}/applications/fedora-pcmanfm.desktop
%files 后面的 -f %{name}.lang 则是跟 %find_lang macro 搭配
用来处理 locale mo 档
%doc 部份,则是放 AUTHORS COPYING ChangeLog INSTALL NEWS README TODO 等文件
至少要放版权的部份 (如 License: GPL 则 COPYING 的内容就是放 GPL 版权的内容)
若不知道还会安装哪些档案也没关系,之后可以利用 rpmbuild -bi 的 log 来查询
2.11.%post
%post
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :
用来处理套件安装完成后要执行的指令
例如 update-desktop-database 那行就是在处理 Desktop files 部份
2.12.%postun
%postun
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :
用来处理套件移除后要执行的指令
例如 update-desktop-database 那行就是在处理 Desktop files 部份
2.13.%pre
用来处理套件安装前要执行的指令
在本例中没有用到
2.14.%preun
用来处理套件移除前要执行的指令
在本例中没有用到
三、测试打包
除了 %files 的部份还没完全处理完外,其他部份大致上都没问题了
1.rpmbuild -bc
rpmbuild -bc 会从一开始一直做到 %build 为止
用来检查到 %build 为止是否还有问题
若有发现任何错误,如 command not found 等等
就要去 check required package 然后加到 Requires/BuildRequires 中
rpmbuild -bc pcmanfm.spec
像我一执行时就出现错误:
checking for PACKAGE... configure: error: Package requirements (gtk+-2.0 >= 2.6.
0 gthread-2.0 libstartup-notification-1.0) were not met:
No package 'libstartup-notification-1.0' found
查了一下,所需要的套件是 startup-notification-devel
[candyz@candyz:~/rpmbuild/SPECS] locate libstartup-notification-1.0
/usr/lib/pkgconfig/libstartup-notification-1.0.pc
[candyz@candyz:~/rpmbuild/SPECS] rpm -qf /usr/lib/pkgconfig/libstartup-notification-1.0.pc
startup-notification-devel-0.8-3.2.1
因此,修改 BuildRequires 如下:
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils, gettext, startup-notification-devel
加进了 startup-notification-devel
而多加了 gettext 则是给 mock build 用的
因为在 mock build 时会去 check 是否有 gettext,有才会去执行 %find_lang macro
2.rpmbuild -bi
rpmbuild -bi 会从一开始一直做到 %install 为止
rpmbuild -bi pcmanfm.spec
例如我执行完的结果,看到以下的警告讯息:
warning: Installed (but unpackaged) file(s) found:
/usr/bin/pcmanfm
/usr/share/applications/pcmanfm.desktop
/usr/share/locale/ca/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/de/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/es/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/fr/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/hu/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/it/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/pl/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/pt_BR/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/ru/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/sv_SE/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_CN/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_TW/LC_MESSAGES/pcmanfm.mo
因此,可以得知,%files 中还少了 /usr/bin/pcmanfm
至於 locale 的 mo 档部份,可以不用管,改交给 %find_lang macro 去处理了
而 /usr/share/applications/pcmanfm.desktop 则改由 desktop-file-install 处理
因此,修改后的 %files 部份如下:
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_bindir}/pcmanfm
%{_datadir}/applications/fedora-pcmanfm.desktop
相关的 macros 可以在 http://fedoraproject.org/wiki/Extras/RPMMacros 查询到
常见的如:
%{_sysconfdir} /etc
%{_initrddir} %{_sysconfdir}/rc.d/init.d
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_lib} lib
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} %{_prefix}/com
%{_datadir} %{_prefix}/share
%{_includedir} %{_prefix}/include
%{_oldincludedir} /usr/include
%{_var} /var
%{_tmppath} %{_var}/tmp
请尽量改用 macros 来取代 /etc /usr/bin /usr/lib 的写法
3.rpmbuild -bs、rpmbuild -bb and rpmbuild -ba
若 rpmbuild -bi 都没错误,接下来就可以开始打包套件了
3.1.用 rpmbuild -bs 来产生 SRPMS
rpmbuild -bs pcmanfm.spec
3.2.用 rpmbuild -bb 来产生 RPMS
rpmbuild -bb pcmanfm.spec
3.3.用 rpmbuild -ba 来同时产生 SRPMS 及 RPMS
rpmbuild -ba pcmanfm.spec
四、使用 rpmlint 来检查 SRPMS RPMS
rpmlint -i ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm
rpmlint -i ~/rpmbuild/RPMS/i386/pcmanfm-*.rpm
rpmlint 的错误讯息请参考:
http://fedoraproject.org/wiki/ParagNemade/CommonRpmlintErrors
及 http://fedoraproject.org/wiki/Packaging/CommonRpmlintIssues
五、使用 mock 来 chroot build
mock 是一个 Chroot Build Tools
关於 mock 的安装、设定及使用请参考: http://blog.candyz.org/20060818/1307
mock -r fedora-5-i386-core.cfg ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm
六、其他进阶部份
1.devel subpackage
所有的可执行档及 *.so.* 要放在 main package
而所有的 headers, static libraries, libtool archives, *.so files, autotools,
and pkgconfig files 则要放在 -devel subpackage.
若套件有包含一些不重要的 examples 时,可以在 %install 最后的地方删除掉
把 examples 改放到 -devel 的 %doc 中
请参考:
http://fedoraproject.org/wiki/Docs/Drafts/BuildingPackagesGuide 的范例
2.不需要加到 BuildRequires 中的 Exceptions
bash
bzip2
coreutils
cpio
diffutils
fedora-release (and/or redhat-release)
gcc
gcc-c++
gzip
make
patch
perl
redhat-rpm-config
rpm-build
sed
tar
unzip
which
详细清单请参考: http://fedoraproject.org/wiki/Extras/FullExceptionList
3.Documentation
若有相关的说明文件,可以独立成 -doc subpackage
并以 Documentation 当作 Group Tag
4.Configuration files
设定档请使用 %config(noreplace) 来代替 %config
只有当设定档有变时,才改用 %config 来覆盖掉旧的
5.Macros
详细的 Macros 请参考: http://fedoraproject.org/wiki/Extras/RPMMacros
6.不要使用 %makeinstall macro
直接用:
make DESTDIR=$RPM_BUILD_ROOT install
7.Fedora RPM Development Tools
fedora-rpmdevtools,请参考: http://fedoraproject.org/wiki/fedora-rpmdevtools
8.RPM scriptlet recipes
关於 %pre %post %preun %postun 的用法及注意事项,请参考:
http://fedoraproject.org/wiki/Packaging/ScriptletSnippets
七、GPG Sign
1.rpmbuild –sign
在执行 rpmbuild 时加上 –sign 的参数
2.rpm -addsign
若在 rpmbuild 时没有使用 –sign 参数,也可以事后再用 rpm –addsign 来 Sign 套件
八、参考文件
http://www.rpm.org/max-rpm/
http://fedoraproject.org/wiki/Packaging/Guidelines
http://fedoraproject.org/wiki/ParagNemade/PackagingNotes
http://fedoraproject.org/wiki/Docs/Drafts/BuildingPackagesGuide
http://koti.welho.com/vskytta/packagers-handbook/packagers-handbook.html
九、最新版本
2020年10月1日,RPM 4.16.0 已经发布,此版本更新亮点包括:
数据库后端:
NDB 后端升级到稳定状态
新的基于 sqlite 的后端
新的实验性只读 BDB 后端
BDB 数据库后端已弃用
强大的宏和 %if 表达式,包括三元运算符和原生版本比较
可选的基于 MIME 类型的文件分类
通过参数宏生成依赖项
C 和 Python 新版本解析和比较 API
并行测试套件执行
更多详情查看更新说明。
2024年10月中旬发布了v4.20版本。其主要新特性如下:
声明式构建系统支持
在 RPM 4.20 中,最大的亮点之一就是引入了 声明式构建系统支持。这意味着开发者可以更轻松地指定使用哪种构建系统(如 Autotools 或 CMake),而 RPM 将根据这些构建系统的最佳实践,自动准备、编译和安装源代码。
好处是什么
单来说,这个功能大大减少了繁琐的模板代码,优化了软件包的构建流程,使其更加高效,也更符合不同 Linux 发行版的需求。
动态 spec 文件的改进
在 RPM 4.20 中,动态 spec 文件 也得到了进一步优化。这些文件定义了如何构建 RPM 包,现在开发者可以在不影响实际构建过程的前提下,添加新指令,增强了模块化和可维护性。这意味着开发者在创建和维护 spec 文件时,会有更大的灵活性和控制力。
提升构建流程的工具与安全性
独立构建目录
每个软件包现在都有一个由 RPM 自动管理的独立构建目录。这不仅有助于简化软件包的构建流程,还能防止多个软件包同时构建时可能产生的冲突问题,使构建更加有序和高效。
新增 unshare 插件:隔离脚本执行
v4.20 还推出了 unshare 插件,专为提高安全性设计。通常在安装软件包前后会执行一些脚本命令,而 unshare 插件通过隔离这些脚本,确保它们无法意外访问系统的文件或网络,从而有效避免潜在的安全问题,增加了一层保护。
更好的用户体验与新功能
密钥管理与包签名增强
在可用性方面,RPM 4.20 对密钥管理工具进行了改进。现在,rpmkeys 命令新增了列出和删除加密密钥的选项,方便用户更灵活地管理密钥。此外,rpmsign 现在支持使用 ECDSA 密钥 进行包签名,为加密提供了更多选择和灵活性。
现代数据格式支持:JSON 输出
为了满足现代数据处理需求,RPM 4.20 还支持将查询结果以 JSON 格式 输出。相较于传统的 XML 格式,JSON 更加简洁、易读,并且便于与其他工具集成,这对开发者和系统管理员来说是一个非常友好的改进。
新工具 rpm2archive
RPM 4.20 还引入了 rpm2archive 工具,这是一个用于将 RPM 包转换为存档格式的实用程序。新版本支持 CPIO 文件格式,提高了与旧版系统的兼容性。老的 rpm2cpio 命令现在只是这个新工具的一个符号链接。
为开发者提供的好消息
公共插件 API 正式发布
开发者们会特别高兴听到,RPM 的 公共插件 API 现在正式发布了。这为扩展 RPM 的功能开辟了新的可能性,开发者可以更加轻松地定制 RPM 的行为,创建新的插件,满足不同场景的需求。
加速依赖生成
此外,新增的多文件协议 使得依赖项生成的速度大幅提升。这不仅让构建过程更加流畅,也为所有 Linux 用户带来了更好的软件管理体验。
可重现构建支持进一步增强
RPM 4.20 也对 可重现构建 做了进一步优化。这是现代软件开发中的重要需求,确保软件包无论在何时何地构建,都能生成一致的结果。为此,RPM 现在提供了一个新的宏 %build_mtime_policy,开发者可以选择将时间戳固定为源代码日期或构建时间,从而提高构建的一致性。
其他改进与错误修复
最后,RPM 4.20 还包含了多项错误修复和性能改进。例如,RPM 现在不再尝试处理某些非可执行文件(如 Ruby、Python 或 JavaScript 文件),这加快了处理速度。此外,spec 文件中的注释和缩进语法也得到了清理,使文件更加简洁、易读、便于维护。
何时可以使用 RPM v4.20
Fedora 工程指导委员会(FESCo)已经批准将 v4.20 纳入即将发布的 Fedora 41 版本中,预计会在2024年11月初发布。
RPM v4.20 的发布带来了许多全新的功能和优化,从声明式构建系统支持,到增强的安全性和可用性工具,再到针对开发者的全新 API 及插件支持。这个版本不仅提高了 RPM 的易用性,还使构建过程更加灵活高效,满足了现代 Linux 生态系统的多种需求。如果你是软件开发者、系统管理员,或者只是对 Linux 包管理感兴趣,那么 RPM 4.20 将会是一个令人期待的工具升级。想了解更多技术细节,请查阅 RPM 4.20 的发行说明。