RPM打包原理spec
概述
RPM(Redhat Package Manager)是用于Redhat、CentOS、Fedora等Linux 分发版(distribution)的常见的软件包管理器。因为它允许分发已编译的软件,所以用户只用一个命令就可以安装软件。
准备
首先请准备一个Linux环境,比如CentOS。
RPM打包使用的是rpmbuild命令,这个命令来自rpm-build包,这个是必装的。
yum install rpm-build
当然也可以直接安装rpmdevtools,这个工具还包含一些其他的工具,同时它依赖rpm-build,所以直接安装的话会同时把rpm-build装上。
yum install rpmdevtools
当然,根据不同的软件构建过程,还需要其他的编译打包工具,比如C语言的make、gcc,python的setuptools等,根据需要安装即可。
原理
RPM打包的时候需要编译源码,还需要把编译好的配置文件、二进制命令文件之类的东西按照安装好的样子放到合适的位置,还要根据需要对RPM的包进行测试,这些都需要先有一个“工作空间”。rpmbuild命令使用一套标准化的“工作空间”:
生成 rpmbuild 目录
rpmdev-setuptree
rpmdev-setuptree这个命令就是安装rpmdevtools带来的。可以看到运行了这个命令之后,在$HOME家目录下多了一个叫做rpmbuild的文件夹,里边内容如下:
$ tree rpmbuild
rpmbuild
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
如果没有安装rpmdevtools的话,其实用mkdir命令创建这些文件夹也是可以的。
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
从这些文件的名字大体也能看得出来都是干嘛用的。具体来说:
默认位置 | 宏代码 | 名 称 | 用途 |
---|---|---|---|
~/rpmbuild/SPECS | %_specdir | Spec 文件目录 | 保存 RPM 包配置(.spec)文件 |
~/rpmbuild/SOURCES | %_sourcedir | 源代码目录 | 保存源码包(如 .tar 包)和所有 patch 补丁 |
~/rpmbuild/BUILD | %_builddir | 构建目录 | 源码包被解压至此,并在该目录的子目录完成编译 |
~/rpmbuild/BUILDROOT | %_buildrootdir | 最终安装目录 | 保存 %install 阶段安装的文件 |
~/rpmbuild/RPMS | %_rpmdir | 标准 RPM 包目录 | 生成/保存二进制 RPM 包 |
~/rpmbuild/SRPMS | %_srcrpmdir | 源代码 RPM 包目录 | 生成/保存源码 RPM 包(SRPM) |
说明
SPEC关键字
**Name: **软件包的名称,后面可使用%{name}的方式引用
**Summary: **软件包的内容概要
**Version: **软件的实际版本号,例如:1.0.1等,后面可使用%{version}引用
Release: 发布序列号,例如:1linuxing等,标明第几次打包,后面可使用%{release}引用
**Group: **软件分组,建议使用标准分组
**License: **软件授权方式,通常就是GPL
**Source: **源代码包,可以带多个用Source1、Source2等源,后面也可以用%{source1}、%{source2}引用
**BuildRoot: **这个是安装或编译时使用的“虚拟目录”,考虑到多用户的环境,一般定义为:%{tmppath}/{name}-%{version}-%{release}-root或%{tmppath}/%{name}-%{version}-%{release}-buildroot-%%__id_u} -n}.该参数非常重要,因为在生成rpm的过程中,执行make install时就会把软件安装到上述的路径中,在打包的时候,同样依赖“虚拟目录”为“根目录”进行操作。后面可使用$RPM_BUILD_ROOT 方式引用。
**URL: **软件的主页
**Vendor: **发行商或打包组织的信息,例如RedFlag Co,Ltd
**Disstribution: **发行版标识
**Patch: **补丁源码,可使用Patch1、Patch2等标识多个补丁,使用%patch0或%{patch0}引用
**Prefix: **%{_prefix} 这个主要是为了解决今后安装rpm包时,并不一定把软件安装到rpm中打包的目录的情况。这样,必须在这里定义该标识,并在编写%install脚本的时候引用,才能实现rpm安装时重新指定位置的功能
**Prefix: **%{sysconfdir} 这个原因和上面的一样,但由于%{prefix}指/usr,而对于其他的文件,例如/etc下的配置文件,则需要用%{_sysconfdir}标识
Build Arch: 指编译的目标处理器架构,noarch标识不指定,但通常都是以/usr/lib/rpm/marcros
中的内容为默认值
Requires: 该rpm包所依赖的软件包名称,可以用>=或<=表示大于或小于某一特定版本,例如:libpng-devel >= 1.0.20 zlib ※“>=”号两边需用空格隔开,而不同软件名称也用空格分开,还有例如PreReq、Requires(pre)、Requires(post)、Requires(preun)、Requires(postun)、BuildRequires等都是针对不同阶段的依赖指定
BuildRequires 编译时的依赖
**Provides: **指明本软件一些特定的功能,以便其他rpm识别
**Packager: **打包者的信息
**%description **软件的详细说明
SPEC脚本主体
%prep 预处理脚本
%setup %setup -q 解压并cd到相关目录
%setup -n %{name}-%{version}
把源码包解压并放好通常是从/usr/src/asianux/SOURCES里的包解压到/usr/src/asianux/BUILD/%{name}-%{version}中。一般用%setup -c就可以了,但有两种情况:一就是同时编译多个源码包,二就是源码的tar包的名称与解压出来的目录不一致,此时,就需要使用-n参数指定一下了。
**%patch **打补丁通常补丁都会一起在源码tar.gz包中,或放到SOURCES目录下。一般参数为:
%patch -p1 使用前面定义的Patch补丁进行,-p1是忽略patch的第一层目
%Patch2 -p1 -b xxx.patch 打上指定的补丁,-b是指生成备份文件
补充
%setup 不加任何选项,仅将软件包打开。
%setup -n newdir 将软件包解压在newdir目录。
%setup -c 解压缩之前先产生目录。
%setup -b num 将第num个source文件解压缩。
%setup -T 不使用default的解压缩操作。
%setup -T -b 0 将第0个源代码文件解压缩。
%setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。
%patch 最简单的补丁方式,自动指定patch level。
%patch 0 使用第0个补丁文件,相当于%patch ?p 0。
%patch -s 不显示打补丁时的信息。
%patch -T 将所有打补丁时产生的输出文件删除。
%configure 这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置,在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行 ,使用标准写法,会引用/usr/lib/rpm/marcros中定义的参数。另一种不标准的写法是,可参考源码中的参数自定义,例如:
引用CFLAGS=“RPMOPTFLAGS"CXXFLAGS="RPM_OPT_FLAGS" CXXFLAGS="RPMOPTFLAGS"CXXFLAGS="RPM_OPT_FLAGS” ./configure --prefix=%{_prefix}
**%build **开始构建包,在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make的工作
**%install **开始把软件安装到虚拟的根目录中.在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make install的操作。这个很重要,因为如果这里的路径不对的话,则下面%file中寻找文件的时候就会失败。 常见内容有:
**%makeinstall **这不是关键字,而是rpm定义的标准宏命令。也可以使用非标准写法:make DESTDIR=RPMBUILDROOTinstall或引用makeprefix=RPM_BUILD_ROOT install或引用make prefix=RPMBUILDROOTinstall或引用makeprefix=RPM_BUILD_ROOT install
需要说明的是,这里的%install主要就是为了后面的%file服务的。所以,还可以使用常规的系统命令:引用install -d $RPM_BUILD_ROOT/和cp -a * $RPM_BUILD_ROOT/
%clean 清理临时文件
%pre rpm安装前执行的脚本
%post rpm安装后执行的脚本
%preun rpm卸载前执行的脚本
%postun rpm卸载后执行的脚本
%files 定义那些文件或目录会放入rpm中
**%defattr (-,root,root) **指定包装文件的属性,分别是(mode,owner,group),-表示默认值,对文本文件是0644,可执行文件是0755
%defattr 用于设置默认文件权限,通常可以在 %files 的开头看到它。注意,如果不需要修改权限,则不需要使用它。其格式为:
%defattr(<文件权限>, <用户>, <用户组>, <目录权限>)
**%changelog ** 变更日志,标签应包含每个 Release 所做的更改日志,尤其应包含上游的安全/漏洞补丁的说明。Changelog 日志可使用 rpm --changelog -q 查询,通过查询可得知已安装的软件是否包含指定漏洞和安全补丁。%changelog 条应包含版本字符串,以避免 rpmlint 工具警告。
命令及工具
rpmbuild打包
一旦 SPEC 编写完毕,请执行以下命令来构建 SRPM 和 RPM 包:
rpmbuild -ba program.spec
如果成功,RPM 会保存至 ~/rpmbuild/RPMS,SRPM 会保存至 ~/rpmbuild/SRPMS。
如果失败,请查看 BUILD 目录的相应编译日志。为了帮助调试,可以用 --short-circuit 选项来忽略成功的阶段。例如,若想要(略过更早的阶段)重新从 %install 阶段开始,请执行:
rpmbuild -bi --short-circuit program.spec
如果只想创建 RPM,请执行:
rpmbuild -bb program.spec
如果只想创建 SRPM(不需要执行 %prep 或 %build 或其他阶段),请执行:
rpmbuild -bs program.spec
rpmlint检查
为避免常见错误,请先使用 rpmlint 查找 SPEC 文件的错误:
rpmlint program.spec
如果返回错误/警告,使用 “-i” 选项查看更详细的信息。
也可以使用 rpmlint 测试已构建的 RPM 包,检查 SPEC/RPM/SRPM 是否存在错误。你需要在发布软件包之前,解决这些警告。此页面 提供一些常见问题的解释。如果你位于 SPEC 目录中,请执行:
rpmlint NAME.spec …/RPMS//NAME.rpm …/SRPMS/NAME*.rpm
进入 ~/rpmbuild/RPMS 下的特定架构目录中,您会发现有许多二进制 RPM 包。使用以下命令快速查看 RPM 包含的文件和权限:
rpmls *.rpm
rpm安装
如果看上去正常,以 root 身份安装它们:
rpm -ivp package1.rpm package2.rpm package3.rpm …
以不同方式来测试程序,看看是否全部都正常工作。如果是 GUI 工具,请确认其是否出现在桌面菜单中,否则表示 .desktop 条目可能有错。
最后卸载软件包:
rpm -e package1 package2 package3
附录
rpmbuild目录
默认位置 | 宏代码 | 名称 | 用途 |
---|---|---|---|
~/rpmbuild/SPECS | %_specdir | Spec 文件目录 | 保存 RPM 包配置(.spec)文件 |
~/rpmbuild/SOURCES | %_sourcedir | 源代码目录 | 保存源码包(如 .tar 包)和所有 patch 补丁 |
~/rpmbuild/BUILD | %_builddir | 构建目录 | 源码包被解压至此, |
~/rpmbuild/BUILDROOT | %_buildrootdir | 最终安装目录 | 保存 %install 阶段安装的文件 |
~/rpmbuild/RPMS | %_rpmdir | 标准 RPM 包目录 | 生成/保存二进制 RPM 包 |
~/rpmbuild/SRPMS | %_srcrpmdir | 源代码 RPM 包目录 | 生成/保存源码 RPM 包(SRP |
spec文件阶段
阶段 | 读取的目录 | 写入的目录 | 具体动作 |
---|---|---|---|
%prep | %_sourcedir | %_builddir | 读取位于 %_sourcedir 目录的源代码和 patch 。之后,解压源代码至 %_builddir 的子目录并应用所有 patch。 |
%build | %_builddir | %_builddir | 编译位于 %_builddir 构建目录下的文件。通过执行类似 ./configure && make 的命令实现。 |
%install | %_builddir | %_buildrootdir | 读取位于 %_builddir 构建目录下的文件并将其安装至 %_buildrootdir 目录。这些文件就是用户安装 RPM 后,最终得到的文件。注意一个奇怪的地方: 最终安装目录 不是 构建目录。通过执行类似 make install 的命令实现。 |
%check | %_builddir | %_builddir | 检查软件是否正常运行。通过执行类似 make test 的命令实现。很多软件包都不需要此步。 |
bin | %_buildrootdir | %_rpmdir | 读取位于 %_buildrootdir 最终安装目录下的文件,以便最终在 %_rpmdir 目录下创建 RPM 包。在该目录下,不同架构的 RPM 包会分别保存至不同子目录, noarch 目录保存适用于所有架构的 RPM 包。这些 RPM 文件就是用户最终安装的 RPM 包。 |
src | %_sourcedir | %_srcrpmdir | 创建源码 RPM 包(简称 SRPM,以.src.rpm 作为后缀名),并保存至 %_srcrpmdir 目录。SRPM 包通常用于审核和升级软件包。 |
file代表路径的宏列表
%{_sysconfdir} /etc
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} /var/lib
%{_datarootdir} %{_prefix}/share
%{_datadir} %{_datarootdir}
%{_includedir} %{_prefix}/include
%{_infodir} /usr/share/info
%{_mandir} /usr/share/man
%{_localstatedir} /var
%{_initddir} %{_sysconfdir}/rc.d/init.d
%{_var} /var
%{_tmppath} %{_var}/tmp
%{_usr} /usr
%{_usrsrc} %{_usr}/src
%{_lib} lib (lib64 on 64bit multilib systems)
%{_docdir} %{_datadir}/doc
%{buildroot} %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
$RPM_BUILD_ROOT %{buildroot}
RPM打包原理spec相关推荐
- RPM打包原理、示例、详解及备查
原文地址:https://blog.csdn.net/qq_16542775/article/details/80961213 RPM(Redhat Package Manager)是用于Redhat ...
- RPM打包与SPEC文件
制作RPM软件包并不是一件复杂的工作,其中的关键在于编写SPEC软件包描述文件.要想制作一个rpm软件包就必须写一个软件包描述文件(SPEC). 这个文件中包含了软件包的诸多信息,如软件包的名字.版本 ...
- RPM打包之spec示例
示例来源于rpmbuild官网:https://rpmbuildtut.wordpress.com/development-packages/ vpython 的一个依赖包,gtkglarea,的sp ...
- [RPM打包学习-SPEC文件]——%patch相关问题
今天在软件包编译时,需要给其制作patch修改部分问题.根据相关diff指令制作patch,并在本地使用patch命令验证均成功,下面实战进入spec编写. 将相关SOURCE放入指定目录,根据以往经 ...
- RPM安装包-Spec文件參数具体解释与演示样例分析
spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件. 1.Spec文件參数 spec文件包括建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个 ...
- 用 RPM 打包软件,第 2 部分
在不具备 root 权限的情况下构建.给软件打补丁和分发 RPM RPM 是一种广泛用于发布 Linux 软件的工具: 用户可以轻松地安装用 RPM 打包的产品.在本文(该系列文章的第 2 篇)中,D ...
- 使用RPM打包QT程序
本文章只是一个RPM打包的一个小例子,仅适合初学者参考! 先说一下使用RPM打包的步骤: 一.首先将写好的内容使用tar压缩成.tar.gz格式 二.创建所需的目录并配置rpm打包目录 使用rpm打包 ...
- rpm打包的流程包括以下哪些_Linux下RPM打包流程分享
本文主要和大家分享Linux下RPM打包流程,希望能帮助到大家. 开始前的准备 安装rpmbuild软件包yum -y install rpm-build 生成相关目录 要生成rpm相关目录,可以手动 ...
- RPM打包探索(rpm-max翻译整理)
1. %global 和 %define 的区别? 这是内置宏,%define用来定义宏,%global用来定义一个全局可见的宏(在整个spec文件中可见) 2. %{!?macro-name} 和 ...
最新文章
- fflush(stdin)和fflush(stdout)和rewind(stdin)的区别和作用
- sublime python3中读取和写入文件时如何解决编码问题
- 业务系统设计之一:系统菜单设计
- okgo 缓存html,okhttp-OkGo OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 RxJava,比 Retro @codeKK Android开源站...
- Tornado報錯AttributeError: Unrecognized option 'port'
- 洛谷P3392 涂国旗
- think in python 第二版_译林版牛津高中英语,模块词组二
- error: The following untracked working tree files would be overwritten by merge:
- 序列化(写对象)与反序列化(读对象)
- 翻翻git之---实用工具类Lazy(绝对的好东西,走过路过别错过)
- 【css】css实现图片或动图边缘模糊化处理(附示例代码)
- 陈莉君教授: 回望踏入Linux内核之旅(上篇)
- cocoscreator中tween详细用法
- MATLAB凸优化工具箱CVX用户手册-Chapter5
- linux上mysql初次运行的报错
- 小米手机深陷“返修门” 售后成软肋
- IntelliJ IDEA 2018.3 安装、永久破解及新特性说明
- 基于 Electron + ES6 实现的桌面计算器应用
- eslint prettier husky代码规范配置
- 输入半径计算圆的周长和面积
热门文章
- ubuntu16.04下安装GVIM,亲测可用
- can not cast to JSONObject,HTTPClient项目间服务调用时踩的一个大坑
- Mysql数据库基本操作(七)多表查询-子查询,表自身关联查询
- 华硕笔记本 点击Splendid Utility没反应
- 建网站,做网站,更有多种自定制网站建设套餐供您选择!用建站宝盒自助建站软件,免费智能建站系统,......
- R语言兵器谱:数据科学家的十八般武艺
- LECTROETCH FORMULA LNC-3 0.93L
- 触摸膜的应用及市场分析
- input 正则校验
- 怎样快速制作婚礼视频