在Linux世界里,软件的安装方式主要有三条路径:源码编译、RPM包管理,以及类似Windows双击运行的*.bin文件。如果非要再精简一下,日常接触最多的其实就两类——一类是形如xxx.i386.rpm的二进制包,另一类是形如xxx.tar.gz的源码包。
当然,随着Linux发行版的不断演化,获取软件的方式也变得更加丰富。RedHat/CentOS系有yum配合镜像源,Ubuntu/Fedora/Debian则用apt-get管理deb包,还有通过刻盘加密方式安装的,甚至运维人员会借助ssh或Python脚本实现自动化管理。下面这张图可以清晰地展示Linux软件应用的架构关系:

Linux启动时,首先登场的是内核(kernel)。内核是一段直接管理硬件的程序——CPU、内存、硬盘接口、网络接口,所有操作都得经过它才能抵达硬件。内核与上层应用之间通过系统调用这个关键接口隔离开来,给程序员屏蔽了底层复杂性,也提高了应用的可移植性。即便升级内核,只要系统调用接口不变,上层应用几乎感知不到变化。库函数在系统调用之上搭建模块化功能,shell则提供用户界面,并允许编写脚本整合程序。理解了这些底层逻辑,就能快速掌握Linux软件安装与运行的原理。
本文重点聚焦源码安装和RPM包安装。
源码包和商业软件包会以多种格式发布——tar压缩包、bin源程序、已经编译好的可执行文件,甚至光盘虚拟化后的iso文件。有意思的是,通过yum或make install安装的软件,系统内部最终都会生成对应的RPM包,只是参数和功能模块略有差异。
简单说一下RPM(RedHat Package Manager),它是红帽子贡献的软件包管理工具,用于安装、查询、升级、校验、卸载,还能生成.rpm格式的软件包。使用前需要挂载安装光盘(以CentOS 4为例),当然也可以从网上下载免费的RPM包。
# mount /dev/cdrom --- 挂载光盘
# cd /media/cdrom/CentOS/RPMS --- 进入光盘中RPM包的目录
# ls
一、源码包安装
1、*.src.rpm形式的源代码软件包
安装步骤:
rpm --rebuild *.src.rpm
cd /usr/src/dist/RPMS
rpm -ivh *.rpm
卸载:
rpm -e packagename
2、.tar.gz、*.tgz、*.bz2形式软件包的安装
首先解压:
tar zxvf *.tar.gz
tar xvfz *.tgz
tar xvfj *.tar.bz2
进入解压目录后,通常执行以下操作:
配置:./configure
编译:make
安装:make install
卸载:make uninstall
源码安装有一定难度,不同软件可能有不同要求。解压后最好先阅读说明文档,按照说明进行安装——上面说的只是通用流程。
二、RPM包安装
RPM安装包格式由Redhat公司提出,大大简化了Linux下的软件安装流程。
通用选项
-v:显示附加信息
-vv:显示调试信息
--root directory:以directory为根目录
1、安装:rpm -i
常用选项:
-h:安装时输出hash记号
--test:只测试,不真正安装
--persent:以百分比显示进度
--excludedocs:不安装文档
--replacepkgs:强制重新安装
--replacefiles:替换属于其它包的文件
--force:忽略冲突
--ignorearch:不校验结构
--ignoreos:不检查操作系统
--nodeps:不检查依赖关系
--noscripts:不运行安装脚本
2、删除:rpm -e
选项:
--test:只做删除测试
--noscripts:不运行脚本
--nodeps:不检查依赖
注意:pkgname是安装后软件包的名字,不是rpm包名字本身,可以用查询命令查找。
3、升级:rpm -U(或--upgrade)
特殊选项:
--oldpackage:允许旧版本
4、查询:rpm -q(或--query)
选项:
-p PACKAGE_FILE:查询软件包文件
-f FILE:查询文件归属
-a:查询所有已安装包
-g group:查询组内包
--whatprovides CAPABILITY:查询提供某功能的包
--whatrequires CAPABILITY:查询需要某功能的包
-i:显示概要信息
-l:显示文件列表
-c:显示配置文件
-s:显示文件列表
--scripts:显示脚本
--qf:用户指定格式查询
--dump:显示校验信息
--provides:显示包提供的功能
-R:显示包需要的功能
5、校验已安装包:rpm -V(或--verify)
选项与其他命令类似。
6、校验包中文件:rpm -K(或--checksig)
选项:
-v:显示版本
-vv:显示调试信息
--rcfile FILELIST:设置rpmrc文件
7、其它RPM选项
--rebuilddb:重建资料库
--initdb:创建新资料库
--quiet:减少输出
--help:显示帮助
--version:显示当前版本
上面只是常用选项的总结,具体问题可以用man rpm命令查看——官方文档永远是最好的老师。
三、*.bin格式安装文件
只需双击或单击*.bin文件,根据提示安装即可,不再赘述。
要制作一个RPM格式的软件包,需要编写软件包描述文件。标准命名格式为:软件名-版本号-释出号.spec(现在大多直接用:软件名.spec)。这个文件详细描述了软件名、版本、类别、说明摘要、创建指令、安装操作、包含的文件等信息。有了它,RPM就能制作出相应的包裹文件。当然也有Source rpm这样的辅助工具,通过向导即可快速制作。
简单制作例子:将nginx的tar包制作为RPM包
1. 下载nginx的源码包
2. 将文件放到/usr/src/redhat/SOURCES/目录下
3. 编写SPEC文件
[root@mail SPECS]# vim nginx-0.8.35.spec
Summary: the first rpm package
Name: nginx
Version: 0.8
Release: 35
Vendor: chenwei01@corp.the9.com
License: Share
Group: Applications/Text
Source0: nginx-0.8.35.tar.gz
%description
my test nginx
%prep
tar -zxvf $RPM_SOURCES_DIR/nginx-0.8.35.tar.gz
%build
cd $RPM_BUILD_DIR/nginx-0.8.35
./configure
make
%install
cd $RPM_BUILD_DIR/nginx-0.8.35
make install
%clean
rm -rf $RPM_BUILD_DIR/nginx-0.8.35
%files
%defattr(-,root,root)
/usr/local/nginx/sbin/nginx
%doc $RPM_BUILD_DIR/nginx-0.8.35/README
4. 制作RPM包
[root@mail SPECS]# rpmbuild -ba nginx-0.8.35.spec
若运行无误,将会生成两个文件:/usr/src/redhat/RPMS/i386/nginx-0.8-35.i386.rpm 和 /usr/src/redhat/SRPMS/nginx-0.8-35.src.rpm。
RPM包制作之个人经验总结
一、RPM介绍
RPM最初是RedHat Package Manager的缩写,现在则代表RPM Package Manager。在Fedora、Redhat、Mandriva、SuSE、YellowDog等主流发行版及其二次开发版本中使用。RPM包中不仅包含程序运行所需的文件,还有其他附加文件。一个RPM包有时还需要特定版本的其他文件才能正常运行,这就是软件包的依赖关系。
RPM允许用户以二进制方式直接安装,还能自动查询相关库文件是否已安装。删除程序时,它会询问是否删除相关程序。升级时,RPM会保留原有的配置文件,免去重新配置的麻烦。RPM维护着一个包含所有软件包资料的数据库,方便用户查询。虽然RPM是为Linux设计的,但它已经移植到SunOS、Solaris、AIX、Irix等UNIX系统上。RPM遵循GPL版权协议。
二、RPM包分类
RPM包大致可以分为两类:
1. 二进制类包,包括rpm安装包(分i386和x86等)和调试信息包。
2. 源码类包,包括源码包和开发包。
它们之间的关系是:先按RPM打包要求改造软件项目源码,符合要求后使用rpmbuild命令生成不同的RPM包,同时生成的包之间版本直接对应。在网上查找RPM包时,RPMS目录中能找到预编译的二进制包,源码包则在SRPMS目录内。
这里说的RPM制作,就是指改造软件源代码使之符合RPM打包要求的过程,这等价于RPM源码包的制作——有了源码包,就能直接编译得到二进制安装包和其他任意包。
三、RPM包制作介绍
RPM包的制作,本质上就是RPM源码包的制作。
RPM的工作原理值得一说。它之所以出现,是为了解决源码包不易安装(需要编译)以及软件包相互依赖的问题。RPM通过探测源码包在build和install阶段的动作,获得最终需要安装到系统的文件,记录必要的操作(比如安装完成后执行某项任务),然后打包成一个整体。用户安装时,RPM原原本本地把所有这些操作应用到实际系统上。
为一个普通源码打RPM包,需要做几件事:首先改造项目的Makefile以支持RPM打包操作(实际上这不是绝对的,只要SPEC文档和Makefile配合好就行);其次撰写SPEC文档,它包含了打包过程的操作内容和生成包的基本信息,作用对象是打包程序rpmbuild。
四、RPM包制作过程
1. 准备打包环境
Fedora系统下使用以下命令安装rpmbuild:
# yum install rpmbuild
rpmbuild的工作目录结构如下:
~/rpmbuild
~/rpmbuild/SOURCES
~/rpmbuild/SPECS
~/rpmbuild/BUILD
~/rpmbuild/RPMS
~/rpmbuild/RPMS/i386
~/rpmbuild/SRPMS
如果主目录下没有类似结构,可以用工具自动配置生成:
# yum install rpmdevtools
# rpmdev-setuptree
rpmdev-setuptree命令默认在当前用户主目录下创建RPM构建根目录结构。如果需要改变位置,可以修改配置文件~/.rpmmacros中的_topdir变量。SOURCES目录放置打包资源,包括源码打包文件和补丁文件;SPECS目录放置SPEC文档;BUILD是打包工作目录;RPMS目录存放生成的二进制包,根据硬件平台分类存放;SRPMS目录存放生成的源码包。
2. 撰写SPEC文档
SPEC撰写是打包RPM的核心,也是最有挑战性的一步。好在可以从一个简单模板开始,在实现基本功能的基础上逐步扩充。下面是一个针对hellorpm测试项目的简单SPEC文档:
#软件包简要介绍
Summary: hellorpm is a test program.
#软件包的名字
Name: hellorpm
#软件包的主版本号
Version: 2.2.6
#软件包的次版本号
Release: 1
#源代码包,默认在SOURCES目录中寻找
Source0: %{name}-%{version}.tar.gz
#授权协议
License: GPL
#定义临时构建目录
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
#软件分类
Group: Development/Tools
%description
The hellorpm program is a test.
#预操作字段,在源码BUILD前执行
%prep
#构建BUILD环境,解压源码到BUILD目录
%setup -q
#BUILD字段,调用自动构建工具完成编译
%build
./configure
make
#安装字段
%install
make DESTDIR=$RPM_BUILD_ROOT install
#文件说明字段
%files
%defattr(-,root,root)
/usr/local/bin/hellorpm
%doc %attr(0444,root,root) /usr/local/man/man1/hellorpm.1
%doc README
需要特别说明的是BuildRoot变量,它表示源码的临时安装目录,rpmbuild通过这个目录获取所有将要安装到系统的文件。SPEC文档中make install命令的参数DESTDIR=$RPM_BUILD_ROOT即是对该参数的引用,它会传给Makefile,告诉自动构建工具文件应该安装到哪里。
写好SPEC文档后,把名为hellorpm-2.2.6.tar.gz的源码压缩文件放到rpmbuild根目录下的SOURCES目录下(注意:解压后的目录名必须是hellorpm-2.2.6)。
3. 构建RPM包
使用rpmbuild命令在SPEC的指导下完成构建。首先进入当前用户的rpmbuild根目录:
# cd ~/rpmbuild/
执行以下命令,-ba表示build all,即生成二进制包和源代码包的所有RPM包:
# rpmbuild -ba SPECS/hellorpm.spec
如果一切顺利,RPMS目录和SRPMS目录中将会生成对应的RPM包。
这里只介绍了最简单项目的最简单RPM打包操作。对于涉及共享文件、复杂配置、复杂依赖关系的项目打包,以及后续的补丁制作,可以在实际使用中逐步完善。费了大半夜整理出这些内容,希望能对你有所帮助。
