Maximum RPM读书纪要第十章 构建RPM包的一个简单例子

http://www.jsxubar.info/maximum-rpm-chapter10-example.html

Maximum RPM读书纪要第十章 构建RPM包的一个简单例子

jsxubar 5星推荐 / 最后更新: 2012年06月28日  ⁄ RPM运维 ⁄ 共 6714字 ⁄ 评论数 1 ⁄ 被围观 202 views+
1 Star 2 Stars 3 Stars 4 Stars 5 Stars ( 1 votes, average:  5.00 out of  5)

在学习了Maximum RPM读书纪要》第九章 RPM开发基础,知道spec文件需要包含的内容之后,我们学习第十章先构建一个简单的RPM包,然后再逐步深入RPM打包的spec文件编写.

第十章  构建包的一个简单例子

10.1 创建构建目录

默认目录位于/usr/src/redhat,包含以下子目录:

  • SOURCE
  • SPECS
  • BUID
  • RPMS:其中RPMS内会有两个子文件夹,一个与构建包的主机的系统架构相同的目录,如x86_64,另一个是noarch.
  • SRPMS

10.2 将源码压缩文件放入SOURCE目录下

10.3 创建spec文件,spec文件放在SPECS目录下

spec文件中可以包含以下内容:

  • 注释:以#号开头的行都是注释
  • tags:定义数据,可以使用rpm --querytags查看所有的tag.
  • 脚本:包含在特定时间执行的命令
  • 宏:包含两个宏:%setup和%patch,都只能用于%prep部分
  • 文件列表:包含在包中的文件的列表
  • 指示:对于文件列表中的文件,可以指定指示
  • 条件语句:通常用于执行与系统架构和操作系统相关的问题,不同的类型执行不同的操作
序言部分(the preamble)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Summary: A CD player app that rocks!
  #Name tag中不能包含空格,如Name:cd player,将只识别为cd,后面部分忽略
Name: cdplayer
  #Version tag中不能包含”-“符号,不能包含空格,处理方法与Name tag类似
Version: 1.0
  #Release tag中不能包含”-“符号
Release: 1
Copyright: GPL
  #Group tag的定义在/usr/share/doc/rpm-4.4.2.3/GROUPS文件中
Group: Applications/Sound
  #Source tag中表示软件来源,最后部分表示源码的文件名
  #该文件名必须与SOURCE目录对应源码文件相同.
Source: ftp://ftp.gnomovision.com/pub/cdplayer/cdplayer-1.0.tar.gz
URL: http://www.gnomovision.com/cdplayer/cdplayer.html
  #Distribution tag表示该软件包属于哪个组
Distribution: WSS Linux
  #Vendor tag表示发行人,发行机构,供应商
Vendor: White Socks Software, Inc.
  #Packager tag表示打包的人,一般会提供一个email地址
Packager: Santa Claus <sclaus@northpole.com>
  #包建立者必须给包加上合适的依赖性信息
  #依赖性信息包括提供什么(provides),需要什么(requires)和与什么冲突(conflicts).
  #一般包括两方面的信息,共享库和软件信息,共享库信息可以使用
  #rpmbuild命令自动完成,该功能默认开启,如果不需要,则使用autoreqprov tag
  #可以控制这个功能,在序言部分加入autoreqprov:no即可.软件信息也包含两种:
  #虚拟包和一般包,虚拟包一般是软件的某项功能,在指定依赖性信息时无版本信息
  #一般软件可以使用>,>=,=.<=,<指定版本要求,版本值可以使用Version中指定的数值
  #和serial定义的值,serial一般用于版本字段太复杂,rpmbuild命令无法比较时.
  #每个版本必须对应唯一的serial值,且随版本递增.
Provides:cdplayer
Requires:cdbasic >= %{Version}-%{Release}
Requires:cdreader =S 5
conflicts:playmidi = 2.3-1
  #系统架构与操作系统相关tag
  #包括: EXCLUDEARCH, EXCLUDEOS, EXCLUSIVEARCH, EXCLUSIVEOS
  #前两者表示在指定的架构和系统下不能构建软件包
  #后两者表示只能在指定的架架和系统下构建软件包
  #目录相关tag
  #prefix tag用于构建可重定向软件.当定义了这个值之后,文件列表需做相应调整
  #如Prefix: /opt,则文件列表部分可能为/opt/bin/cdplayer
  #BuildRoot tag只与构建软件时的安装部分有关,对文件列表不会有任何影响
  #除了在这个部分进行定义后,还需要在安装时
  #使用make DESTDIR=$RPM_BUILD_ROOT install才会生效
%description
It slices! It dices! It’s a CD player app thatcan’t be beat. By using the resonant frequency of the CD itself, it is able to simulate 20X oversampling.

以上都是tag,一般在spec最前面定义.tag名称大小写不敏感,但养成好的习惯,最好以大写字母开头,后接小写字母,然后加上”:”,再是tag内容,”:”前后可以加空格.

