第二十一章 SRPM 的使用 : rpmbuild

谈完了 RPM 类型的软件之后,再来我们谈一谈包含了 Source code 的 SRPM 该如何使用呢?假如今天我们由网络上面下载了一个 SRPM 的文件,该如何安装他?又,如果我想要修改这个 SRPM 里面原始码的相关配置值,又该如何订正与重新编译呢? [color=red]此外,最需要注意的是,新版的 rpm 已经将 RPM 与 SRPM 的命令分开了,SRPM 使用的是 rpmbuild 这个命令,而不是 rpm 喔![/color]如果你是 Red Hat 7.3 以前的用户,那么请使用 rpm 来替代 rpmbuild 啦!

[size=large][b]利用默认值安装 SRPM 文件 (--rebuid/--recompile)[/b][/size]

假设我下载了一个 SRPM 的文件,又不想要修订这个文件内的原始码与相关的配置值, 那么我可以直接编译并安装吗?[color=red]当然可以!利用 rpmbuild 配合选项即可。[/color]选项主要有底下两个:

[color=red]--rebuild[/color] 这个选项会将后面的 SRPM 进行『编译』与『打包』的动作,最后会产生 RPM 的文件,但是产生的 RPM 文件并没有安装到系统上。当你使用 --rebuild 的时候,最后通常会发现一行字体:
Wrote: /usr/src/redhat/RPMS/i386/pkgname.i386.rpm
这个就是编译完成的 RPM 文件罗!这个文件就可以用来安装啦!安装的时候请加绝对路径来安装即可!
[color=red]--recompile 这个动作会直接的『编译』『打包』并且『安装』罗![/color]请注意, [color=blue]rebuild 仅『编译并打包』而已,而 recompile 不但进行编译跟打包,还同时进行『安装』了![/color]

不过,要注意的是,这两个选项都没有修改过 SRPM 内的配置值,仅是透过再次编译来产生 RPM 可安装软件文件而已。 一般来说,如果编译的动作顺利的话,那么编译过程所产生的中间缓存档都会被自动删除,如果发生任何错误, 则该中间文件会被保留在系统上,等待使用者的除错动作!那么,该如何除错呢?如果想要自行除错, 或者是想要修改 SRPM 内的配置值时,就得要知道利用 SRPM 的时候,系统会动用到哪些重要的目录了! 底下我们就来谈一谈当处理 SRPM 时,系统会使用到的目录。

[size=large][b]SRPM 使用的路径与需要的软件[/b][/size]

SRPM 既然含有 source code ,那么其中必定有配置档罗,所以首先我们必需要知道,这个 SRPM 在进行编译的时候会使用到哪些目录呢?这样一来才能够来修改嘛!你可以到你的 /usr/src 这个目录里面去查看一下,通常每个 distribution 提供的目录都不太相同,以 CentOS 5.x 为例,他是以 /usr/src/redhat/ 为工作目录, Openlinux 则是以 /usr/src/openlinux 为工作目录![color=red]无论如何,反正就是在 /usr/src 这个目录下就对了![/color]好了,既然我们是 CentOS , 请到 /usr/src/redhat 里头去看一看呦:

[color=red]/usr/src/redhat/SPECS 这个目录当中放置的是该软件的配置档,例如这个软件的资讯参数、配置项目等等都放置在这里;[/color]
[color=red]/usr/src/redhat/SOURCES 这个目录当中放置的是该软件的原始档 (*.tar.gz 的文件) 以及 config 这个配置档;[/color]
/usr/src/redhat/BUILD 在编译的过程中,有些缓存的数据都会放置在这个目录当中;
[color=red]/usr/src/redhat/RPMS 经过编译之后,并且顺利的编译成功之后,将打包完成的文件放置在这个目录当中。里头有包含了 i386, i586, i686, noarch.... 等等的次目录。[/color]
/usr/src/redhat/SRPMS 与 RPMS 内相似的,这里放置的就是 SRPM 封装的文件罗!有时候你想要将你的软件用 SRPM 的方式释出时, 你的 SRPM 文件就会放置在这个目录中了。

