news 2026/4/2 7:45:10

构建RPM包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
构建RPM包

打包说明

原理介绍

RPM打包的时候需要编译源码,需要把编译好的配置文件、二进制命令文件等放到合适的位置,还要根据需要对RPM的包进行测试,这些都需要先有一个“工作空间”。rpmbuild命令使用一套标准化的“工作空间”:

$ rpmdev-setuptree

rpmdev-setuptree这个命令就是安装 rpmdevtools 带来的。可以看到运行了这个命令之后,在"/root"目录(非root用户为"/home/用户名"目录)下多了一个 rpmbuild 的文件夹,目录结构如下:

$ tree rpmbuild rpmbuild ├── BUILD ├── RPMS ├── SOURCES ├── SPECS └── SRPMS

内容相关的说明如下:

目录

宏代码

名称

功能

~/rpmbuild/BUILD

%_builddir

构建目录

源码包被解压至此,并在该目录的子目录完成编译

~/rpmbuild/RPMS

%_rpmdir

标准 RPM 包目录

生成/保存二进制 RPM 包

~/rpmbuild/SOURCES

%_sourcedir

源代码目录

保存源码包(如 .tar 包)和所有 patch 补丁

~/rpmbuild/SPECS

%_specdir

Spec 文件目录

保存 RPM 包配置(.spec)文件

~/rpmbuild/SRPMS

%_srcrpmdir

源代码 RPM 包目录

生成/保存源码 RPM 包(SRPM)

SPECS 下是RPM包的配置文件,是RPM打包的“图纸”,这个文件会告诉rpmbuild命令如何去打包。“宏代码”这一列就可以在SPEC文件中用来代指所对应的目录,类似于编程语言中的宏或全局变量。

打包流程

打包的过程主要分为如下步骤:

  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 后,最终得到的文件。

%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 包通常用于审核和升级软件包。

打包选项

通过rpmbuild命令构建软件包。rpmbuild构建软件包一般可以通过构建SPEC文件、tar文件、source文件实现。

rpmbuild命令格式为:rpmbuild [option...]

常用的rpmbuild打包选项如表1所示。

表 1rpmbuild打包选项

option取值

说明

-bpspecfile

specfile文件的%prep段开始构建(解开源码包并打补丁)。

-bcspecfile

specfile文件的%build段开始构建。

-bispecfile

specfile文件的%install段开始构建。

-blspecfile

specfile文件的%file段开始检查。

-baspecfile

通过specfile文件构建源码包和二进制包。

-bbspecfile

通过specfile文件构建二进制包。

-bsspecfile

通过specfile文件构建源码包。

-rpsourcefile

sourcefile文件的%prep段开始构建(解开源码包并打补丁)。

-rcsourcefile

sourcefile文件的%build段开始构建。

-risourcefile

sourcefile文件的%install段开始构建。

-rlsourcefile

sourcefile文件的%file段开始检查。

-rasourcefile

通过sourcefile文件构建源码包和二进制包。

-rbsourcefile

通过sourcefile文件构建二进制包。

-rssourcefile

通过sourcefile文件构建源码包。

-tptarfile

tarfile文件的%prep段开始构建(解开源码包并打补丁)。

-tctarfile

tarfile文件的%build段开始构建。

-titarfile

tarfile文件的%install段开始构建。

-tatarfile

通过tarfile文件构建源码包和二进制包。

-tbtarfile

通过tarfile文件构建二进制包。

-tstarfile

通过tarfile文件构建源码包。

--buildroot=DIRECTORY

在构建时,使用DIRECTORY目录覆盖默认的/root目录。

--clean

完成打包后清除BUILD目录下的文件。

--nobuild

不执行任何实际的构建步骤。可用于测试spec文件。

--noclean

不执行spec文件的"%clean"阶段(即使它确实存在)。

--nocheck

不执行spec文件的"%check"阶段(即使它确实存在)。

--dbpathDIRECTORY

使用DIRECTORY中的数据库,而不是默认的 /var/lib/rpm。

--rootDIRECTORY

使DIRECTORY为最高级别的路径,默认“/”为最高路径。

--rebuildsourcefile

将安装指定的源代码包sourcefile,然后进行准备、编译、安装。

--recompilesourcefile

在--recompile 的基础上额外构建一个新的二进制包。在构建结束时,构建目录、源代码和 spec 文件都将被删除(就好像用了 --clean)。

