RPM制作宝典(3)
作者:雨亦奇 ,赵建利
要想制作RPM格式的软件包,需使用如下命令格式:
rpm-bX[制作选项1制作选项2...]描述文件1描述文件2...
注:-bX可用-tX替换,效果有所不同:使用-b时,需要在命令行上指定软件包描述文件;而使用-t时,在命令行上需要指定的不是软件包描述文件,而是含有此描述文件的TAR格式的包裹文件(必须用gzip压缩),RPM在准备制作软件包时,会自动从此包裹文件中提取描述文件,根据其中的建包指令,生成RPM格式的软件包。注意:此描述文件必须以.spec为后缀,其中必须有Source域,并且此域定义的源程序包必须存放在当前目录下,否则的话,RPM将报错退出。
注意,-bX与-tX当中的X,取不同的值时,RPM将执行不同的操作:(下面各个例子均对LZE的描述文件lze-6.0-2.spec进行操作,有的则通过管道技术,用nl命令给输出加上行号,以便解释)
1)X=p时,指示RPM执行描述文件中的预处理段(%prep)的脚本程序。该脚本程序一般用来解压源程序包,并且为源程序打补丁,升级源程序。
#rpm-bplze-6.0-2.spec2>&1|nl
1Executing:%prep
2+umask022
3+cd/usr/src/dist/BUILD
4+echo'预处理脚本程序(prep)开始执行'
5预处理脚本程序(prep)开始执行
6+cd/usr/src/dist/BUILD
7+rm-rflze-6.0
8+/bin/gzip-dc/usr/src/dist/SOURCES/lze-6.0-2.src.tgz
9+tar-xvvf-
10drwxr-xr-xroot/root02001-11-0216:02lze-6.0/
11-rw-------root/root2462262001-11-0216:00lze-6.0/lze.c
12-rw-------root/root982492001-11-0216:00lze-6.0/lzeime.wb.c
13-rw-------root/root3399022001-11-0216:00lze-6.0/lzeime.py.c
14-rw-r--r--root/root12832001-11-0216:00lze-6.0/funkey.def
15-rwxr--r--root/root2502001-11-0216:00lze-6.0/inputme.def
16-rw-r--r--root/root8132742001-11-0216:00lze-6.0/wbzc.dat
17-rw-------root/root4742001-11-0216:02lze-6.0/makefile
18+STATUS=0
19+'['0-ne0']'
20+cdlze-6.0
21++/usr/bin/id-u
22+'['0=0']'
23+/bin/chown-Rhfroot.
24++/usr/bin/id-u
25+'['0=0']'
26+/bin/chgrp-Rhfroot.
27+/bin/chmod-Rfa+rX,g-w,o-w.
28+exit0
#
注:本例中第1行显示的"Executing:%prep"表明RPM开始执行预处理段的脚本程序。例中行号后那些以加号(+)开始的行均为预处理段脚本程序的指令,其它内容则为指令执行所输出的结果。从预处理段脚本程序所执行的指令,我们就可以看出RPM正在做什么:
第2行:设置文件创建掩码;
第3行:转到RPM默认的编译目录;
第4行:回显字符串,这才是用户所写的预处理段脚本程序的开始,第2,3行均是RPM增加的指令;
第6-27行:为%setup所扩展出来的指令及其执行结果,其中可以看到RPM用gzip命令解压LZE的源程序包(第8行),而后用tar命令展开源程序包(第9行)。
第28行:正常退出,返回值为0。
2)X=l时,指示RPM检查文件段(%files),看其中的文件是否存在。如果不存在,则RPM会报错退出。
#rpm-bl-vvlze-6.0-2.spec|nl
1Processingfiles:lze
2D:File0:0100644root.root/etc/funkey.def
3D:File1:0100644root.root/etc/inputme.def
4D:File2:0100644root.root/usr/doc/lze-6.0-2/README
5Filenotfound:/usr/doc/lze-6.0-2/LICENSE
6D:File3:0100555root.root/usr/bin/lze
7D:File4:0100511root.root/usr/bin/lzeime.py
8D:File5:0100511root.root/usr/bin/lzeime.wb
9D:File6:0100644root.root/etc/wbzc.dat
10Provides:lze-edit
11PreReq:/bin/sh
12Requires:/bin/sh
#
注:本例命令中使用了通用选项-vv,以输出RPM检查时的调试信息(以行号和D:开始的行)。
由上看出,RPM对文件段的所有文件逐一进行检查,找到的文件显示其权限,属主和属组信息,结果发现/usr/doc/lze-6.0-2.LICENSE文件不存在,于是报出错误(File not found)(见第5行)。RPM在检查过文件后,还显示出描述文件要求LZE提供的功能(Provides)和所需的功能(Requires)。
3)当X=c时,指示RPM依次执行预处理段(%prep),编译段(%build)的脚本程序。编译段的脚本程序用来编译连接软件的源程序,生成可执行程序,通常一个make命令足够。因为一个有良好习惯的程序员会把Makefile(程序维护文件)写好,以便其它程序员编译该软件。如果某个软件没有维护文件的话,用户要么自己写个Makefile,要么在编译段里写上软件编译与连接的各项命令。
4)当X=i时,指示RPM依次执行预处理段(%prep),编译段(%build)和安装段(%install)的脚本程序。安装段的脚本程序的任务是将编译连接好的执行程序拷贝到适当的目录(如/bin,/usr/bin等公共执行目录),以便打包或执行。它通常执行的指令是make install。
5)当X=b时,指示RPM依次执行预处理段(%prep),编译段(%build),安装段(%install)的脚本程序,之后根据文件段(%files)的文件列表,将文件打包,生成RPM执行程序包,最后执行清理段(%clean)。
#rpm-bblze-6.0-2.spec2>&1|nl
1Executing:%prep
2+umask022
3+cd/usr/src/dist/BUILD
4+echo'预处理脚本程序(prep)开始执行'
5预处理脚本程序(prep)开始执行
6+cd/usr/src/dist/BUILD
7+rm-rflze-6.0
8+tar-xvvf-
9+/bin/gzip-dc/usr/src/dist/SOURCES/lze-6.0-2.src.tgz
10drwxr-xr-xroot/root02001-11-0217:04lze-6.0/
11-rw-------root/root2462262001-11-0216:00lze-6.0/lze.c
12-rw-------root/root982492001-11-0216:00lze-6.0/lzeime.wb.c
13-rw-------root/root3399022001-11-0216:00lze-6.0/lzeime.py.c
14-rw-r--r--root/root12832001-11-0216:00lze-6.0/funkey.def
15-rwxr--r--root/root2502001-11-0216:00lze-6.0/inputme.def
16-rw-r--r--root/root8132742001-11-0216:00lze-6.0/wbzc.dat
17-rw-------root/root4742001-11-0216:02lze-6.0/makefile
18-rw-r--r--root/root12552001-11-0217:04lze-6.0/getinputme.c
19+STATUS=0
20+'['0-ne0']'
21+cdlze-6.0
22++/usr/bin/id-u
23+'['0=0']'
24+/bin/chown-Rhfroot.
25++/usr/bin/id-u
26+'['0=0']'
27+/bin/chgrp-Rhfroot.
28+/bin/chmod-Rfa+rX,g-w,o-w.
29+exit0
30Executing:%build
31+umask022
32+cd/usr/src/dist/BUILD
33+cdlze-6.0
34+echo'编译连接脚本程序(build)开始执行'
35编译连接脚本程序(build)开始执行
36+make
37cc-fwritable-strings-DUSE_AS_LZE-DFOR_LINUX-s-I/usr/zzz/src/include-DFOR_LZE_INPUTME-olze/usr/zzz/src/li-
38bsrc/mycurses.clze.cgetinputme.c/usr/zzz/src/my.a
39cc-DFOR_LINUX-s-I/usr/zzz/src/include-olzeime.wbgetinputme.clzeime.wb.c/usr/zzz/src/my.a
40lzeime.wb.c:Infunction`do_service':
41lzeime.wb.c:1409:warning:passingarg5of`bsearch'fromincompatiblepointertype
42cc-DFOR_LINUX-s-I/usr/zzz/src/include-olzeime.pygetinputme.clzeime.py.c/usr/zzz/src/my.a
43+exit0
44Executing:%install
45+umask022
46+cd/usr/src/dist/BUILD
47+cdlze-6.0
48+echo'安装脚本程序(install)开始执行'
49安装脚本程序(install)开始执行
50+makeinstall
51installing...
52done
53+exit0
54Processingfiles:lze
55FindingProvides:(using/usr/lib/rpm/find-provides)...
56FindingRequires:(using/usr/lib/rpm/find-requires)...
57Provides:lze-edit
58PreReq:/bin/sh
59Requires:/bin/shld-linux.so.2libc.so.6libc.so.6(GLIBC_2.0)libc.so.6(GLIBC_2.1)
60Wrote:/usr/src/dist/RPMS/i386/lze-6.0-2.i386.rpm
61Executing:%clean
62+umask022
63+cd/usr/src/dist/BUILD
64+cdlze-6.0
65+echo'建包结束后清理脚本程序(clean)开始执行'
66建包结束后清理脚本程序(clean)开始执行
67+exit0
#
注:本例中,各行解释如下:
第1行:显示RPM开始执行预处理段(%prep);
第2-29行:为预处理段(%prep)脚本程序执行的命令与结果,命令前有加号(+),结果前面则没有。预处理完成了LZE源程序包的解压缩(gzip-dc)与包的展开(tar-xvvf),从而为源程序的编译打下了基础;
第30行:RPM表示开始执行编译段(%build);
第31-43行:为编译段(%build)脚本程序执行的命令与结果。脚本程序执行的make维护命令,该命令执行了cc编译程序,以编译与连接LZE软件;
第44行:RPM表示开始执行安装段(%install);
第45-53行:为安装段(%install)脚本程序执行的命令与结果。本段程序执行了makeinstall命令,将LZE的执行程序等文件拷贝到系统目录下;
第54行:RPM显示:开始处理LZE的文件(为%files文件段的内容);
第55-59行:RPM利用/usr/lib/rpm/find-provides程序查找LZE提供的功能,又利用/usr/lib/rpm/find-requires查找LZE所依赖的功能,以设定LZE的依赖关系;
第60行:制作完成LZE执行程序包,文件名为lze-6.0-2.i386.rpm,在/usr/src/dist/RPMS/i386目录下;
第61行:RPM显示:开始执行清理段(%clean)脚本程序,本段程序用于清理临时文件;
第62-67行:为清理段(%clean)脚本程序执行的命令与