此外,在编译的过程当中,可能会发生不明的错误,或者是配置的错误,这个时候就会在 [color=red]/tmp 底下产生一个相对应的错误档[/color],你可以根据该错误档进行除错的工作呢! 等到所有的问题都解决之后,也编译成功了,那么刚刚解压缩之后的文件,就是在 /usr/src/redhat/SPECS, SOURCES, BUILD 等等的文件都会被杀掉,而只剩下放置在 /usr/src/redhat/RPMS 底下的文件了!

由於 SRPM 需要重新编译,而编译的过程当中,我们至少需要有 make 与其相关的程序,及 gcc, c, c++ 等其他的编译用的程序语言来进行编译,更多说明请参考第二十二章原始码所需基础软件吧。 所以,如果你在安装的过程当中没有选取软件开发工具之类的软件, 呵呵!得重新拿出你的光盘,然后再安装喔!哈哈!只是得要克服一大堆的属性相依的问题就是了~ 这问题待会儿可以使用 yum 来处理,你当然也可以先使用『 yum groupinstall "Development Tools" 』来安装开发软件。 鸟哥这里假设你已经安装了该软件群组罗。

例题:
[color=red]尝试使用 --rebuild 选项制作出一个 RPM 软件文件[/color],可以到国家高速网络中心下载 rp-pppoe 这个 SRPM 软件文件, 你可以到 http://ftp.twaren.net/Linux/CentOS/5/os/SRPMS/ 找到这个软件来下载。 鸟哥这里使用 CentOS 5.3 的 rp-pppoe-3.5-32.1.src.rpm 为例喔。
答:
假设你已经将 rp-pppoe 软件下载到 /root 底下,那接下来可以简单的使用底下的方式来重新编译:

[code="linux"]
# rpmbuild --rebuild rp-pppoe-3.5-32.1.src.rpm
正在安装 rp-pppoe-3.5-32.1.src.rpm
警告:使用者 mockbuild 不存在 - 现使用 root 代替
....(中间省略)....
已写入:/usr/src/redhat/RPMS/i386/rp-pppoe-3.5-32.1.i386.rpm
已写入:/usr/src/redhat/RPMS/i386/rp-pppoe-debuginfo-3.5-32.1.i386.rpm
正在运行 (%clean):/bin/sh -e /var/tmp/rpm-tmp.69789
+ umask 022
+ cd /usr/src/redhat/BUILD
+ cd rp-pppoe-3.5
+ rm -rf /var/tmp/rp-pppoe-3.5-32.1-root
+ exit 0
正在运行 (--clean):/bin/sh -e /var/tmp/rpm-tmp.69789
+ umask 022
+ cd /usr/src/redhat/BUILD
+ rm -rf rp-pppoe-3.5
+ exit 0

# ll /usr/src/redhat/RPMS/i386/
-rw-r--r-- 1 root root 105443 6月 27 02:51 rp-pppoe-3.5-32.1.i386.rpm
-rw-r--r-- 1 root root 18756 6月 27 02:51 rp-pppoe-debuginfo-3.5-32.1.i386.rpm
[/code]

其实整个过程与 Tarball 的方式差不多,也是编译后变成 binary program,接著再以 RPM 的机制封装起来啦。 重点在上面特殊字体的部分,记得要察看一下喔!若一切正常,则会看到 exit 0 的字样,且会主动的删除 (rm) 很多中间缓存档哩。

[size=large][b]配置档的主要内容 (*.spec)[/b][/size]

除了使用 SRPM 内默认的参数来进行编译之外,我们还可以修改这些参数后再重新编译喔!那该如何处理呢? [color=red]首先我们必须要将 SRPM 内的文件安置到 /usr/src/redhat/ 内的相关目录[/color],然后再去修改配置档即可啊! 我们就拿刚刚上头那个 rp-pppoe 来说明好了,假设我们已经将该文件放置到 /root 中啦,然后:

[code="linux"]
# rpm -i rp-pppoe-3.5-32.1.src.rpm
# 过程不会显示任何东西,他只会将 SRPM 的文件解开后,放置到 /usr/src/redhat/