-?,--help

打印详细的帮助信息。

--version

打印详细的版本信息。

本地构建

本章通过一个简单的示例介绍如何在本地构建RPM软件包的方法。

搭建开发环境(以openEuler为例)

前提条件

需要root权限,已设置openEuler的repo软件源。

操作步骤

用户可以直接使用DNF工具安装 rpmdevtools,其中包含 rpm-build 等命令以及相关依赖(例如make、gdb)。使用如下命令:

# dnf install rpmdevtools*

创建Hello World RPM包

这里以GNU “Hello World” 项目的打包过程作为示例,包含了典型的FOSS(Free and Open Source Software) 软件项目相关的最常用的外围组件,其中包括配置/编译/安装环境、文档、国际化等等。

下载源码

我们直接下载官方例子的源码,使用如下命令:

$ cd ~/rpmbuild/SOURCES $ wget http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
编辑SPEC文件

在**~/rpmbuild/SPECS**目录下新建spec文件,参考命令如下:

$ cd ~/rpmbuild/SPECS $ vi hello.spec

在文件中写入对应内容后保存文件。文件内容示例如下,请根据实际情况修改相应字段。

Name: hello Version: 2.10 Release: 1%{?dist} Summary: The "Hello World" program from GNU Summary(zh_CN): GNU "Hello World" 程序 License: GPLv3+ URL: http://ftp.gnu.org/gnu/hello Source0: http://ftp.gnu.org/gnu/hello/%{name}-%{version}.tar.gz BuildRequires: gettext Requires(post): info Requires(preun): info %description The "Hello World" program, done with all bells and whistles of a proper FOSS project, including configuration, build, internationalization, help files, etc. %description -l zh_CN "Hello World" 程序, 包含 FOSS 项目所需的所有部分, 包括配置, 构建, 国际化, 帮助文件等. %prep %setup -q %build %configure make %{?_smp_mflags} %install make install DESTDIR=%{buildroot} %find_lang %{name} rm -f %{buildroot}/%{_infodir}/dir %post /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || : %preun if [ $1 = 0 ] ; then /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || : fi %files -f %{name}.lang %doc AUTHORS ChangeLog NEWS README THANKS TODO %license COPYING %{_mandir}/man1/hello.1.* %{_infodir}/hello.info.* %{_bindir}/hello %changelog * Thu Dec 26 2019 Your Name <youremail@xxx.xxx> - 2.10-1 - Update to 2.10 * Sat Dec 3 2016 Your Name <youremail@xxx.xxx> - 2.9-1 - Update to 2.9
  • Name 标签是软件名,Version 标签是版本号,而 Release 标签是发布编号。
  • Summary 标签是简要说明,英文的话第一个字母应大写,以避免 rpmlint 工具(打包检查工具)警告。
  • License 标签说明软件包的协议版本,审查软件的 License 状态是打包者的职责,这可以通过检查源码或 LICENSE 文件,或与作者沟通来完成。
  • Group 标签过去用于按照 /usr/share/doc/rpm-/GROUPS 分类软件包。目前该标记已丢弃,vim的模板还有这一条,删掉即可,不过添加该标记也不会有任何影响。%changelog 标签应包含每个 Release 所做的更改日志,尤其应包含上游的安全/漏洞补丁的说明。%changelog 条目应包含版本字符串,以避免 rpmlint 工具警告。
  • 多行的部分,如 %changelog 或 %description 由指令下一行开始,空行结束。
  • 一些不需要的行 (如 BuildRequires 和 Requires) 可在行首使用 ‘#’ 注释。
  • %prep、%build、%install、%file暂时用默认的,未做任何修改。
构建RPM包

构建源码、二进制和包含调试信息的软件包,在spec文件所在目录执行如下命令:

$ rpmbuild -ba hello.spec

执行成功后,查看结果,使用如下命令:

$ tree ~/rpmbuild/*RPMS /home/testUser/rpmbuild/RPMS └── aarch64 ├── hello-2.10-1.aarch64.rpm ├── hello-debuginfo-2.10-1.aarch64.rpm └── hello-debugsource-2.10-1.aarch64.rpm /home/testUser/rpmbuild/SRPMS └── hello-2.10-1.src.rpm

使用OBS构建

本章介绍通过网页和osc构建RPM软件包的方法。主要包括如下两类:

  • 修改已有软件包:修改已有软件包源代码,然后将修改后的源代码构建成一个RPM软件包。
  • 新增软件包:从无到有全新开发一个新的软件源文件,并将新开发的源文件构建成一个RPM软件包。

OBS简介

OBS是基于openSUSE发行版的通用编译框架,用于将源码包构建为RPM软件包或Linux镜像。OBS采用自动化的分布式编译方式,支持多种Linux操作系统发行版(openEuler、SUSE、Debian等)镜像和安装包的编译,且支持在多种架构平台(x86、ARM64等)上编译。

OBS由后端和前端组成,后端实现所有核心功能,前端提供了网页应用和API,用于与后端进行交互。此外,OBS还有一个API命令行客户端osc,osc是在一个单独的存储库中开发的。

OBS使用工程组织软件包。基础的权限控制、相关的存仓库和构建目标(操作系统和架构)都可以在工程中定义。一个工程可以包含多个子工程,各个子工程可以独立配置,共同完成任务。

在线构建软件包

本章介绍通过OBS网页端在线构建RPM软件包的方法。

构建已有软件包

说明:

  • 若为首次使用,请首先在OBS网页注册个人账号。
  • 该方法需要拷贝修改后的代码,因此,请在执行下述操作前完成代码修改并提交到正确的代码路径。代码路径会在_service文件中指定。

使用OBS网页端,修改已有软件的源代码,并将修改后的源文件构建为RPM软件包的操作方法如下:

  1. 登录OBS界面,地址为:https://build.openeuler.openatom.cn/。

  2. 单击“All Projects”进入所有工程页面。

  3. 单击需要修改的对应工程,进入该工程的详情页面,例如单击“openEuler:Mainline”。

  4. 在工程详情页面的搜索框查找需要修改的软件包,然后单击该软件包包名,进入该软件包详情页面。

  5. 单击“Branch package”,在弹出的确认页面单击“Accept”确认创建子工程,如图1所示。

    图 1Branch Confirmation页面

  6. 单击“_service”文件进入编辑页面,修改_service内容后点击“Save”保存该文件。_service内容示例如下,其中userCodeURLuserCommitID分别为用户代码托管路径、用户代码提交版本号或分支。

    <services> <service name="tar_scm_kernel"> <param name="scm">git</param> <param name="url">userCodeURL</param> <param name="revision">userCommitID</param> </service> <service name="recompress"> <param name="compression">bz2</param> <param name="file">*.tar</param> </service> </services>

    说明:
    单击“Save”保存_service文件后,OBS服务会根据_service文件描述,从指定的url下载源码到OBS对应工程的软件目录下并替换原有文件,例如上述例子中 “openEuler:Mainline”工程的kernel目录。

  7. 文件拷贝并替换完成后,OBS会自动开始构建RPM软件包。等待构建完成,并查看右侧状态栏的构建状态。

    • succeeded:构建成功。用户可以单击“succeeded”查看构建日志,如图2所示。

      图 2succeeded的页面

    • failed:构建失败。请单击“failed”查看错误日志进行问题定位后重新构建。

    • unresolvable:未进行构建,可能由于缺失依赖。

    • disabled:构建被手动关闭或正在排队构建。

    • excluded:构建被禁止,可能由于缺少spec文件或者spec文件中禁止了目标架构的编译。

新增软件包

使用OBS网页端,新增一个全新软件包的操作方法如下:

  1. 登录OBS界面。

  2. 根据新增软件包的依赖情况,选择合适的工程,即单击“All Projects”选择对应工程,例如“openEuler:Mainline”。

  3. 单击工程下任一软件包,进入该软件包的详情页面。

  4. 单击“Branch package”,在弹出的确认页面单击“Accept”确认创建子工程。

  5. 单击“Delete package”,删除新创建子工程中的软件包,如图3所示。

    图 3删除子工程中软件包

    说明:
    通过已有软件创建新工程是为了继承环境等依赖,而不需要实际的文件,所以这里需要把这些文件删除。

  6. 单击“Create Package”,在弹出的页面输入软件包名称、标题和软件包描述,然后单击“Create”创建软件包,分别如图4、图5所示。

    图 4Create Package页面

    图 5创建软件包信息填写页面

  7. 在页面中单击“Add file”上传spec文件和需要编译的文件(在spec文件中指定),如图6所示。

    图 6Add file页面

  8. 文件上传成功后,OBS会自动开始构建RPM软件包。等待构建完成,并查看右侧状态栏的构建状态。

获取软件包

RPM软件包构建完成后,通过网页端获取对应RPM软件包的方法如下:

  1. 登录OBS界面。

  2. 单击“All Projects”找到所需软件包的对应工程,例如“openEuler:Mainline”。

  3. 在工程下单击所需软件包的包名,进入该软件包详情页面。例如上述例子中的kernel页面。

  4. 选择Repositories页签进入软件包的软件仓库管理页面,在Publish Flag中通过单击选择“Enable”开启(状态由

    变为

    )对应的RPM软件包下载功能,如图7所示。

    图 7Repositories页面

  5. 单击Repository列的构建工程名称,进入RPM软件包下载页面,单击RPM软件包右侧的“Download”即可下载对应RPM软件包,如图8所示。

    图 8RPM软件包下载页面

使用osc构建软件包

本章介绍使用OBS的命令行工具osc创建工程并构建RPM软件包的方法。

安装并配置osc
前提条件

需要root权限,已设置openEuler的repo软件源。

操作步骤
  1. 使用root用户安装osc命令行工具及依赖。

    # dnf install osc build

    说明:
    编译RPM软件包的过程中会依赖build。

  2. 配置osc。

    1. 打开~/.oscrc,命令如下:

      $ vi ~/.oscrc
    2. 在~/.oscrc中添加user和pass字段,如下所示,它们的取值userNamepassWord分别是用户在OBS网页(https://build.openeuler.openatom.cn/)上已经注册的账号和密码。

      [general] apiurl = https://build.openeuler.openatom.cn/ [https://build.openeuler.openatom.cn/] user=userName pass=passWord
构建已有软件包

创建工程

  1. 通过拷贝已有工程,创建属于用户自己的子工程。例如将openEuler:Mainline工程下的zlib软件包到新分支,参考命令如下:

    $ osc branch openEuler:Mainline zlib

    回显如下所示,说明在用户testUser下创建了新的分支工程home:testUser:branches:openEuler:Mainline。

    A working copy of the branched package can be checked out with: osc co home:testUser:branches:openEuler:Mainline/zlib
  2. 将需要修改软件包的相关配置文件(例如_service)下载到本地当前路径。其中testUser为~/.oscrc配置文件中配置的账户名称,请根据实际情况修改。

    $ osc co home:testUser:branches:openEuler:Mainline/zlib

    回显如下所示:

    A home:testUser:branches:openEuler:Mainline A home:testUser:branches:openEuler:Mainline/zlib A home:testUser:branches:openEuler:Mainline/zlib/_service
  3. 进入本地子工程目录,并将软件包远程代码同步到本地。

    $ cd home:testUser:branches:openEuler:Mainline/zlib $ osc up -S

    回显如下所示:

    A _service:tar_scm_kernel_repo:0001-Neon-Optimized-hash-chain-rebase.patch A _service:tar_scm_kernel_repo:0002-Porting-optimized-longest_match.patch A _service:tar_scm_kernel_repo:0003-arm64-specific-build-patch.patch A _service:tar_scm_kernel_repo:zlib-1.2.11-optimized-s390.patch A _service:tar_scm_kernel_repo:zlib-1.2.11.tar.xz A _service:tar_scm_kernel_repo:zlib-1.2.5-minizip-fixuncrypt.patch A _service:tar_scm_kernel_repo:zlib.spec

构建RPM包

  1. 重命名源文件,然后将重命名后的源文件添加到OBS暂存中。

    $ rm -f _service;for file in `ls | grep -v .osc`;do new_file=${file##*:};mv $file $new_file;done $ osc addremove *
  2. 修改源代码和spec文件,并执行如下命令更新文件。

    $ osc up
  3. 将对应软件包的所有修改同步到OBS服务器。参考命令如下,-m参数后的信息为提交记录。

    $ osc ci -m "commit log"
  4. 获取当前工程的仓库名称和架构,参考命令如下:

    $ osc repos home:testUser:branches:openEuler:Mainline
  5. 修改提交成功后,OBS会自动开始编译软件包。可以通过如下命令,查看对应仓库的编译日志,其中standard_aarch64aarch64分别为查询所得仓库名称和架构。

    $ osc buildlog standard_aarch64 aarch64

    说明:
    用户也可以通过网页端打开自己创建的对应工程,查看构建日志。

新增软件包

使用OBS的osc工具新增一个全新软件包的操作方法如下:

创建工程

  1. 根据新增软件包的依赖情况,基于合适的工程,创建属于用户自己的个人工程。例如基于openEuler:Mainline工程的 zlib 创建工程的参考命令如下,zlib 为工程下的任一软件包。

    $ osc branch openEuler:Mainline zlib
  2. 删除创建工程时新增的无用软件包。例如删除zlib软件包的参考命令如下:

    $ cd home:testUser:branches:openEuler:Mainline $ osc rm zlib $ osc commit -m "commit log"
  3. 在个人工程下创建新增的软件包。例如新增软件包 my-first-obs-package命令如下:

    $ mkdir my-first-obs-package $ cd my-first-obs-package

构建RPM包

  1. 添加准备的源文件和spec文件到软件包目录。

  2. 修改源代码和spec文件,并将对应软件包的所有文件上传到OBS服务器。参考命令如下,-m 参数后的信息为提交记录。

    $ cd home:testUser:branches:openEuler:Mainline $ osc add my-first-obs-package $ osc ci -m "commit log"
  3. 获取当前工程的仓库名称和架构,参考命令如下:

    $ osc repos home:testUser:branches:openEuler:Mainline
  4. 修改提交成功后,OBS会自动开始编译软件包。可以通过如下命令,查看对应仓库的编译日志,其中standard_aarch64aarch64分别为查询所得仓库名称和架构。

    $ cd home:testUser:branches:openEuler:Mainline/my-first-obs-package $ osc buildlog standard_aarch64 aarch64

    说明:
    用户也可以通过网页端打开自己创建的对应工程,查看构建日志。

获取软件包

RPM软件包构建完成后,使用osc获取对应RPM软件包的命令如下:

$ osc getbinaries home:testUser:branches:openEuler:Mainline my-first-obs-package standard_aarch64 aarch64

命令中的各参数含义如下,请用户根据实际情况修改:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 8:48:07

新品发布 | 生产、制造及售后领域强有力的VCI接口M810

MC810是MC产品系列的又一个强大的VCI。凭借紧凑的设计和WiFi、USB及蓝牙作为主机系统的接口&#xff0c;以及CAN(FD)、以太网到车辆&#xff0c;MC810特别适合面向未来的制造和售后服务应用。一、应用场景下图展示了通过车辆通信卡进行诊断测试的系统框图。其中&#xff0c;PC可…

作者头像 李华
网站建设 2026/3/29 20:42:10

LLaMA Factory微调大模型完整指南:从数据准备到API部署

本文详细介绍了使用LLaMA Factory对大语言模型进行指令监督微调(SFT)的完整流程。从数据准备、清洗和格式化开始&#xff0c;讲解了全量微调(Full FT)和参数高效微调(PEFT/LoRA)两种技术方法&#xff0c;最后通过LLaMA Factory API和Ollama API实现模型部署。文章提供了详细的配…

作者头像 李华
网站建设 2026/3/30 18:09:41

谷歌PH-LLM大模型:可穿戴设备数据的健康洞察革命

谷歌推出基于Gemini模型的PH-LLM大模型和智能Agent系统&#xff0c;能够分析可穿戴设备数据并生成个性化健康建议。PH-LLM在睡眠和健身领域表现接近专家水平&#xff0c;而智能Agent可通过迭代推理提供准确健康洞察。这两项技术为开发真正个性化的健康助手奠定基础&#xff0c;…

作者头像 李华
网站建设 2026/3/25 9:46:42

效率提升超24倍!如何实现财务报表OCR识别自动录入?

借助智能财报录入系统&#xff0c;银行将PDF、图片等非结构化财报秒级转为结构化数据。该方案能精准解析印章遮挡及跨页表格&#xff0c;通过自动勾稽校验确保准确性&#xff0c;将作业效率提升超24倍&#xff0c;解决人工录入效率低、易出错的痛点。 为什么银行必须升级到智能…

作者头像 李华
网站建设 2026/4/1 22:07:58

69、《gawk 编程语言与源代码管理系统入门》

《gawk 编程语言与源代码管理系统入门》 1. gawk 编程语言基础 gawk 是一种功能强大的文本处理语言,拥有丰富的控制结构和内置函数。 1.1 控制结构 if 语句 :用于条件判断,语法如下: if (condition)statement1 [elsestatement2]如果 condition 为真,则执行 state…

作者头像 李华