RPM打包学习(含例子)

目录

1  RPM打包学习

1.1 安装打包工具(服务器环境:openEuler 20.03)

1.2 工作目录

 1.3 .spec文件

2    一个简单的小栗子

3  参考文档

1  RPM打包学习

1.1 安装打包工具(服务器环境:openEuler 20.03)

    打包的rpmbuild命令需要rpm-build包,所以我们可以使用yum安装rpm-build:

yum install rpm-build

或者直接安装rpmdevtools,里面包含了rpm-build和一些其他的工具:

yum install rpmdevtools

我们还可以根据自己的需求安装一些编译工具:

yum install gcc make python

1.2 工作目录

    我们在打包的时候可能要编译源码,并且将编译后得到的二进制包预安装到对应的位置,完成这些需要一个工作目录,我们的编译、预安装、打包和测试等都在这个工作目录中完成。

我们可以使用如下指令在当前位置生成一个工作目录(该指令来自于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目录中编译好的二进制包、配置文件和一些脚本。

 1.3 .spec文件

    打包过程有多个步骤,而.spec文件类似于一个脚本,可以帮我们自动地执行各个步骤的指令,从而实现自动化打包。可以使用如下指令在当前目录创建一个.spec文件模板:

rpmdev-newspec kibana

执行完成后可以发现目录下生成了一个kibana.spec文件:

 进去查看会发现里面部分内容已经帮我们写好:

RPM打包学习(含例子)_第1张图片

其中:

(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目录下。

2    一个简单的小栗子

    没有什么比一个简单的例子更容易上手了,下面我会用一个能输出“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

RPM打包学习(含例子)_第2张图片

源码包准备好了,下面我们开始准备.spec文件,在SPECS目录下使用

rpmdev-newspec hello

生成.spec模板文件,并将其改写成如下样子:

RPM打包学习(含例子)_第3张图片

其中:

(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包。

RPM打包学习(含例子)_第4张图片

安装完成后,在命令行输入hello,可以发现输出了hello world,安装成功!

并且可以看到二进制可执行文件被安装到了服务器的/usr/bin路径下: 

RPM打包学习(含例子)_第5张图片

 最后使用指令

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}

3  参考文档

RPM Packaging Guide

How to create a GNU Hello RPM package/zh-cn

Spec File Preamble

RPM打包原理、示例、详解及备查

你可能感兴趣的:(嵌入式,linux)