# find /usr/src/redhat/ -type f
/usr/src/redhat/SOURCES/rp-pppoe-3.5-firewall.patch <==补丁档
/usr/src/redhat/SOURCES/adsl-stop <==CentOS 提供的脚本
/usr/src/redhat/SOURCES/rp-pppoe-3.5.tar.gz <==原始码啦!
/usr/src/redhat/SOURCES/rp-pppoe-3.5-buildroot.patch <==补丁档
/usr/src/redhat/SOURCES/adsl-start <==CentOS 提供的脚本
/usr/src/redhat/SOURCES/adsl-connect
/usr/src/redhat/SOURCES/adsl-setup
/usr/src/redhat/SOURCES/adsl-status
/usr/src/redhat/SOURCES/rp-pppoe-3.4-redhat.patch <==补丁档
/usr/src/redhat/SPECS/rp-pppoe.spec <==重要配置档!
# 主要含有原始码与一个重要的配置档啊! rp-pppoe.spec !
[/code]

好了,来看看我们的配置参数档,亦即是在 /usr/src/redhat/SPECS 内的 *.spec 文件罗!

[code="linux"]
# cd /usr/src/redhat/SPECS
# vi rp-pppoe.spec
# 1. 首先,这个部分在介绍整个软件的基本相关资讯!不论是版本还是释出次数等。
Summary: A PPP over Ethernet client (for xDSL support).
Name: rp-pppoe
Version: 3.5
Release: 32.1
License: GPL
Group: System Environment/Daemons
Url: http://www.roaringpenguin.com/pppoe/
Source: http://www.roaringpenguin.com/rp-pppoe-%{version}.tar.gz
Source1: adsl-connect
Source2: adsl-setup
....(中间省略)....

# 2. 这部分则是在配置相依属性需求的地方!
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root

Prereq: /sbin/chkconfig <==需要的前驱程序有哪些!
Prereq: /sbin/service
Prereq: fileutils

Requires: ppp >= 2.4.2 <==需要的软件又有哪些!
Requires: initscripts >= 5.92
Requires: iproute >= 2.6

BuildRequires: libtool <==还需要哪些工具软件?
BuildRequires: autoconf
BuildRequires: automake

%description <==此软件的描述啦!
PPPoE (Point-to-Point Protocol over Ethernet) is a protocol used by
many ADSL Internet Service Providers. This package contains the
Roaring Penguin PPPoE client, a user-mode program that does not
require any kernel modifications. It is fully compliant with RFC 2516,
the official PPPoE specification.


# 3. 编译前的预处理,以及编译过程当中所需要进行的命令,都写在这里
# 尤其 %build 底下的数据,几乎就是 makefile 里面的资讯啊!
%prep <==这部份在预先 (pre) 进行处理,大致就是 patch 软件啊!
%setup -q
%patch0 -p1 -b .config
%patch1 -p1 -b .buildroot
%patch2 -p1 -b .ipchains

%build <==这部分就是在实际编译罗!
cd src
autoconf
CFLAGS="-D_GNU_SOURCE" %configure
make

install -m 0755 %{SOURCE1} scripts
install -m 0755 %{SOURCE2} scripts
install -m 0755 %{SOURCE3} scripts
install -m 0755 %{SOURCE4} scripts
install -m 0755 %{SOURCE5} scripts

%install <==这就是安装过程!
rm -rf %{buildroot}

mkdir -p %{buildroot}/sbin
make -C src install RPM_INSTALL_ROOT=%{buildroot}
....(中间省略)....

