概述

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="RPMO​PTF​LAGS"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=RPMB​UILDR​OOTinstall或引用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相关推荐

  1. RPM打包原理、示例、详解及备查

    原文地址:https://blog.csdn.net/qq_16542775/article/details/80961213 RPM(Redhat Package Manager)是用于Redhat ...

  2. RPM打包与SPEC文件

    制作RPM软件包并不是一件复杂的工作,其中的关键在于编写SPEC软件包描述文件.要想制作一个rpm软件包就必须写一个软件包描述文件(SPEC). 这个文件中包含了软件包的诸多信息,如软件包的名字.版本 ...

  3. RPM打包之spec示例

    示例来源于rpmbuild官网:https://rpmbuildtut.wordpress.com/development-packages/ vpython 的一个依赖包,gtkglarea,的sp ...

  4. [RPM打包学习-SPEC文件]——%patch相关问题

    今天在软件包编译时,需要给其制作patch修改部分问题.根据相关diff指令制作patch,并在本地使用patch命令验证均成功,下面实战进入spec编写. 将相关SOURCE放入指定目录,根据以往经 ...

  5. RPM安装包-Spec文件參数具体解释与演示样例分析

    spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件. 1.Spec文件參数 spec文件包括建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个 ...

  6. 用 RPM 打包软件,第 2 部分

    在不具备 root 权限的情况下构建.给软件打补丁和分发 RPM RPM 是一种广泛用于发布 Linux 软件的工具: 用户可以轻松地安装用 RPM 打包的产品.在本文(该系列文章的第 2 篇)中,D ...

  7. 使用RPM打包QT程序

    本文章只是一个RPM打包的一个小例子,仅适合初学者参考! 先说一下使用RPM打包的步骤: 一.首先将写好的内容使用tar压缩成.tar.gz格式 二.创建所需的目录并配置rpm打包目录 使用rpm打包 ...

  8. rpm打包的流程包括以下哪些_Linux下RPM打包流程分享

    本文主要和大家分享Linux下RPM打包流程,希望能帮助到大家. 开始前的准备 安装rpmbuild软件包yum -y install rpm-build 生成相关目录 要生成rpm相关目录,可以手动 ...

  9. RPM打包探索(rpm-max翻译整理)

    1. %global 和 %define 的区别? 这是内置宏,%define用来定义宏,%global用来定义一个全局可见的宏(在整个spec文件中可见) 2. %{!?macro-name} 和 ...

最新文章

  1. fflush(stdin)和fflush(stdout)和rewind(stdin)的区别和作用
  2. sublime python3中读取和写入文件时如何解决编码问题
  3. 业务系统设计之一:系统菜单设计
  4. okgo 缓存html,okhttp-OkGo OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 RxJava,比 Retro @codeKK Android开源站...
  5. Tornado報錯AttributeError: Unrecognized option 'port'
  6. 洛谷P3392 涂国旗
  7. think in python 第二版_译林版牛津高中英语,模块词组二
  8. error: The following untracked working tree files would be overwritten by merge:
  9. 序列化(写对象)与反序列化(读对象)
  10. 翻翻git之---实用工具类Lazy(绝对的好东西,走过路过别错过)
  11. 【css】css实现图片或动图边缘模糊化处理(附示例代码)
  12. 陈莉君教授: 回望踏入Linux内核之旅(上篇)
  13. cocoscreator中tween详细用法
  14. MATLAB凸优化工具箱CVX用户手册-Chapter5
  15. linux上mysql初次运行的报错
  16. 小米手机深陷“返修门” 售后成软肋
  17. IntelliJ IDEA 2018.3 安装、永久破解及新特性说明
  18. 基于 Electron + ES6 实现的桌面计算器应用
  19. eslint prettier husky代码规范配置
  20. 输入半径计算圆的周长和面积

热门文章

  1. ubuntu16.04下安装GVIM,亲测可用
  2. can not cast to JSONObject,HTTPClient项目间服务调用时踩的一个大坑
  3. Mysql数据库基本操作(七)多表查询-子查询,表自身关联查询
  4. 华硕笔记本 点击Splendid Utility没反应
  5. 建网站,做网站,更有多种自定制网站建设套餐供您选择!用建站宝盒自助建站软件,免费智能建站系统,......
  6. R语言兵器谱:数据科学家的十八般武艺
  7. LECTROETCH FORMULA LNC-3 0.93L
  8. 触摸膜的应用及市场分析
  9. input 正则校验
  10. 怎样快速制作婚礼视频