序言部分必须包含Summary,Name,Version,Release,Group,Source 等tag,其中description以%开头,全部字母小写,可以跨越多行,因此序言部分的其它tag放在%description前面.

  • 补丁相关内容

补丁的制作首先在SOURCE目录中解压源码压缩包,以cdplayer-1.0.tar.gz为例.解压出来的目录为cdplayer-1.0,将此目录重命令为cdplayer-1.0-orig,再解压源码压缩包,然后对cdplayer-1.0目录内文件进行必要的修改,

运行diff -uNr cdplayer-1.0-orig/ cdplayer-1.0/ >cdplayer-1.0.linux.patch产生补丁文件.补丁文件一般放置于源码压缩文件的顶层目录中.因此可以将此patch放入cdplayer-1.0-orig目录中,然后将原来源代码压缩文件和cdplayer-1.0目录都删除,将cdplayer-1.0-orig改为cdplayer-1.0,重新生成源代码压缩包.

  • 补丁的使用

首先需要在序言部分定义patch,然后在%prep中应用此patch.patch可以定义多个,如:

1
2
Patch0:cdplayer-1.0.linux.patch
Patch1: cdplayer-1.0.unix.patch

 注意Patch:cdplayer-1.0.linux.patch与Patch0:cdplayer-1.0.linux.patch相同

patch命令的-pn参数表示省去patch文件内文件的前n个”/”,因此我们的patch文件放在cdplayer-1.0目录内,使用类似宏%patch1 -p1来应用补丁,省去第一层cdplayer-1.0.-b <file>参数表示会备份原文件,将备份文件的扩展名改成<file>,因此<file>一般以点号开头.%patch -p1 -P 4 -b .bak表示应用第四个补丁,且将原文件备份,备份名字为原文件名.bak.-s选项表示静默模式,只显示错误.

 source tag的定义方法与patch的定义方法类似,可以使用宏%setup来操作source.

预备,编译,安装和清理部分使用共享的环境.

 预备部分(prep section)

一般即是解压和打补丁,这里提供了两个宏,%setup和%patch.内容可能如下:

1
2
%prep
%setup -q

%setup一般会被扩展成以下命令:(注意并不是完全这样,但不影响我们的理解)

1
2
3
4
5
6
7
8
9
cd /usr/src/redhat/BUILD
rm -rf cdplayer-1.0
gzip - dc /usr/src/redhat/SOURCES/cdplayer-1 .0.tgz | tar -xvvf -
if [ $? - ne 0 ]; then
     exit $?
      fi
cd cdplayer-1.0
chown -R root.root .
/bin/chmod -Rf a+rX,u+w,g-w,o-w .

         %setup有一些选项可以利用:

1.-q,静默模式,尽量少的输出

2.-n <name>,设置BUILD目录下的解压目录.RPM默认解压后的目录名为<name>-<version>,但有些软件不是这样时,就有必要设置-n选项.设置之后,会说表中第2,5行改成相应的值.请小心使用这个选项,因为如果-n选项设置的目录名称如果与解压出来的目录名称不一致的话将会停止构建.

3.-c选项设置在解压前先创建目录,进入该目录,再进行解压.效果等于在第2,3行之间加入:

1
2
mkdir -p cdplayer-1.0
cd cdplayer-1.0

4.-D解压源代码之前并不删除目录,等于将表中第2行去掉

5.-T不进行默认的解压操作,等于将表中第3,4行去掉

6.-b <n>表示在切换目录前解压第N个源代码,效果等于在第五行之前加入另一个解压操作,常与-T配合,解压特定的源代码.

7.-a <n>表示在切换目录后解压第N个源代码

编译部分(build section)

一般就是configure命令和make命令,如:

1
2
3
%build
./configure
make
安装部分(install section)

一般就是make install命令,如:

1
2
%install
make install

如果在序言部分加入了BuildRoot定义,一般定义为BuildRoot:%{_tmppath}/%{name}-%{version}-%{release}-root,则可以在此使用BuildRoot来将软件安装在以这个目录为根目录的路径下,而不是安装在实际系统中.进行如下改写:

1
2
3
4
%install
rm -rf ${RPM_BUILD_ROOT}
mkdir ${RPM_BUILD_ROOT}
make DESTDIR=$RPM_BUILD_ROOT install
文件列表部分

如何创建文件列表,一般使用BuildRoot方式来进行创建,将文件安装在一个相对根路径下,而该路径下只有该软件的文件,所以很容易就可以获得文件列表.
文件列表中可以包含目录的路径,rpmbuild将会自动打包该目录的所有文件和子目录.shell风格的通配符也可以在文件列表中使用.
文件指示的作用:标识文档和配置文件,其中man目录中的文件自动识别为文档,不需标识.确保每个文件有正确的权限值和所有值.控制在包验证过程中文件将被检查的方面.
先看以下例子:

1
2
3
4
5
6
%files
%doc README
%doc doc/INSTALL
/usr/local/bin/cdp
/usr/local/bin/cdplay
/usr/local/man/man1/cdp.1