# 4. 这里列出,这个软件释出的文件有哪些的意思!
%files <==这个软件提供的文件有哪些?需要记录在数据库内!
%defattr(-,root,root)
%doc doc/LICENSE scripts/adsl-connect scripts/adsl-setup scripts/adsl-init
%doc scripts/adsl-start scripts/adsl-status scripts/adsl-stop
%doc configs
%config(noreplace) %{_sysconfdir}/ppp/pppoe-server-options
%config(noreplace) %{_sysconfdir}/ppp/firewall*
/sbin/*
%{_sbindir}/*
%{_mandir}/man?/*

# 5. 列出这个软件的更改历史纪录档!
%changelog
* Wed Jul 12 2006 Jesse Keating - 3.5-32.1
- rebuild
....(中间省略)....
* Wed May 31 2000 Than Ngo
- adopted for Winston.
[/code]

要注意到的是 rp-pppoe.sepc 这个文件,这是主要的将 SRPM 编译成 RPM 的配置档,他的基本守则可以这样看:

整个文件的开头以Summary为开始,这部份的配置都是最基础的说明内容;
[color=red]然后每个不同的段落之间,都以%来做为开头,例如%prep与%install等;[/color]

我们来谈一谈几个常见的 SRPM 配置段落:

[size=small][b]系统整体资讯方面:[/b][/size]

刚刚你看到的就有底下这些重要的咚咚罗:

参数 参数意义
Summary 本软件的主要说明,例如上表中说明了本软件是针对 xDSL 的拨接用途啦!
Name 本软件的软件名称 (最终会是 RPM 文件的档名构成之一)
Version 本软件的版本 (也会是 RPM 档名的构成之一)
Release 这个是该版本打包的次数说明 (也会是 RPM 档名的构成之一)。由於我们想要动点手脚,所以上头的文件中, 这个部分请修改为 32.2.vbird 看看
License 这个软件的授权模式,我们是使用 GPL 啦!
Group 这个软件的发展团体名称;
Url 这个原始码的主要官方网站;
Source 这个软件的来源,如果是网络上下载的软件,通常一定会有这个资讯来告诉大家这个原始档的来源! 此外,还有来自开发商自己提供的原始档数据喔!例如上面的 adsl-start 等程序。
Patch 就是作为补丁的 patch file 罗!
BuildRoot 配置作为编译时,该使用哪个目录来缓存中间文件 (如编译过程的目标文件/连结文件等档)。
ExclusiveArch 这个是说明这个软件的适合安装的硬件,通常默认为 i386,当然,你也可以调整为 i586 啦等等的! 由於我们的系统是新的 CPU 架构,这里我们修改内容成为『ExclusiveArch: i686』来玩玩看。
上述为必须要存在的项目,底下为可使用的额外配置值
Requires 如果你这个软件还需要其他的软件的支持,那么这里就必需写上来,则当你制作成 RPM 之后,系统就会自动的去检查啦!这就是『相依属性』的主要来源罗!
Prereq 这个软件需要的前驱程序为何!这里指的是『程序』而 Requires 指的是『软件』!
BuildRequires 编译过程中所需要的软件。Requires 指的是『安装时需要检查』的,因为与实际运行有关,这个 BuildRequires 指的是『编译时』所需要的软件,只有在 SRPM 编译成为 RPM 时才会检查的项目。
Packager 这个软件是经由谁来打包的呢?
Vender 发展的厂商哪;

上面几个数据通常都必需要写啦!但是如果你的软件没有相依属性的关系时,那么就可以不需要那个 Requires 罗! 根据上面的配置,最终的档名就会是『{Name}-{Version}-{Release}.{ExclusiveArch}.rpm』的样式, 以我们上面的配置来说,档名应该会是『rp-pppoe-3.5-32.2.vbird.i686.rpm』的样子罗!

%description:
将你的软件做一个简短的说明!这个也是必需要的。还记得使用『 rpm -qi 软件名称 』会出现一些基础的说明吗? 上面这些东西包括 Description 就是在显示这些重要资讯的啦!所以,这里记得要详加解释喔!


%prep:
pre 这个关键字原本就有『在...之前』的意思,因此这个项目在这里指的就是『尚未进行配置或安装之前,你要编译完成的 RPM 帮你事先做的事情』,就是 prepare 的简写罗!那么他的工作事项主要有:

进行软件的补丁 (patch) 等相关工作;
寻找软件所需要的目录是否已经存在?确认用的!
事先创建你的软件所需要的目录,或者事先需要进行的任务;
如果待安装的Linux系统内已经有安装的时候可能会被覆盖掉的文件时,那么就必需要进行备份(backup)的工作了!
在本案例中,你会发现程序会使用 patch 去进行补丁的动作啦!


%setup:
这个项目就是在进行类似解压缩之类的工作!这个项目一定要写喔!不然你的 tarball 原始码是无法被解压缩的哩!切记切记!


[b]%build:[/b]
build 就是创建啊!所以当然罗,这个段落就是在谈怎么 make 编译成为可运行的程序罗! 你会发现在此部分的程序码方面,就是 ./configure, make 等项目哩!


%install:
编译完成 (build) 之后,就是要安装啦!安装就是写在这里,也就是类似 Tarball 里面的 make install 的意思罗!


%clean:
编译与安装完毕后,必须要将一些缓存在 BuildRoot 内的数据删除才好, 因此这个时候这个 clean 的项目就重要啦!这有点像是 make clean 的感觉~保持系统的干爽嘛!


[b]%files:[/b]
这个软件安装的文件都需要写到这里来,当然包括了『目录』喔!所以连同目录请一起写到这个段落当中!以备查验呢!^_^ !此外,你也可以指定每个文件的类型,包括文件档 (%doc 后面接的) 与配置档 (%config 后面接的) 等等。


[b]%changelog:[/b]
这个项目主要则是在记录这个软件曾经的升级纪录罗!星号 (*) 后面应该要以时间,修改者, email 与软件版本来作为说明, 减号 (-) 后面则是你要作的详细说明罗!在这部份鸟哥就新增了两行,内容如下:


%changelog
* Wed Jul 01 2009 VBird Tsai - 3.5-32.2.vbird
- only rebuild this SRPM to RPM

* Wed Jul 12 2006 Jesse Keating - 3.5-32.1
....(底下省略)....


修改到这里也差不多了,您也应该要了解到这个 rp-pppoe.spec 有多么重要![color=red]我们用 rpm -q 去查询一堆资讯时, 其实都是在这里写入的![/color]这样了解否?接下来,就让我们来了解一下如何将 SRPM 给他编译出 RPM 来吧!

[size=large][b]SRPM 的编译命令 (-ba/-bb)[/b][/size]

要将在 [color=red]/usr/src/redhat 底下的数据编译或者是单纯的打包成为 RPM 或 SRPM 时,就需要 rpmbuild 命令与相关选项的帮忙了![/color]我们只介绍两个常用的选项给您了解一下:

[code="linux"]
# rpmbuild -ba rp-pppoe.spec <==编译并同时产生 RPM 与 SRPM 文件
# rpmbuild -bb rp-pppoe.spec <==仅编译成 RPM 文件
[/code]

这个时候系统就会这样做:

先进入到 BUILD 这个目录中,亦即是: /usr/src/redhat/BUILD 这个目录;

依照 *.spec 文件内的 Name 与 Version 定义出工作的目录名称,以我们上面的例子为例,那么系统就会在 BUILD 目录中先删除 rp-pppoe-3.5 的目录,再重新创建一个 rp-pppoe-3.5 的目录,并进入该目录;

在新建的目录里面,针对 SOURCES 目录下的来源文件,也就是 *.spec 里面的 Source 配置的那个文件,以 tar 进行解压缩,以我们这个例子来说,则会在 /usr/src/redhat/BUILD/rp-pppoe-3.5 当中,将 /usr/src/redhat/SOURCES/rp-pppoe-3.5.tar.gz 进行解压缩啦!

[color=red]再来开始 %build 及 %install 的配置与编译![/color]

最后将完成打包的文件给他放置到该放置的地方去,如果你的规定的硬件是在 i386 的系统,那么最后编译成功的 *.i386.rpm文件就会被放置在 /usr/src/redhat/RPMS/i386 里面罗!如果是 i686 那么自然就是 /usr/src/redhat/RPMS/i686 目录下罗!
整个步骤大概就是这样子!最后的结果数据会放置在 RPMS 那个目录底下就对啦!我们这个案例中想要同时打包 RPM 与 SRPM , 因此请您自行处理一下『 rpmbuild -ba rp-pppoe.spec 』吧!

[size=large][b]一个打包自己软件的范例[/b][/size]

这个就有趣了!我们自己来编辑一下自己制作的 RPM 怎么样?会很难吗?完全不会! 我们这里就举个例子来玩玩吧!还记得我们在前一章谈到 Tarball 与 make 时,曾经谈到的 main 这个程序吗?[color=red]现在我们将这个程序加上 Makefile 后, 将他制作成为 main-0.1.i386.rpm[/color] 好吗?那该如何进行呢?底下就让我们来处理处理吧!

[size=small][b]制作原始码文件 tarball 产生:[/b][/size]

请将前一章你曾经处理过的 main.tgz 再次的捉下来一次,我们将这个文件放置到 /root 底下, 并且在[color=darkred] /usr/local/src[/color] 底下创建一个名为 main-0.1 的目录来解压缩喔!

[code="linux"]
# mkdir /usr/local/src/main-0.1
# tar -zxvf main.tgz -C /usr/local/src/main-0.1
# cd /usr/local/src/main-0.1
# vim Makefile <==创建原始码所需 make 守则
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
main: ${OBJS}
gcc -o main ${OBJS} ${LIBS}
clean:
rm -f main ${OBJS}
install:
install -m 755 main $(RPM_INSTALL_ROOT)/usr/local/bin/main
# 记得 gcc 与 rm 之前是使用 按键作出来的空白喔!

# cd ..
# tar -zcvf main-0.1.tar.gz main-0.1
# 此时会产生 main-0.1.tar.gz ,将他挪到 /usr/src/redhat/SOURCES 底下:
# cp main-0.1.tar.gz /usr/src/redhat/SOURCES
[/code]

这个时候在 [color=red]/usr/src/redhat 底下的原始码就创建成功[/color]了!接下来就是 spec 文件的创建罗!

[size=small][b]创建 *.spec 的配置档[/b][/size]

这个文件的建置是所有 RPM 制作里面最重要的课题!你必须要仔细的配置他,不要随便处理!仔细看看吧!

[code="linux"]
# cd /usr/src/redhat/SPECS
# vim main.spec
Summary: calculate sin and cos value.
Name: main
Version: 0.1
Release: 1
License: GPL
Group: VBird's Home
Source: main-0.1.tar.gz <==记得要写正确的 Tarball 档名喔!
Url: http://linux.vbird.org
Packager: VBird
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root

%description
This package will let you input your name and calculate sin cos value.

%prep
%setup -q

%build
make

%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/usr/local/bin
make install RPM_INSTALL_ROOT=%{buildroot} <==这项目也很重要!

%files
/usr/local/bin/main

%changelog
* Wed Jul 01 2009 VBird Tsai 0.1
- build the program
[/code]

[size=small][b]编译成为 RPM 与 SRPM[/b][/size]

老实说,那个 spec 文件建置妥当后,后续的动作就简单的要命了!开始来编译吧!

[code="linux"]
# rpmbuild -ba main.spec
....(前面省略)....
已写入:/usr/src/redhat/SRPMS/main-0.1-1.src.rpm
已写入:/usr/src/redhat/RPMS/i386/main-0.1-1.i386.rpm
已写入:/usr/src/redhat/RPMS/i386/main-debuginfo-0.1-1.i386.rpm
[/code]

很快的,我们就已经创建了几个 RPM 文件罗!接下来让我们好好测试一下打包起来的成果吧!

[size=small][b]安装/测试/实际查询[/b][/size]

[code="linux"]
# rpm -ivh /usr/src/redhat/RPMS/i386/main-0.1-1.i386.rpm
正在准备… ########################################### [100%]
1:main ########################################### [100%]

# rpm -ql main
/usr/local/bin/main <==自己尝试运行 main 看看!

# rpm -qi main
Name : main Relocations: (not relocatable)
Version : 0.1 Vendor: (none)
Release : 1 Build Date: 西元2009年07月02日 (周四)
Install Date: 西元2009年07月02日 Build Host: www.vbird.tsai
Group : VBird's Home Source RPM: main-0.1-1.src.rpm
Size : 3360 License: GPL
Signature : (none)
Packager : VBird
URL : http://linux.vbird.org
Summary : calculate sin and cos value.
Description :
This package will let you input your name and calculate sin cos value.
# 看到没?属於你自己的软件喔!真是很愉快的啦!
[/code]

用很简单的方式,就可以将自己的软件或者程序给他修改与配置妥当!以后你就可以自行配置你的 RPM 罗!当然,也可以手动修改你的 SRPM 的来源档内容罗!

转自:[url]http://vbird.dic.ksu.edu.tw/linux_basic/0520rpm_and_srpm_3.php[/url]

你可能感兴趣的:(Linux)