目录
1 RPM打包学习
1.1 安装打包工具(服务器环境:openEuler 20.03)
1.2 工作目录
1.3 .spec文件
2 一个简单的小栗子
3 参考文档
打包的rpmbuild命令需要rpm-build包,所以我们可以使用yum安装rpm-build:
yum install rpm-build
或者直接安装rpmdevtools,里面包含了rpm-build和一些其他的工具:
yum install rpmdevtools
我们还可以根据自己的需求安装一些编译工具:
yum install gcc make python
我们在打包的时候可能要编译源码,并且将编译后得到的二进制包预安装到对应的位置,完成这些需要一个工作目录,我们的编译、预安装、打包和测试等都在这个工作目录中完成。
我们可以使用如下指令在当前位置生成一个工作目录(该指令来自于rpmdevtools包)
rpmdev-setuptree
执行指令后可以看到当前位置生成了一个rpmbuild文件夹
其结构为:
其中:
(1)BUILD目录(宏:%_builddir):用于存放解压后的源码,并且源码的编译在该目录完成。
(2)RPMS目录(宏:%_rpmdir):存放生成的二进制rpm包。
(3)SOURCES目录(宏:%_sourcedir):存放源代码压缩包和补丁。
(4)SPECS目录(宏:%_specdir):存放.spec文件。
(5)SRPMS目录(宏:%_srcrpmdir):存放生成的源码rpm包。
这里其实还有一个BUILDROOT目录(宏:%_buildrootdir),它是在打包执行过程中生成的,这个目录用于存放.spec文件中%install阶段定义的所需安装的文件,这些文件来自BUILD目录中编译好的二进制包、配置文件和一些脚本。
打包过程有多个步骤,而.spec文件类似于一个脚本,可以帮我们自动地执行各个步骤的指令,从而实现自动化打包。可以使用如下指令在当前目录创建一个.spec文件模板:
rpmdev-newspec kibana
执行完成后可以发现目录下生成了一个kibana.spec文件:
进去查看会发现里面部分内容已经帮我们写好:
其中:
(1)Name 为软件名,Version 为版本号,Release 为发布编号,Summary 为简要说明,License说明软件包的协议版本。URL为说明这个项目信息的网站,比如说官网链接,Source为指向源码压缩包资源的链接。
(2)BuildRequires为%build阶段所需的各种依赖,Requires为%install阶段所需的各种依赖。
(3)%prep阶段:将SOURCE目录下的源码解压至BUILD目录下,为%build阶段做好准备。其中%autosetup指令用于解压源码包。
(4) %build阶段:编译BUILD目录下的源码,生成二进制文件,为之后的%install阶段做准备。
(5)%install阶段:读取BUILD目录下需要安装的文件,将其预安装至BUILDROOT目录下,这个阶段还可以加入一些额外的文件,比如说一些脚本文件或者配置文件。
(6)%file部分:此部分列出需要被打包的文件和目录,这些文件和目录就是最终会安装到用户系统的文件了。
注:关于%install阶段定义文件安装位置,这一部分我的理解还是有点模糊,我的理解是,比如说,在%install阶段,将一个文件预安装到%{buildroot}/usr/bin/目录下,那么最后安装rpm包的时候,会将该文件安装到服务器上的/usr/bin目录下。
没有什么比一个简单的例子更容易上手了,下面我会用一个能输出“hello world”C语言文件作为例子。
众所周知,C源文件是不能直接执行的,它需要通过编译变成二进制文件后才能执行。所以,在打包之前,确保你的服务器上安装了gcc编译器:
yum install gcc -y
下面我们来创建一个C源文件hello.c:
#include
int main(void) {
printf("Hello World\n");
return 0;
}
使用gcc将其编译成可执行文件:
gcc -g -o hello hello.c
编译后生成了hello可执行文件,使用./hello执行它可以看到输出了Hello World:
我们这个例子目标就是制作出把能输出Hello World的二进制文件安装到/usr/bin目录下的rpm包。
因为rpm打包需要源码的压缩包,所以我们需要将hello.c变成压缩包:
tar -zcvf hello.tar.gz hello.c
可以看到已经生成了源码的压缩包,下一步我们需要将源码的压缩包放到我们的打包的工作目录的SOURCES目录下:
mv hello.tar.gz ~/rpmbuild/SOURCES
源码包准备好了,下面我们开始准备.spec文件,在SPECS目录下使用
rpmdev-newspec hello
生成.spec模板文件,并将其改写成如下样子:
其中:
(1)将SOURCES目录下的压缩包解压至BUILD目录下:
%prep
tar -zxvf %_sourcedir/%{name}.tar.gz -C %_builddir/
(2)将BUILD目录中的C源文件编译成二进制可执行文件:
%build
gcc -g -o hello %{name}.c
(3)在BUILDROOT目录下创建/usr/bin目录,并且将BUILD目录下的可执行文件hello安装到/usr/bin目录下(%{_bindir}是/usr/bin的宏):
%install
mkdir -p %{buildroot}/%{_bindir}
cp %{name} %{buildroot}/%{_bindir}/
(4)最后在%file下指定需要打包的文件(还可以指定不打包的文件):
%files
%{_bindir}/%{name}
编写完保存后在SPECS目录下执行指令
rpmbuild -ba hello.spec
来构建rpm包(注:-ba生成RPM和SPRM包,-bb只创建RPM包,-bs只创建SRPM包)。
1.-bp #只执行spec的%pre段(解开源码包并打补丁,即只做准备)
2.-bc #执行spec的%pre和%build 段(准备并编译)
3.-bi #执行spec中%pre,%build与%install(准备,编译并安装)
4.-bl #检查spec中的%file段(查看文件是否齐全)
5.-ba #建立源码与二进制包(常用):即编译后做成*.rpm和*.src.rpm
6.-bb #只建立二进制包(常用):即编译后做成*.rpm
7.-bs #只建立源码包:即只做成*.src.rpm
构建完成后,在RPMS目录下找到生成的rpm包,执行指令
rpm -ivp hello-1.0-1.aarch64.rpm
来安装rpm包。
安装完成后,在命令行输入hello,可以发现输出了hello world,安装成功!
并且可以看到二进制可执行文件被安装到了服务器的/usr/bin路径下:
最后使用指令
rpm -e hello-1.0-1.aarch64
来卸载该rpm包。至此,整个打包流程结束!
最后列出一些常用的宏路径
%{_sysconfdir} /etc
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} /var/lib
%{_datarootdir} %{_prefix}/share
%{_datadir} %{_datarootdir}
%{_includedir} %{_prefix}/include
%{_infodir} /usr/share/info
%{_mandir} /usr/share/man
%{_localstatedir} /var
%{_initddir} %{_sysconfdir}/rc.d/init.d
%{_var} /var
%{_tmppath} %{_var}/tmp
%{_usr} /usr
%{_usrsrc} %{_usr}/src
%{_lib} lib (lib64 on 64bit multilib systems)
%{_docdir} %{_datadir}/doc
%{buildroot} %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
$RPM_BUILD_ROOT %{buildroot}
RPM Packaging Guide
How to create a GNU Hello RPM package/zh-cn
Spec File Preamble
RPM打包原理、示例、详解及备查