每个文件占据一行,文件可以有多个指示.
第二行中,README前面包含%doc指示,表示这是文档,但并未指定绝对路径,表示README放在源代码的顶层目录中,且在安装后将放置在变量_defaultdocdir(使用rpmbuild --showrc |grep doc查看)所定义的目录下所软件名称所对应的目录下.
其它行都包含绝对路径,必须以/开头, rpmbuild命令寻找这些文件,并进行打包,以后安装rpm包时也会将文件安装在相同路径.
%config指示表示该文件是配置文件.
%attr指示用来表示权根值,格式为:%attr(<mode>,<user>,<group>) file,如:
%attr(755,root,root)  foo.bar
user和group不能使用数字值,可以使用-来代替, <mode>值也可以使用”-“来代替.
%verify指示包含9个属性
%verify([not] owner group mode md5 size maj min symlink mtime) file
上一行中,在括号中的项在运行rpm的验证命令时都将检查,而如果加上not,而表示括号中的项都不检查.
%docdir用于标识该文件夹下的文件均为文档,且子目录下包含的也都是文档.注意该标识并不会让rpmbuild将该文件夹下的文件打包,还需要另外声明.如:
%docdir /usr/blather
/usr/blather
%dir指示表示只打包该目录本身.
-f <file>表示从文件中读取文件列表,文件内文件列表的格式与spec文件中的相同.通常用于某些文件名称需要在运行时才确定,这时可以使用sed命令来更新文件列表内容.

安装/卸载脚本

包含以下四个脚本:%pre,%post.%preun,%postun
这四个脚本只有一个环境变量可以使用,那就是RPM_INSTALL_PREFIX,这个变量只有在包使用了安装前缀的时候才会被设置.
%post脚本一般在进行一个新安装后运行ldconfig命令来更新共享库.如果一个包使用了%post脚本来执行某些功能,通常它也会包含一个在卸载后使用的%postun脚本来执行与%post脚本相反的功能.

1
%verifyscript

#这个脚本在执行RPM的验证命令时使用.
清除脚本(%clean部分)
如果定义了BuildRoot,则可能需要清除BuildRoot的内容

1
rm -rf ${RPM_BUILD_ROOT}

10.4 开始构建

1
2
cd /usr/src/redhat/SPECS
rpmbuild -ba cdplayer-1.0.spec

现在我们来看一个rpmbuild命令参数:

  • -b<stage>和-t<stage>
  • -b指定spec文件,-t指定tar文件,而rpmbuild会在tar文件中查找spec来使用.
  • -p表示只执行预备部分,-c表示执行预备和编译部分,-i表示执行预备,编译和安装部分,-l表示进行文件列表检查,-b表示执行预备,编译,安装和产生二进制包,-a表示执行所有步骤,即预备,编译,安装和产生二进制包和源码包,-s表示只构建源码包
  • --rebuild和--recompile以源码包为操作对象
  • --recompile依次进行安装源码包,解压源码,编译软件,安装软件,移除软件构建目录,当构建完成后,只留下新安装的软件和源码包.--recompile通常用于之前安装的软件包需要重新编译时.当使用--recompile时,RPM数据库并不会更新,这可能会导致问题的产生.
  • --rebuild比--recompile多一个操作,即产生二进制包,会留下二进制包,源码包,和安装的软件.
  • rpmbuild --showrc用于显示参数,变量定义.
  • --buildroot directory指定buildroot目录,--clean在建包完成后清除编译目录
  • --nobuild表示不执行构建过程,通常用于检查spec文件
  • --rmsource和--rmspec表示构建完成后删除源码和spec文件,也可单独操作,如:
  • rpmbuild --rmsource foo.spec; rpmbuild --rmspec foo.spec;
  • --short--circuit表示直接执行指定的阶段,不执行前面的部分,只与-bc和-bi搭配使用
  • --sign用于加入GPG签名到包中

以下是通用选项

附rpmrc 文件简介

以使用rpmbuild --showrc或rpm --showrc来展示每个值,两个命令的结果是一样的.这些值包括两类:一是与系统和架构相关的值,二是rpmrc值.

RPM在四个地方查找rpmrc文件

  1. /usr/lib/rpm/下的rpmrc文件,
  2. 在/etc/rpm下的rpmrc文件,
  3. 在用户登录目录下的.rpmrc文件,
  4. 使用--rcfile选项指定的文件.

前三个文件是按顺序读入的,如果某一项值在多个文件中进行了设置,则以最后读入的值为准.因此用户登录目录的.rpmrc具有最高优先级.

如果指定了--rcfile选项,则只会读取/usr/lib/rpm下的rpmrc文件和--rcfile指定的文件,且/usr/lib/rpm下的rpmrc文件先读取.

不应该修改/usr/lib/rpm/rpmrc文件./etc/rpm/rpmrc是保存全局值的最好的地方.

rpmrc文件中值的设置格式为:

1
<name>:<value>

其中值部分不区分大小写,引号必须紧跟在<name>后面,不能有空格

Maximum RPM读书纪要附录

原版书籍和读书纪要下载:

读书纪要总索引:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值