1 准备
首先请准备一个Linux环境,比如CentOS。
RPM打包使用的是rpmbuild
命令,这个命令来自rpm-build包,这个是必装的。
$ yum
install
rpm-build
|
当然也可以直接安装rpmdevtools,这个工具还包含一些其他的工具,同时它依赖rpm-build,所以直接安装的话会同时把rpm-build装上。
$ yum
install
rpmdevtools
|
当然,根据不同的软件构建过程,还需要其他的编译打包工具,比如C语言的make
、gcc
,python的setuptools
等,根据需要安装即可。
2 原理
RPM打包的时候需要编译源码,还需要把编译好的配置文件啊二进制命令文件啊之类的东西按照安装好的样子放到合适的位置,还要根据需要对RPM的包进行测试,这些都需要先有一个“工作空间”。rpmbuild
命令使用一套标准化的“工作空间”:
$ rpmdev-setuptree
|
rpmdev-setuptree
这个命令就是安装rpmdevtools带来的。可以看到运行了这个命令之后,在$HOME
家目录下多了一个叫做rpmbuild
的文件夹,里边内容如下:
$ tree rpmbuild
|
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) |
SPECS下是RPM包的配置文件,是RPM打包的“图纸”,这个文件会告诉rpmbuild
命令如何去打包。“宏代码”这一列就可以在SPEC文件中用来代指所对应的目录,类似于编程语言中的宏或全局变量。当然~/rpmbuild
这个文件夹也是有宏代码的,叫做%_topdir
。
打包的过程有点像是流水线,分好几个工序:
1. 首先,需要把源代码放到%_sourcedir
中;
2. 然后,进行编译,编译的过程是在%_builddir
中完成的,所以需要先把源代码复制到这个目录下边,一般情况下,源代码是压缩包格式,那么就解压过来即可;
3. 第三步,进行“安装”,这里有点类似于预先组装软件包,把软件包应该包含的内容(比如二进制文件、配置文件、man文档等)复制到%_buildrootdir
中,并按照实际安装后的目录结构组装,比如二进制命令可能会放在/usr/bin
下,那么就在%_buildrootdir
下也按照同样的目录结构放置;
4. 然后,需要配置一些必要的工作,比如在实际安装前的准备啦,安装后的清理啦,以及在卸载前后要做的工作啦等等,这样也都是通过配置在SPEC文件中来告诉rpmbuild
命令;
5. 还有一步可选操作,那就是检查软件是否正常运行;
6. 最后,生成的RPM包放置到%_rpmdir
,源码包放置到%_srpmdir
下。
以上这些步骤都是配置在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 包通常用于审核和升级软件包。 |
3 示例
$
cd
rpmbuild
/SPECS
#进入SPECS目录
$ rpmdev-newspec
test
.spec
#生成spec文件模板
#将要打包的源码以tar.gz的格式移动到SOURCES目录,此处特别注意源码文件一定要齐全如Makefile等。可以到官网http://ftp.gnu.org/gnu/下载压缩包测试
$
mv
your_path
/test-1
.0.
tar
.gz ..
/SOURCES
|
SPEC编写(关键)
- #名字与test-1.0.tar.gz名字对应
- Name: test
- #版本号与test-1.0.tar.gz版本号对应
- Version:1.0
- #编译的次序
- Release:1
- #一句话介绍包 (不超过50个字符)
- Summary: is test
- Group: Applications/Communications
- License: GPL
- URL: www.ustack.com
- #要安装的压缩包源文件
- Source: test-1.0.tar.gz
- BuildRoot: %{_tmppath}/%{name}-%{version}-root
- %description
- a test
- #构建包前的处理
- %prep
- #-- 解压:这里主要是构建的时候解压缩源码到系统目录,这里是$RPM_BUILD_DIR
- # setup -c 解压的时候会生成一个和压缩包同名的新目录 ; setup -n dirname 指定一个新的目录以解压缩 setup -q 直接解压,不产生新的目录
- %setup -q
- #-- 生成:这里主要是构建二进制包的的时候执行编译生成二进制文件
- %build
- make
- #-- 安装:构建的时候把当前文件安装到系统目录$RPM_BUILD_ROOT/下,二进制安装的时候是安装文件到/根目录下
- %install
- #make install #使用makefile的install,方便
- #没有makefile,自定义安装脚本
- rm -rf $RPM_BUILD_ROOT/*
- mkdir -p $RPM_BUILD_ROOT/usr/bin/
- cp -r $RPM_BUILD_DIR/%{name}-%{version} $RPM_BUILD_ROOT/usr/bin/
- #安装完成后续:二进制包安装后的处理脚本
- %post
- chmod +x /usr/bin/%{name}-%{version}/confAgent
- chmod +x /usr/bin/%{name}-%{version}/check_confAgent.sh
- #卸载完成后续:二进制包卸载完成后的处理脚本
- %postun
- rm -fr /usr/bin/%{name}-%{version}
- #清理:构建包完成后处理
- %clean
- rm -rf $RPM_BUILD_ROOT
- #文件列表:指示哪些文件应该被安装到系统中以及安装的目录;
- #构建包时,文件列表的文件或目录必须和虚拟目录RPM_BUILD_ROOT中的文件或目录一致,否则构建时会
- #提示找不到文件
- %files
- %defattr(-,root,root)
- /usr/bin/%{name}-%{version}
- %changelog
test.spec编写结束。
4、生成RPM包
$rpmbuild -ba
test
.spec
#生成RPM包
|
生成的RPM包在rpmbuild/RPMS目录下。
5 测试
$ rpm -ivh ~
/rpmbuild/RPMS/x86_64/test-1
.0-1.el7.centos.x86_64.rpm
|
编译成功即可运行相应的命令或客户端。