Bootstrap

从零开始构建 RPM 包

一、说明

本教程通过一个简单示例从 0 开始构建一个 RPM 包。

二、参考

https://www.cnblogs.com/zafu/p/7423758.html
https://ftp.osuosl.org/pub/rpm/max-rpm/
https://www.linuxprobe.com/how-rpm-spec.html
https://www.cnblogs.com/michael-xiang/p/10480809.html
https://www.cnblogs.com/LiuYanYGZ/p/9566353.html
http://bbs.chinaunix.net/thread-4179207-1-1.html
https://younger.blog.csdn.net/article/details/53131105
https://younger.blog.csdn.net/article/details/53131071
https://younger.blog.csdn.net/article/details/53131170
https://younger.blog.csdn.net/article/details/53131128
https://www.jianshu.com/p/691189360ede
https://blog.csdn.net/taget/article/details/8493596
https://blog.csdn.net/u011057409/article/details/122162170
https://zhuanlan.zhihu.com/p/47868584
https://blog.csdn.net/chengfei112233/article/details/7641923
https://www.linuxidc.com/Linux/2019-02/157098.htm

三、使用工具

1、yum

1、介绍

yum( Yellow dog Updater, Modified)是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。

基于 RPM 包管理,能够从指定的服务器自动下载 RPM 包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。

yum 提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。

2、yum参数

[lq@laptop-7nmg10e6 ~]$ yum --help
usage: yum [options] COMMAND

主要命令列表:

alias                     列出或创建命令别名
autoremove                删除所有原先因为依赖关系安装的不需要的软件包
check                     在包数据库中寻找问题
check-update              检查是否有软件包升级
clean                     删除已缓存的数据
deplist                   [已弃用,请使用 repoquery --deplist] 列出软件包的依赖关系和提供这些软件包的源
distro-sync               同步已经安装的软件包到最新可用版本
downgrade                 降级包
group                     显示或使用组信息
help                      显示一个有帮助的用法信息
history                   显示或使用事务历史
info                      显示关于软件包或软件包组的详细信息
install                   向系统中安装一个或多个软件包
list                      列出一个或一组软件包
makecache                 创建元数据缓存
mark                      在已安装的软件包中标记或者取消标记由用户安装的软件包。
module                    与模块交互。
provides                  查找提供指定内容的软件包
reinstall                 重装一个包
remove                    从系统中移除一个或多个软件包
repolist                  显示已配置的软件仓库
repoquery                 搜索匹配关键字的软件包
repository-packages       对指定仓库中的所有软件包运行命令
search                    在软件包详细信息中搜索指定字符串
shell                     运行一个交互式的 YUM shell
swap                      运行一个交互式的 YUM mod 以删除或安装 spec
updateinfo                显示软件包的参考建议
upgrade                   升级系统中的一个或多个软件包
upgrade-minimal           升级,但只有“最新”的软件包已修复可能影响你的系统的问题

插件命令列表:

builddep                  Install build dependencies for package or spec file
changelog                 查看软件包的改变日志数据
config-manager            管理 yum 配置选项和软件仓库
copr                      与 Copr 仓库交互。
debug-dump                转储已安装的 RPM 软件包信息至文件
debug-restore             恢复调试用转储文件中的软件包记录
debuginfo-install         安装调试信息软件包
download                  下载软件包至当前目录
groups-manager            创建并编辑组元数据文件
kpatch                    Toggles automatic installation of kpatch-patch packages
needs-restarting          判断所升级的二进制文件是否需要重启
playground                与 Playground 仓库交互。
repoclosure               显示仓库中未被解决的依赖关系的列表
repodiff                  列出两组仓库中的不同
repograph                 以点线图方式输出完整的软件包依赖关系图
repomanage                管理 RPM 软件包目录
reposync                  下载远程仓库中的全部软件包

General YUM options:
  -c [config file], --config [config file]
                        配置文件位置
  -q, --quiet           静默执行
  -v, --verbose         详尽执行
  --version             显示 YUM 的版本并退出
  --installroot [path]  设置目标根目录
  --nodocs              不要安装文档
  --noplugins           禁用所有插件
  --enableplugin [plugin]
                        启用指定名称的插件
  --disableplugin [plugin]
                        禁用指定名称的插件
  --releasever RELEASEVER
                        覆盖在配置文件和仓库文件中 $releasever 的值
  --setopt SETOPTS      设置任意配置和仓库选项
  --skip-broken         通过跳过软件包来解决依赖问题
  -h, --help, --help-cmd
                        显示命令帮助
  --allowerasing        允许解决依赖关系时删除已安装软件包
  -b, --best            在事务中尝试最佳软件包版本。
  --nobest              不将事务限制在最佳候选
  -C, --cacheonly       完全从系统缓存运行,不升级缓存
  -R [minutes], --randomwait [minutes]
                        最大命令等待时间
  -d [debug level], --debuglevel [debug level]
                        调试输出级别
  --debugsolver         转储详细解决结果至文件
  --showduplicates      在 list/search 命令下,显示仓库里重复的条目
  -e ERRORLEVEL, --errorlevel ERRORLEVEL
                        错误输出级别
  --obsoletes           对 upgrade 启用 yum 的过期处理逻辑,或对 info、list 和 repoquery
                        启用软件包过期的显示功能
  --rpmverbosity [debug level name]
                        rpm调试输出等级
  -y, --assumeyes       全部问题自动应答为是
  --assumeno            全部问题自动应答为否
  --enablerepo [repo]   启用附加仓库。列出选项。支持通配符,可以指定多次。
  --disablerepo [repo]  停用仓库。列出选项。支持通配符,可指定多次。
  --repo [repo], --repoid [repo]
                        启用指定 id 或 glob 的仓库,可以指定多次
  --enable              使用 config-manager 命令启用 repos (自动保存)
  --disable             使用 config-manager 命令禁用 repos (自动保存)
  -x [package], --exclude [package], --excludepkgs [package]
                        用全名或通配符排除软件包
  --disableexcludes [repo], --disableexcludepkgs [repo]
                        禁用 excludepkgs
  --repofrompath [repo,path]
                        附加仓库所要使用的标签和路径(与 baseurl 中的路径一致),可以指定多次。
  --noautoremove        禁用删除不再被使用的依赖软件包
  --nogpgcheck          禁用 gpg 签名检查 (如果 RPM 策略允许)
  --color COLOR         配置是否使用颜色
  --refresh             在运行命令之前将元数据标记为过期
  -4                    仅解析 IPv4 地址
  -6                    仅解析 IPv6 地址
  --destdir DESTDIR, --downloaddir DESTDIR
                        设置软件包要复制到的目录
  --downloadonly        仅下载软件包
  --comment COMMENT     为事务添加一个注释
  --bugfix              在更新中包括与 bug 修复有关的软件包
  --enhancement         在更新中包括与功能增强有关的软件包
  --newpackage          在更新中包括与新软件包有关的软件包
  --security            在更新中包括与安全有关的软件包
  --advisory ADVISORY, --advisories ADVISORY
                        在更新中包括修复指定公告所必须的软件包
  --bz BUGZILLA, --bzs BUGZILLA
                        在更新中包括修复给定 BZ 所必须的软件包
  --cve CVES, --cves CVES
                        在更新中包括修复给定 CVE 所必须的软件包
  --sec-severity {Critical,Important,Moderate,Low}, --secseverity {Critical,Important,Moderate,Low}
                        在更新中包括匹配给定安全等级的安全相关的软件包
  --forcearch ARCH      强制使用一个架构
[lq@laptop-7nmg10e6 ~]$ 

3、示例

1、列出所有可更新软件清单**命令:yum check-update

2、更新所有软件命令:yum update

3、仅安装指定的软件命令:yum install <package_name>

4、仅更新指定的软件命令:yum update <package_name>

5、列出所有可安裝软件清单命令:yum list

6、删除软件包命令:yum remove <package_name>

7、查找软件包命令:yum search

8、清除缓存命令:

  • yum clean packages: 清除缓存目录下的软件包
  • yum clean headers: 清除缓存目录下的 headers
  • yum clean oldheaders: 清除缓存目录下旧的 headers
  • yum clean, yum clean all (= yum clean packages; yum clean oldheaders) :清除缓存目录下的软件包及旧的 headers

2、rpm

1、介绍

rpm(英文全拼:redhat package manager) 原本是 Red Hat Linux 发行版专门用来管理 Linux 各项套件的程序,由于它遵循 GPL 规则且功能强大方便,因而广受欢迎。逐渐受到其他发行版的采用。RPM 套件管理方式的出现,让 Linux 易于安装,升级,间接提升了 Linux 的适用度。

2、rpm参数

[lq@laptop-7nmg10e6 ~]$ rpm --help
用法: rpm [选项...]

查询/验证软件包选项:
  -a, --all                          查询/验证所有软件包
  -f, --file                         query/verify package(s) owning installed file
      --path                         query/verify package(s) owning path, installed or not
  -g, --group                        查询/验证组中的软件包
  -p, --package                      查询/验证一个软件包
      --pkgid                        根据软件包标识符查找/校验软件包
      --hdrid                        根据头部标识符查找/校验软件包
      --triggeredby                  查找由软件包所触发的软件包
      --whatconflicts                查找/校验需要某个依赖对象的软件包
      --whatrequires                 查找/校验需要某个依赖对象的软件包
      --whatobsoletes                query/verify the package(s) which obsolete a dependency
      --whatprovides                 查询/验证提供相关依赖的软件包
      --whatrecommends               query/verify the package(s) which recommends a dependency
      --whatsuggests                 query/verify the package(s) which suggests a dependency
      --whatsupplements              query/verify the package(s) which supplements a dependency
      --whatenhances                 query/verify the package(s) which enhances a dependency
      --nomanifest                   不把非软件包文件作为清单处理

查询选项(用 -q 或 --query):
  -c, --configfiles                  列出所有配置文件
  -d, --docfiles                     列出所有程序文档
  -L, --licensefiles                 列出所有许可证文件
  -A, --artifactfiles                list all artifact files
      --dump                         转储基本文件信息
  -l, --list                         列出软件包中的文件
      --queryformat=QUERYFORMAT      使用这种格式打印信息
  -s, --state                        显示列出文件的状态

验证选项(用 -V 或 --verify):
      --nofiledigest                 不验证文件摘要
      --nofiles                      不验证软件包中文件
      --nodeps                       不验证包依赖
      --noscript                     不执行验证脚本

安装/升级/擦除选项:
      --allfiles                     安装全部文件,包含配置文件,否则配置文件会被跳过。
      --allmatches                   移除所有符合 <package> 的软件包(如果 <package>
                                     被指定未多个软件包,常常会导致错误出现)
      --badreloc                     对不可重定位的软件包重新分配文件位置
  -e, --erase=<package>+             清除 (卸载) 软件包
      --excludedocs                  不安装程序文档
      --excludepath=<path>           略过以 <path> 开头的文件
      --force                        --replacepkgs --replacefiles 的缩写
  -F, --freshen=<packagefile>+       如果软件包已经安装,升级软件包
  -h, --hash                         软件包安装的时候列出哈希标记 (和 -v 一起使用效果更好)
      --ignorearch                   不验证软件包架构
      --ignoreos                     不验证软件包操作系统
      --ignoresize                   在安装前不检查磁盘空间
      --noverify                     short hand for --ignorepayload --ignoresignature
  -i, --install                      安装软件包
      --justdb                       更新数据库,但不修改文件系统
      --nodeps                       不验证软件包依赖
      --nofiledigest                 不验证文件摘要
      --nocontexts                   不安装文件的安全上下文
      --nocaps                       don't install file capabilities
      --noorder                      不对软件包安装重新排序以满足依赖关系
      --noscripts                    不执行软件包小脚本
      --notriggers                   不执行本软件包触发的任何小脚本
      --oldpackage                   更新到软件包的旧版本(带 --force 自动完成这一功能)
      --percent                      安装软件包时打印百分比
      --prefix=<dir>                 如果可重定位,便把软件包重定位到 <dir>
      --relocate=<old>=<new>         将文件从 <old> 重定位到 <new>
      --replacefiles                 忽略软件包之间的冲突的文件
      --replacepkgs                  如果软件包已经有了,重新安装软件包
      --test                         不真正安装,只是判断下是否能安装
  -U, --upgrade=<packagefile>+       升级软件包
      --reinstall=<packagefile>+     重新安装软件包

所有 rpm 模式和可执行文件的通用选项:
  -D, --define=“MACRO EXPR”          定义值为 EXPR 的 MACRO
      --undefine=MACRO               未定义的 MACRO
  -E, --eval=“EXPR”                  打印 EXPR 的宏展开
      --target=CPU-VENDOR-OS         Specify target platform
      --macros=<FILE:…>              从文件 <FILE:...> 读取宏,不使用默认文件
      --noplugins                    不要启用任何插件
      --nodigest                     不校验软件包的摘要
      --nosignature                  不验证软件包签名
      --rcfile=<FILE:…>              从文件 <FILE:...> 读取宏,不使用默认文件
  -r, --root=ROOT                    使用 ROOT 作为顶级目录 (default: "/")
      --dbpath=DIRECTORY             使用 DIRECTORY 目录中的数据库
      --querytags                    显示已知的查询标签
      --showrc                       显示最终的 rpmrc 和宏配置
      --quiet                        提供更少的详细信息输出
  -v, --verbose                      提供更多的详细信息输出
      --version                      打印使用的 rpm 版本号

Options implemented via popt alias/exec:
      --scripts                      list install/erase scriptlets from package(s)
      --setperms                     set permissions of files in a package
      --setugids                     set user/group ownership of files in a package
      --setcaps                      set capabilities of files in a package
      --restore                      restore file/directory permissions
      --conflicts                    list capabilities this package conflicts with
      --obsoletes                    list other packages removed by installing this package
      --provides                     list capabilities that this package provides
      --requires                     list capabilities required by package(s)
      --recommends                   list capabilities recommended by package(s)
      --suggests                     list capabilities suggested by package(s)
      --supplements                  list capabilities supplemented by package(s)
      --enhances                     list capabilities enhanced by package(s)
      --info                         list descriptive information from package(s)
      --changelog                    list change logs for this package
      --changes                      list changes for this package with full time stamps
      --xml                          list metadata in xml
      --triggers                     list trigger scriptlets from package(s)
      --filetriggers                 list filetrigger scriptlets from package(s)
      --last                         list package(s) by install time, most recent first
      --dupes                        list duplicated packages
      --filesbypkg                   list all files from each package
      --fileclass                    list file names with their classes
      --filecolor                    list file names with their colors
      --fileprovide                  list file names with their provides
      --filerequire                  list file names with requires
      --filecaps                     list file names with their POSIX1.e capabilities

帮助选项:
  -?, --help                         显示这个帮助信息
      --usage                        显示简短的使用说明
[lq@laptop-7nmg10e6 ~]$ 

3、示例

1、安装软件包

rpm -ivh packge.rpm 

2、忽略报错,强制安装

rpm --force -ivh package.rpm

3、列出所有安装过的包

rpm -qa

4、获得软件包的文件全名

rpm -q vsftpd

获得软件包相关的信息用 rpm -q,q表示查询query,后面可以跟其他选项,比如

  • i 表示info,获得软件包的信息;
  • l 表示list,获得文件列表;
  • a 表示all,在所有包中执行查询;
  • f 表示file,根据文件进行相关的查询;
  • p 表示package,根据软件包进行查询;

5、卸载 rpm 包

rpm -e package.rpm 

6、升级软件包

rpm -U file.rpm

7、哪个软件包包含这个程序

rpm -qf `which 程序名`    #返回软件包的全名

rpm -qif `which 程序名`   #返回软件包的有关信息

rpm -qlf `which 程序名`   #返回软件包的文件列表[root@localhost ~]# rpm -qf `which sshd`

3、rpmbuild

1、介绍

rpmbuild 用于创建创建 rpm 包。

2、rpmbuild命令安装

[root@laptop-7nmg10e6 ~]# yum install rpm-build
上次元数据过期检查:1:47:03 前,执行于 2022年04月30日 星期六 01时06分05秒。
依赖关系解决。
============================================================================================================================
 软件包                               架构                   版本                           仓库                       大小
============================================================================================================================
安装:
 rpm-build                            x86_64                 4.14.3-23.el8                  appstream                 174 k
安装依赖关系:
 dwz                                  x86_64                 0.12-10.el8                    appstream                 109 k
 efi-srpm-macros                      noarch                 3-3.el8                        appstream                  22 k
 elfutils                             x86_64                 0.186-1.el8                    baseos                    542 k
 gc                                   x86_64                 7.6.4-3.el8                    appstream                 109 k
 gdb-headless                         x86_64                 8.2-18.el8                     appstream                 3.7 M
 ghc-srpm-macros                      noarch                 1.4.2-7.el8                    appstream                 9.3 k
 go-srpm-macros                       noarch                 2-17.el8                       appstream                  13 k
 guile                                x86_64                 5:2.0.14-7.el8                 appstream                 3.5 M
 libatomic_ops                        x86_64                 7.6.2-3.el8                    appstream                  38 k
 libbabeltrace                        x86_64                 1.5.4-4.el8                    baseos                    200 k
 libipt                               x86_64                 1.6.1-8.el8                    appstream                  50 k
 ocaml-srpm-macros                    noarch                 5-4.el8                        appstream                 9.4 k
 openblas-srpm-macros                 noarch                 2-2.el8                        appstream                 7.9 k
 patch                                x86_64                 2.7.6-11.el8                   baseos                    138 k
 perl-srpm-macros                     noarch                 1-25.el8                       appstream                  11 k
 python-rpm-macros                    noarch                 3-41.el8                       appstream                  15 k
 python-srpm-macros                   noarch                 3-41.el8                       appstream                  15 k
 python3-rpm-macros                   noarch                 3-41.el8                       appstream                  14 k
 qt5-srpm-macros                      noarch                 5.15.3-1.el8                   appstream                  11 k
 redhat-rpm-config                    noarch                 127-1.el8                      appstream                  88 k
 rust-srpm-macros                     noarch                 5-2.el8                        appstream                 9.2 k
 zstd                                 x86_64                 1.4.4-1.el8                    appstream                 393 k

事务概要
============================================================================================================================
安装  23 软件包

总下载:9.1 M
安装大小:29 M
确定吗?[y/N]: y
下载软件包:
(1/23): efi-srpm-macros-3-3.el8.noarch.rpm                                                  162 kB/s |  22 kB     00:00    
(2/23): gc-7.6.4-3.el8.x86_64.rpm                                                           861 kB/s | 109 kB     00:00    
(3/23): dwz-0.12-10.el8.x86_64.rpm                                                          603 kB/s | 109 kB     00:00    
(4/23): ghc-srpm-macros-1.4.2-7.el8.noarch.rpm                                              124 kB/s | 9.3 kB     00:00    
(5/23): go-srpm-macros-2-17.el8.noarch.rpm                                                  122 kB/s |  13 kB     00:00    
(6/23): libatomic_ops-7.6.2-3.el8.x86_64.rpm                                                 54 kB/s |  38 kB     00:00    
(7/23): libipt-1.6.1-8.el8.x86_64.rpm                                                        48 kB/s |  50 kB     00:01    
(8/23): ocaml-srpm-macros-5-4.el8.noarch.rpm                                                 39 kB/s | 9.4 kB     00:00    
(9/23): openblas-srpm-macros-2-2.el8.noarch.rpm                                              33 kB/s | 7.9 kB     00:00    
(10/23): perl-srpm-macros-1-25.el8.noarch.rpm                                                30 kB/s |  11 kB     00:00    
(11/23): gdb-headless-8.2-18.el8.x86_64.rpm                                                 1.2 MB/s | 3.7 MB     00:02    
(12/23): python-rpm-macros-3-41.el8.noarch.rpm                                               62 kB/s |  15 kB     00:00    
(13/23): python-srpm-macros-3-41.el8.noarch.rpm                                              87 kB/s |  15 kB     00:00    
(14/23): python3-rpm-macros-3-41.el8.noarch.rpm                                              90 kB/s |  14 kB     00:00    
(15/23): guile-2.0.14-7.el8.x86_64.rpm                                                      1.1 MB/s | 3.5 MB     00:03    
(16/23): qt5-srpm-macros-5.15.3-1.el8.noarch.rpm                                             80 kB/s |  11 kB     00:00    
(17/23): redhat-rpm-config-127-1.el8.noarch.rpm                                             676 kB/s |  88 kB     00:00    
(18/23): rust-srpm-macros-5-2.el8.noarch.rpm                                                152 kB/s | 9.2 kB     00:00    
(19/23): rpm-build-4.14.3-23.el8.x86_64.rpm                                                 879 kB/s | 174 kB     00:00    
(20/23): zstd-1.4.4-1.el8.x86_64.rpm                                                        1.3 MB/s | 393 kB     00:00    
(21/23): libbabeltrace-1.5.4-4.el8.x86_64.rpm                                               406 kB/s | 200 kB     00:00    
(22/23): patch-2.7.6-11.el8.x86_64.rpm                                                      333 kB/s | 138 kB     00:00    
(23/23): elfutils-0.186-1.el8.x86_64.rpm                                                    730 kB/s | 542 kB     00:00    
----------------------------------------------------------------------------------------------------------------------------
总计                                                                                        1.6 MB/s | 9.1 MB     00:05     
CentOS Stream 8 - AppStream                                                                 1.6 MB/s | 1.6 kB     00:00    
导入 GPG 公钥 0x8483C65D:
 Userid: "CentOS (CentOS Official Signing Key) <[email protected]>"
 指纹: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
 来自: /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
确定吗?[y/N]: y
导入公钥成功
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                                             1/1 
  安装    : python-srpm-macros-3-41.el8.noarch                                                                         1/23 
  安装    : python-rpm-macros-3-41.el8.noarch                                                                          2/23 
  安装    : python3-rpm-macros-3-41.el8.noarch                                                                         3/23 
  安装    : patch-2.7.6-11.el8.x86_64                                                                                  4/23 
  安装    : libbabeltrace-1.5.4-4.el8.x86_64                                                                           5/23 
  运行脚本: libbabeltrace-1.5.4-4.el8.x86_64                                                                           5/23 
  安装    : elfutils-0.186-1.el8.x86_64                                                                                6/23 
  安装    : zstd-1.4.4-1.el8.x86_64                                                                                    7/23 
  安装    : rust-srpm-macros-5-2.el8.noarch                                                                            8/23 
  安装    : qt5-srpm-macros-5.15.3-1.el8.noarch                                                                        9/23 
  安装    : perl-srpm-macros-1-25.el8.noarch                                                                          10/23 
  安装    : openblas-srpm-macros-2-2.el8.noarch                                                                       11/23 
  安装    : ocaml-srpm-macros-5-4.el8.noarch                                                                          12/23 
  安装    : libipt-1.6.1-8.el8.x86_64                                                                                 13/23 
  安装    : libatomic_ops-7.6.2-3.el8.x86_64                                                                          14/23 
  安装    : gc-7.6.4-3.el8.x86_64                                                                                     15/23 
  安装    : guile-5:2.0.14-7.el8.x86_64                                                                               16/23 
  运行脚本: guile-5:2.0.14-7.el8.x86_64                                                                               16/23 
  安装    : gdb-headless-8.2-18.el8.x86_64                                                                            17/23 
  安装    : go-srpm-macros-2-17.el8.noarch                                                                            18/23 
  安装    : ghc-srpm-macros-1.4.2-7.el8.noarch                                                                        19/23 
  安装    : efi-srpm-macros-3-3.el8.noarch                                                                            20/23 
  安装    : dwz-0.12-10.el8.x86_64                                                                                    21/23 
  安装    : redhat-rpm-config-127-1.el8.noarch                                                                        22/23 
  安装    : rpm-build-4.14.3-23.el8.x86_64                                                                            23/23 
  运行脚本: guile-5:2.0.14-7.el8.x86_64                                                                               23/23 
  运行脚本: rpm-build-4.14.3-23.el8.x86_64                                                                            23/23 
  验证    : dwz-0.12-10.el8.x86_64                                                                                     1/23 
  验证    : efi-srpm-macros-3-3.el8.noarch                                                                             2/23 
  验证    : gc-7.6.4-3.el8.x86_64                                                                                      3/23 
  验证    : gdb-headless-8.2-18.el8.x86_64                                                                             4/23 
  验证    : ghc-srpm-macros-1.4.2-7.el8.noarch                                                                         5/23 
  验证    : go-srpm-macros-2-17.el8.noarch                                                                             6/23 
  验证    : guile-5:2.0.14-7.el8.x86_64                                                                                7/23 
  验证    : libatomic_ops-7.6.2-3.el8.x86_64                                                                           8/23 
  验证    : libipt-1.6.1-8.el8.x86_64                                                                                  9/23 
  验证    : ocaml-srpm-macros-5-4.el8.noarch                                                                          10/23 
  验证    : openblas-srpm-macros-2-2.el8.noarch                                                                       11/23 
  验证    : perl-srpm-macros-1-25.el8.noarch                                                                          12/23 
  验证    : python-rpm-macros-3-41.el8.noarch                                                                         13/23 
  验证    : python-srpm-macros-3-41.el8.noarch                                                                        14/23 
  验证    : python3-rpm-macros-3-41.el8.noarch                                                                        15/23 
  验证    : qt5-srpm-macros-5.15.3-1.el8.noarch                                                                       16/23 
  验证    : redhat-rpm-config-127-1.el8.noarch                                                                        17/23 
  验证    : rpm-build-4.14.3-23.el8.x86_64                                                                            18/23 
  验证    : rust-srpm-macros-5-2.el8.noarch                                                                           19/23 
  验证    : zstd-1.4.4-1.el8.x86_64                                                                                   20/23 
  验证    : elfutils-0.186-1.el8.x86_64                                                                               21/23 
  验证    : libbabeltrace-1.5.4-4.el8.x86_64                                                                          22/23 
  验证    : patch-2.7.6-11.el8.x86_64                                                                                 23/23 

已安装:
  dwz-0.12-10.el8.x86_64                   efi-srpm-macros-3-3.el8.noarch          elfutils-0.186-1.el8.x86_64            
  gc-7.6.4-3.el8.x86_64                    gdb-headless-8.2-18.el8.x86_64          ghc-srpm-macros-1.4.2-7.el8.noarch     
  go-srpm-macros-2-17.el8.noarch           guile-5:2.0.14-7.el8.x86_64             libatomic_ops-7.6.2-3.el8.x86_64       
  libbabeltrace-1.5.4-4.el8.x86_64         libipt-1.6.1-8.el8.x86_64               ocaml-srpm-macros-5-4.el8.noarch       
  openblas-srpm-macros-2-2.el8.noarch      patch-2.7.6-11.el8.x86_64               perl-srpm-macros-1-25.el8.noarch       
  python-rpm-macros-3-41.el8.noarch        python-srpm-macros-3-41.el8.noarch      python3-rpm-macros-3-41.el8.noarch     
  qt5-srpm-macros-5.15.3-1.el8.noarch      redhat-rpm-config-127-1.el8.noarch      rpm-build-4.14.3-23.el8.x86_64         
  rust-srpm-macros-5-2.el8.noarch          zstd-1.4.4-1.el8.x86_64                

完毕!
[root@laptop-7nmg10e6 ~]# 

3、rpmbuild参数

[root@laptop-7nmg10e6 ~]# rpmbuild --help
用法: rpmbuild [选项...]

适用于 [ <specfile> | <tarball> | <source package> ] 的构建选项:
      -bp                        依据 <specfile> 从 %prep (解压缩源代码并应用补丁) 开始构建
      -bc                        依据 <specfile> 从 %build (%prep 之后编译) 开始构建
      -bi                        依据 <specfile> 从 %install (%prep、%build 后安装) 开始构建
      -bl                        依据 <specfile> 校验 %files 部分
      -ba                        依据 <specfile> 构建源代码和二进制软件包
      -bb                        依据 <specfile> 构建二进制软件包
      -bs                        依据 <specfile> 构建源代码软件包
      -rp                        仅执行 <source package> 的 %prep 部分(解压缩源代码并应用补丁) 
      -rc                        仅执行 <source package> 的 %build 部分(先执行 %prep,然后 %build)
      -ri                        依据 <source package> 从 %install (%prep、%build 然后安装)开始构建
      -rl                        依据 <source package> 校验 %files 部分
      -ra                        从 <source package> 中构建二进制和源代码 RPM 包
      -rb                        仅从 <source package> 中构建二进制 RPM 包
      -rs                        仅从 <source package> 中构建源代码 RPM 包
      -tp                        依据 <tarball> 从 %prep (解压源代码并应用补丁)开始构建
      -tc                        依据 <tarball> 从 %build (%prep,之后编译)开始构建
      -ti                        依据 <tarball> 从 %install (%prep、%build 然后安装)开始构建
      -ta                        依据 <tarball> 构建源代码和二进制软件包
      -tb                        依据 <tarball> 构建二进制软件包
      -ts                        依据 <tarball> 构建源代码软件包
      --rebuild                  依据 <source package> 构建二进制软件包
      --recompile                依据 <source package> 从 %install (%prep、%build 然后安装)开始构建
      --buildroot=DIRECTORY      重载构建根路径
      --build-in-place           在当前目录中构建
      --clean                    完成后移除构建树
      --nobuild                  不执行任何构建步骤 
      --nodeps                   不检验构建依赖
      --nodirtokens              生成和 rpm v3 包管理(旧版本)兼容的软件包头
      --noclean                  构建过程中不执行 %clean 步骤
      --noprep                   不执行构建的 %prep 阶段
      --nocheck                  构建过程中不执行 %check 步骤
      --rmsource                 完成时移除源代码
      --rmspec                   完成时移除 specfile
      --short-circuit            直接跳转到指定步骤 (仅限 c,i)
      --target=CPU-VENDOR-OS     重载目标平台

所有 rpm 模式和可执行文件的通用选项:
  -D, --define=“MACRO EXPR”      定义值为 EXPR 的 MACRO
      --undefine=MACRO           未定义的 MACRO
  -E, --eval=“EXPR”              打印 EXPR 的宏展开
      --target=CPU-VENDOR-OS     Specify target platform
      --macros=<FILE:…>          从文件 <FILE:...> 读取宏,不使用默认文件
      --noplugins                不要启用任何插件
      --nodigest                 不校验软件包的摘要
      --nosignature              不验证软件包签名
      --rcfile=<FILE:…>          从文件 <FILE:...> 读取宏,不使用默认文件
  -r, --root=ROOT                使用 ROOT 作为顶级目录 (default: "/")
      --dbpath=DIRECTORY         使用 DIRECTORY 目录中的数据库
      --querytags                显示已知的查询标签
      --showrc                   显示最终的 rpmrc 和宏配置
      --quiet                    提供更少的详细信息输出
  -v, --verbose                  提供更多的详细信息输出
      --version                  打印使用的 rpm 版本号

Options implemented via popt alias/exec:
      --with=<option>            enable configure <option> for build
      --without=<option>         disable configure <option> for build
      --buildpolicy=<policy>     set buildroot <policy> (e.g. compress man pages)
      --sign                     generate GPG signature (deprecated, use command rpmsign instead)
      --nodebuginfo              do not generate debuginfo for this package

帮助选项:
  -?, --help                     显示这个帮助信息
      --usage                    显示简短的使用说明
[root@laptop-7nmg10e6 ~]# 

4、install

1、介绍

install命令的作用是安装或升级软件或备份数据,它的使用权限是所有用户。

2、install 参数

[lq@laptop-7nmg10e6 ~]$ install --help
用法:install [选项]... [-T] 源文件 目标文件
 或:install [选项]... 源文件... 目录
 或:install [选项]... -t 目录 源文件...
 或:install [选项]... -d 目录...

This install program copies files (often just compiled) into destination
locations you choose.  If you want to download and install a ready-to-use
package on a GNU/Linux system, you should instead be using a package manager
like yum(1) or apt-get(1).

In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to
the existing DIRECTORY, while setting permission modes and owner/group.
In the 4th form, create all components of the given DIRECTORY(ies).

必选参数对长短选项同时适用。
      --backup[=CONTROL]	为每个已存在的文件创建备份
  -b			类似--backup 但不接受参数
  -c			(忽略)
  -C, --compare		比较每组源文件和目标文件,在一些情况下不修改目标文件
  -d, --directory	将所有参数视为目录名称;为指定的目录创建所有组件
  -D                  create all leading components of DEST except the last,
                        or all components of --target-directory,
                        then copy SOURCE to DEST
  -g, --group=GROUP   set group ownership, instead of process' current group
  -m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x
  -o, --owner=OWNER   set ownership (super-user only)
  -p, --preserve-timestamps	修改源文件的访问/修改时间以与目标文件保持一致
  -s, --strip			拆解符号表
      --strip-program=程序	指定拆解二进制文件的程序
  -S, --suffix=后缀		覆盖常用备份文件后缀
  -t, --target-directory=目录	将源文件所有参数复制到指定目录
  -T, --no-target-directory	将目标文件视为普通文件
  -v, --verbose			创建目录时显示其名称
  -P, --preserve-context  preserve SELinux security context (-P deprecated)
  -Z                      set SELinux security context of destination
                            file and each created directory to default type
      --context[=CTX]     like -Z, or if CTX is specified then set the
                            SELinux or SMACK security context to CTX
      --help		显示此帮助信息并退出
      --version		显示版本信息并退出

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the --backup option or through
the VERSION_CONTROL environment variable.  Here are the values:

  none, off       不进行备份(即使使用了--backup 选项)
  numbered, t     备份文件加上数字进行排序
  existing, nil   若有数字的备份文件已经存在则使用数字,否则使用普通方式备份
  simple, never   永远使用普通方式备份

GNU coreutils 在线帮助:<https://www.gnu.org/software/coreutils/>
请向 <http://translationproject.org/team/zh_CN.html> 报告 install 的翻译错误
完整文档请见:<https://www.gnu.org/software/coreutils/install>
或者在本地使用:info '(coreutils) install invocation'
[lq@laptop-7nmg10e6 ~]$

3、示例

1、install -d 创建目录

install -d [option] DIRECTORY [DIRECTORY...]
[lq@laptop-7nmg10e6 temp]$ pwd
/home/lq/My/temp
[lq@laptop-7nmg10e6 temp]$ ls
[lq@laptop-7nmg10e6 temp]$ install -d dir1/dir2 dir3/dir4
[lq@laptop-7nmg10e6 temp]$ ls
dir1  dir3
[lq@laptop-7nmg10e6 temp]$ tree ../temp/
../temp/
├── dir1
│   └── dir2
└── dir3
    └── dir4

4 directories, 0 files
[lq@laptop-7nmg10e6 temp]$

2、复制文件

install [option] SOURCE DEST
[lq@laptop-7nmg10e6 temp]$ tree ../temp/
../temp/
├── a.txt
├── dir1
│   └── dir2
└── dir3
    └── dir4

4 directories, 1 file
[lq@laptop-7nmg10e6 temp]$ install a.txt dir1/dir2/
[lq@laptop-7nmg10e6 temp]$ tree ../temp/
../temp/
├── a.txt
├── dir1
│   └── dir2
│       └── a.txt
└── dir3
    └── dir4

4 directories, 2 files
[lq@laptop-7nmg10e6 temp]$

3、-D选项作用

install -D x a/b/c

类似:

mkdir -p a/b && cp x a/b/c

四、RPM包构建思路

1、确定RPM包的功能(主要包含哪些内容)。

2、收集原材料(在RPM包中放入哪些文件)。

3、指定安装路径(一般通过相关宏完成)。

4、能否升级旧包。

5、是否兼容。

6、明确依赖关系。

五、确定RPM包功能

本示例制作 RPM 包安装成功后,主要通过 myhello 命令向终端打印 “hello world” 字符串。

RPM 二进制包命名的一般格式如下:

包名-版本号-发布次数-发行商-Linux平台-适合的硬件平台-包扩展名
httpd-2.2.15-15.el6.centos.1.i686.rpm

六、原材料准备

1、目标

创建 myhello.c 文件,myhello.c 文件主要功能向终端打印 “hello world!”。

2、目录和文件管理

[lq@laptop-7nmg10e6 c]$ tree 01/
01/
├── makefile
└── user
    └── myhello.c

1 directory, 2 files
[lq@laptop-7nmg10e6 c]$

文件说明:/user/myhello.c 为源码

3、源码

1、myhello.c

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("hello world!\r\n");

    return 0;
}

2、makefile

# 版本信息:2022.04.02 - lqonlylove-v1.0.0



##############################
# 目标
##############################
TARGET := myhello




##############################
# 环境参数
##############################
# CURDIR - make 自动指定(不用修改)
# SHELL  - make 自动指定(不用修改)




##############################
# 编译参数
##############################
CC      := gcc
#LD		:=
LDLIBS  :=
LDFLAGS :=
DEFINES :=
#INCLUDE := -I.
CFLAGS 	= -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS = $(CFLAGS) -DHAVE_CONFIG_H
#LOADLIBES := 
#OUTPUT_OPTION := 

#OBJCOPY :=
#OBJDUMP :=




##############################
# 目录管理
##############################
# 设置编译目录
BUILD_PATH := build
# 编译过程文件存放目录
OBJ_PATH := $(BUILD_PATH)/temp
# 编译可执行文件存放目录
BIN_PATH := $(BUILD_PATH)/bin

# 头文件目录(根据需要调整)
INC_PATH := user \
		   bsp/inc

# 源文件目录(根据需要调整)
SRC_PATH := user \
			bsp/src

# 获取源文件下的 c 文件列表(带目录信息)
SRC := $(foreach dir,$(SRC_PATH),$(wildcard $(dir)/*.c))
SRC_WITHOUT_DIR := $(notdir $(SRC))

# 为头文件目录添加 -I 选项(详细内容见 gcc 使用手册)
INCLUDE = $(addprefix -I ,$(INC_PATH))

# 生成 .c 文件对应的 .o 文件列表
OBJ := $(patsubst %.c,%.o,$(SRC_WITHOUT_DIR))
# 为 .o 加上编译目录
OBJ_WITH_BUILD_DIR := $(addprefix $(OBJ_PATH)/,$(OBJ))

# 指定 makefile 源文件查找路径(非常重要)
VPATH := $(SRC_PATH)






##############################
# makefile 目标管理
##############################
all: build_path $(TARGET)

# 指定目标文件生成规则
$(TARGET):$(OBJ_WITH_BUILD_DIR)
	$(CC) -o $(BIN_PATH)/$@ $^

# 指定过程文件生成规则(详细内容见 makefile 静态模式)
$(OBJ_WITH_BUILD_DIR):$(OBJ_PATH)/%.o: %.c
	$(CC) -c $(CFLAGS) -o $@ $<

build_path:
	@if [ ! -d $(BUILD_PATH) ]; then \
  	mkdir -p $(OBJ_PATH);mkdir -p $(BIN_PATH);\
	fi


# 清除过程文件
.PHONY: clean print
# 打印部分信息(测试使用)
print:
	@echo $(BIN_PATH)

clean:
	-rm -rf $(BIN_PATH)/$(TARGET) $(OBJ_WITH_BUILD_DIR)

4、编译测试

[lq@laptop-7nmg10e6 c]$ pwd
/home/lq/My/c
[lq@laptop-7nmg10e6 c]$ ls
01
[lq@laptop-7nmg10e6 c]$ tree 01/
01/
├── makefile
└── user
    └── myhello.c

1 directory, 2 files
[lq@laptop-7nmg10e6 c]$ cd 01/
[lq@laptop-7nmg10e6 01]$ pwd
/home/lq/My/c/01
[lq@laptop-7nmg10e6 01]$ ls
makefile  user
[lq@laptop-7nmg10e6 01]$ make
gcc -c -g -Wall -O3  -I user -I bsp/inc -o build/temp/myhello.o user/myhello.c
gcc -o build/bin/myhello build/temp/myhello.o
[lq@laptop-7nmg10e6 01]$ ./build/bin/myhello 
hello world!
[lq@laptop-7nmg10e6 01]$ cd ../
[lq@laptop-7nmg10e6 c]$ pwd
/home/lq/My/c
[lq@laptop-7nmg10e6 c]$ tree 01/
01/
├── build
│   ├── bin
│   │   └── myhello
│   └── temp
│       └── myhello.o
├── makefile
└── user
    └── myhello.c

4 directories, 4 files
[lq@laptop-7nmg10e6 c]$ 

5、打包构建材料

[lq@laptop-7nmg10e6 c]$ pwd
/home/lq/My/c
[lq@laptop-7nmg10e6 c]$ ls
myhello-1.0.0
[lq@laptop-7nmg10e6 c]$ tar -vcjf myhello-1.0.0.tar.bz2 myhello-1.0.0/
myhello-1.0.0/
myhello-1.0.0/makefile
myhello-1.0.0/user/
myhello-1.0.0/user/myhello.c
[lq@laptop-7nmg10e6 c]$ ls
myhello-1.0.0  myhello-1.0.0.tar.bz2
[lq@laptop-7nmg10e6 c]$

特别说明

  • 打包时需要注意压缩包命名。
  • 压缩前目录要和压缩后目录相同(解压后要使用该目录,或者使用%setup -n newdir解决)

七、构建工作目录

1、构建工作目录

[lq@laptop-7nmg10e6 My]$ pwd
/home/lq/My
[lq@laptop-7nmg10e6 My]$ ls
c
[lq@laptop-7nmg10e6 My]$ mkdir -p ./rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
[lq@laptop-7nmg10e6 My]$ ls
c  rpmbuild
[lq@laptop-7nmg10e6 My]$ tree rpmbuild/
rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS

5 directories, 0 files
[lq@laptop-7nmg10e6 My]$

2、目录说明

默认位置宏代码名 称用途
./rpmbuild/SPECS%_specdirSpec 文件目录保存 RPM 包配置(.spec)文件
./rpmbuild/SOURCES%_sourcedir源代码目录保存源码包(如 .tar 包)和所有 patch 补丁
./rpmbuild/BUILD%_builddir编译目录rpmbuild编译软件的目录
./rpmbuild/BUILDROOT%_buildrootdir最终安装目录保存 %install 阶段安装的文件
./rpmbuild/RPMS%_rpmdir标准 RPM 包目录生成/保存二进制 RPM 包
./rpmbuild/SRPMS%_srcrpmdir源代码 RPM 包目录生成/保存源码 RPM 包(SRPM)

3、查看构建目录方法

[lq@laptop-7nmg10e6 My]$ rpmbuild --showrc | grep %{_topdir}
-13: _builddir	%{_topdir}/BUILD
-13: _buildrootdir	%{_topdir}/BUILDROOT
-13: _rpmdir	%{_topdir}/RPMS
-13: _sourcedir	%{_topdir}/SOURCES
-13: _specdir	%{_topdir}/SPECS
-13: _srcrpmdir	%{_topdir}/SRPMS
[lq@laptop-7nmg10e6 My]$

八、宏

RPM包构建过程中会使用一些宏,宏定义文件用如下命令查看:

rpmbuild --showrc | grep macros

在这里插入图片描述
以下是一些常用的宏:

%{_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}

九、sepc语法规则

1、注释

sepc 中注释以 “#” 开头。特变说明注释中使用 “%” 需要进行使用 “%%”。

2、宏

1、宏定义

%define 宏名 值

2、宏引用

%{宏名}

3、软件信息

  • Name:软件包的名字,最终 rpm 软件包是用该名字与版本号(Version)、释出号(Release)及体系号来命名软件包的,后面可使用 %{name} 的方式引用

  • Version:软件版本号。仅当软件包比以前有较大改变时才增加版本号,后面可使用%{version}引用

  • Release:软件包释出号/发行号。一般我们对该软件包做了一些小的补丁的时候就应该把释出号加 1,后面可使用 %{release} 引用

  • Group:软件包所属类别

    • Development/System (开发/系统)
    • System Environment/Daemons (系统环境/守护)

4、公司信息

  • Vendor:软件开发者的名字,发行商或打包组织的信息,例如RedFlagCo,Ltd
  • Packager:打包的人(一般喜欢写个人邮箱)
  • License:软件授权方式,通常是GPL(自由软件)或GPLv2,BSD
  • Copyright:软件包所采用的版权规则。具体有:GPL(自由软件),BSD,MIT,Public Domain(公共域)
  • URL:软件的主页

5、描述信息

  • Summary:用一句话概括该软件s包尽量多的信息。
  • %description:软件包详细说明,可写在多个行上。这样任何人使用 rpm -qi查询您的软件包时都可以看到它。您可以解释这个软件包做什么,描述任何警告或附加的配置指令,等等。

6、包依赖关系

  • BuildRequires: 制作过程中用到的软件包,构建依赖

  • Requires: 安装时所需软件包

    • Requires(pre): 指定不同阶段的依赖

7、build 目录设置

  • buildRoot: 这个是安装或编译时使用的「虚拟目录」,打包时会用到该目录下文件,可查看安装后文件路径,例如:BuildRoot: %_topdir/BUILDROOT。
  • build:编译使用目录

8、源文件

  • Source:源程序软件包的名字/源代码包的名字,如 stardict-2.0.tar.gz。可以带多个用 Source1、Source2 等源,后面也可以用 %{source1}、%{source2} 引用
Source0: %{name}-boost-%{version}.tar.gz    ← 源码包名称(可以使用URL),可以用SourceN指定多个,如配置文件

9、补丁文件

  • #Patch0: some-bugs0.patch ← 如果需要打补丁,则依次填写
  • #Patch1: some-bugs1.patch ← 如果需要打补丁,则依次填写

10、%prep阶段

1、描述

这个阶段是「预处理」,通常用来执行一些解开源程序包的命令,为下一步的编译安装作准备。

%prep 和下面的 %build,%install 段一样,除了可以执行 rpm 所定义的宏命令(以%开头)以外,还可以执行 SHELL 命令,命令可以有很多行,如我们常写的 tar 解包命令。功能上类似于 ./configure。

%prep 阶段进行实际的打包准备工作,它是使用节前缀 %prep 表示的。主要功能有:

  • 将文件 ( SOURCES/) 解压到构建目录 (BUILD/)
  • 应用 Patch(打补丁) (SOURCES/ => BUILD/)
  • 描述 rm -rf $RPM_BUILD_ROOT
  • 描述或编辑本部分用到的命令到 PreReq
  • 通过 -b .XXX 描述补丁备份

它一般包含 %setup 与 %patch 两个命令。%setup 用于将软件包打开,执行 %patch 可将补丁文件加入解开的源程序中。

示例:

%prep
%setup -q                                     ← 宏的作用是解压并切换到目录
#%patch0 -p1                                  ← 如果需要打补丁,则依次写
#%patch1 -p1                                  ← 如果需要打补丁,则依次写

2、%setup命令

这个宏解压源代码,将当前目录改为源代码解压之后产生的目录。这个宏还有一些选项可以用。例如,在解压后,%setup 宏假设产生的目录是 %{name}-%{version}

%setup -n %{name}-%{version} #把源码包解压并放好

主要的用途就是将 %sourcedir 目录下的源代码解压到 %builddir 目录下,也就是将~/rpmbuild/SOURCES 里的包解压到 ~/rpmbuild/BUILD/%{name}-%{version} 中。一般用 %setup -c 就可以了,但有两种情况:

  • 一就是同时编译多个源码包,
  • 二就是源码的 tar 包的名称与解压出来的目录不一致,此时,就需要使用 -n 参数指定一下。
%setup 不加任何选项,仅将软件包打开。 
%setup -n newdir 将软件包解压在newdir目录。 
%setup -c 解压缩之前先产生目录。 
%setup -b num 将第num个source文件解压缩。 
%setup -T 不使用default的解压缩操作。 
%setup -T -b 0 将第0个源代码文件解压缩。 
%setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。 

3、%patch命令

这个宏将头部定义的补丁应用于源代码。如果定义了多个补丁,它可以用一个数字的参数来指示应用哪个补丁文件。它也接受 -b extension 参数,指示 RPM 在打补丁之前,将文件备份为扩展名是 extension 的文件。

通常补丁都会一起在源码 tar.gz 包中,或放到 SOURCES 目录下。一般参数为:

  • %patch -p1 使用前面定义的 Patch 补丁进行,-p1是忽略 patch 的第一层目录
  • %Patch2 -p1 -b xxx.patch打上指定的补丁,-b是指生成备份文件
%patch 最简单的补丁方式,自动指定patch level。
%patch 0 使用第0个补丁文件,相当于%patch ?p 0。
%patch -s 不显示打补丁时的信息。
%patch -T 将所有打补丁时产生的输出文件删除

11、%build 阶段

本段是「构建」阶段,这个阶段会在 %_builddir 目录下执行源码包的编译。一般是执行执行常见的 configure 和 make 操作。

该阶段一般由多个 make 命令组成。与 %prep 段落一样,这些命令可以是 shell 命令,也可以是宏。

记住两点:

  1. %build 和 %install 的过程中,都必须把编译和安装的文件定义到“虚拟根目录” 中
  2. %file 中必须明白,用的是相对目录

这个阶段我们最常见只有两条指令:

%configure
make %{?_smp_mflags} OPTIMIZE="%{optflags}"           ← 多核则并行编译

%configure 这个不是关键字,而是 rpm 定义的标准宏命令。意思是执行源代码的configure配置。会自动将 prefix 设置成 /usr。

12、%install 阶段

「安装」阶段,就是执行 make install 命令操作。开始把软件安装到虚拟的根目录中。这个阶段会在 %buildrootdir 目录里建好目录结构,然后将需要打包到 rpm 软件包里的文件从 %builddir 里拷贝到 %_buildrootdir 里对应的目录里。

在 ~/rpmbuild/BUILD/%{name}-%{version} 目录中进行 make install 的操作。%install 很重要,因为如果这里的路径不对的话,则下面 %file 中寻找文件的时候就会失败。

特别需要注意的是:%install 部分使用的是绝对路径,而 %file 部分使用则是相对路径,虽然其描述的是同一个地方。千万不要写错。

当用户最终用 rpm -ivh name-version.rpm 安装软件包时,这些文件会安装到用户系统中相应的目录里。

%install
if [-d %{buildroot}]; then
   rm -rf %{buildroot}                      ← 清空下安装目录,实际会自动清除
fi
make install DESTDIR=%{buildroot}           ← 安装到buildroot目录下
%{__install} -Dp -m0755 contrib/init.d %{buildroot}%{_initrddir}/foobar
%{__install} -d %{buildroot}%{_sysconfdir}/foobar.d/

需要说明的是,这里的 %install 主要就是为了后面的 %file 服务的。所以,还可以使用常规的系统命令:

install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/

其中 %{buildroot} 和 $RPMBUILDROOT 是等价的, %{buildroot}必须全部用小写,不然要报错。

注意区分 $RPM_BUILD_ROOT和 $RPM_BUILD_DIR:

  • $RPM_BUILD_ROOT 是指开头定义的 BuildRoot,是 %file 需要的。
  • $RPM_BUILD_DIR 通常就是指 ~/rpmbuild/BUILD

13、%clean阶段

清理段,可以通过 --clean 删除 BUILD。

编译完成后一些清理工作,主要包括对 %{buildroot} 目录的清空(这不是必须的),通常执行诸如 make clean 之类的命令。

14、scripts section

1、scripts section 没必要可以不填

  • %pre 安装前执行的脚本
  • %post 安装后执行的脚本
  • %preun 卸载前执行的脚本
  • %postun 卸载后执行的脚本
  • %pretrans 在事务开始时执行脚本
  • %posttrans 在事务结束时执行脚本

2、%preun %postun 的区别是什么呢?

  • 前者在升级的时候会执行,后者在升级 rpm 包的时候不会执行

3、特别说明

$1 == 1 #安装
$1 == 2 #升级
$1 == 0 #卸载

15、%files 阶段

本段是文件段,主要用来说明会将 %{buildroot} 目录下的哪些文件和目录最终打包到rpm包里。定义软件包所包含的文件,分为三类:

  • 说明文档(doc)
  • 配置文件(config)
  • 执行程序

还可定义文件存取权限,拥有者及组别。

这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。

在 %files 阶段的第一条命令的语法是:

%defattr(文件权限,用户名,组名,目录权限)

注意点:同时需要在 %install 中安装。

%files
%defattr (-,root,root,0755)                         ← 设定默认权限
%config(noreplace) /etc/my.cnf                      ← 表明是配置文件,noplace表示替换文件
%doc %{src_dir}/Docs/ChangeLog                      ← 表明这个是文档
%attr(644, root, root) %{_mandir}/man8/mysqld.8*    ← 分别是权限,属主,属组
%attr(755, root, root) %{_sbindir}/mysqld

%exclude 列出不想打包到 rpm 中的文件。注意:如果 %exclude 指定的文件不存在,也会出错的。

在安装 rpm 时,会将可执行的二进制文件放在 /usr/bin 目录下,动态库放在 /usr/lib 或者 /usr/lib64 目录下,配置文件放在 /etc 目录下,并且多次安装时新的配置文件不会覆盖以前已经存在的同名配置文件。

关于 %files 阶段有两个特性:

  1. %{buildroot} 里的所有文件都要明确被指定是否要被打包到 rpm里。什么意思呢?假如,%{buildroot} 目录下有 4 个目录 a、b、c和d,在 %files 里仅指定 a 和 b 要打包到 rpm 里,如果不把 c 和 d 用 exclude 声明是要报错的;
  2. 如果声明了 %{buildroot} 里不存在的文件或者目录也会报错。

关于 %doc 宏,所有跟在这个宏后面的文件都来自 %{_builddir} 目录,当用户安装 rpm 时,由这个宏所指定的文件都会安装到 /usr/share/doc/name-version/ 目录里。

16、%changelog

每一个修改日志都有这样一种格式:

  • 第一行是:星期 月 日 年 修改人 电子信箱。其中:星期、月份均用英文形式的前 3 个字母,用中文会报错。
  • 接下来的行写的是修改了什么地方,可写多行。一般以减号开始,便于后续的查阅。
%changelog
* Fri Dec 29 2012 foobar <[email protected]> - 1.0.0-1
- Initial version
星期一:Monday(Mon.)
星期二:Tuesday(Tue.)
星期三:Wednesday(Wed.)
星期四:Thursday(Thu.)
星期五:Friday(Fri.)
星期六:Saturday(Sat.)
星期日:Sunday(Sun.)

一月份=JAN.  Jan.=January
二月份=FEB.  Feb.=February
三月份=MAR.  Mar.=March
四月份=APR.  Apr.=April
五月份=MAY.  May.=May
六月份=JUN.  Jun.=June
七月份=JUL.  Jul.=July
八月份=AUG.  Aug.=August
九月份=SEP.  Sept.=September
十月份=OCT.  Oct.=October
十一月份=NOV. Nov.=November
十二月份=DEC. Dec.=Decemb

十、编写myhello.sepc文件

Name:       myhello
Version:    1.0.0
Release:    1%{?dist}
Summary:    lq myhello.
License:    GPLv2
Group:      Applications
Source:     %{name}-%{version}.tar.bz2
#BuildRequires:  gcc
#Requires:
BuildRoot:  %{_topdir}/BUILDROOT

%define debug_package %{nil}

%description
lq myhello.

%prep
%setup

%build
make %{?_smp_mflags} OPTIMIZE="%{optflags}"

%install
rm -rf $RPM_BUILD_ROOT
# buildroot	%{_buildrootdir}/%{NAME}-%{VERSION}-%{RELEASE}.%{_arch}
# _buildrootdir	%{_topdir}/BUILDROOT
# _topdir	%{getenv:HOME}/rpmbuild
# 
# _bindir	%{_exec_prefix}/bin
# _exec_prefix	%{_prefix}
# _prefix	/usr
# 为了目录结构干净,因此将软件安装到tmp下
mkdir -p %{buildroot}/usr/myhello/bin/
%{__install} -p %{_topdir}/BUILD/%{name}-%{version}/build/bin/%{name} %{buildroot}/usr/myhello/bin/

%clean
# _topdir	%{getenv:HOME}/rpmbuild
# _rpmdir	%{_topdir}/RPMS
# _srcrpmdir	%{_topdir}/SRPMS
rm -rf $RPM_BUILD_ROOT

%files
%defattr (0755,lq,lq,-)
/usr/myhello/bin/%{name}

%changelog
* Sat Apr 30 2022 lq <[email protected]>
- Initial version

十一、测试

1、准备阶段

lq@laptop-7nmg10e6 ~]$ tree rpmbuild/
rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
│   └── myhello-1.0.0.tar.bz2
├── SPECS
│   └── myhello.spec
└── SRPMS

6 directories, 2 files
[lq@laptop-7nmg10e6 ~]$

准备阶段主要包含:

  • 原材料:myhello-1.0.0.tar.bz2
  • spec文件:myhello.spec

2、执行到%prep阶段

rpmbuild -bp xxx.spec
[lq@laptop-7nmg10e6 ~]$ rpmbuild -bp rpmbuild/SPECS/myhello.spec 
正在执行(%prep):/bin/sh -e /var/tmp/rpm-tmp.EhhXtI
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd /home/lq/rpmbuild/BUILD
+ rm -rf myhello-1.0.0
+ /usr/bin/bzip2 -dc /home/lq/rpmbuild/SOURCES/myhello-1.0.0.tar.bz2
+ /usr/bin/tar -xvvof -
drwxrwxr-x lq/lq             0 2022-04-30 03:59 myhello-1.0.0/
-rw-rw-r-- lq/lq          2157 2022-04-30 03:27 myhello-1.0.0/makefile
drwxrwxr-x lq/lq             0 2022-04-30 03:28 myhello-1.0.0/user/
-rw-rw-r-- lq/lq           103 2022-04-30 03:30 myhello-1.0.0/user/myhello.c
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd myhello-1.0.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
[lq@laptop-7nmg10e6 ~]$
[lq@laptop-7nmg10e6 ~]$ tree rpmbuild/
rpmbuild/
├── BUILD
│   └── myhello-1.0.0
│       ├── makefile
│       └── user
│           └── myhello.c
├── BUILDROOT
├── RPMS
├── SOURCES
│   └── myhello-1.0.0.tar.bz2
├── SPECS
│   └── myhello.spec
└── SRPMS

8 directories, 4 files
[lq@laptop-7nmg10e6 ~]$

3、执行到 %build 阶段

rpmbuild -bc xxx.spec
[lq@laptop-7nmg10e6 ~]$ rpmbuild -bc rpmbuild/SPECS/myhello.spec 
正在执行(%prep):/bin/sh -e /var/tmp/rpm-tmp.VeI1Pm
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd /home/lq/rpmbuild/BUILD
+ rm -rf myhello-1.0.0
+ /usr/bin/bzip2 -dc /home/lq/rpmbuild/SOURCES/myhello-1.0.0.tar.bz2
+ /usr/bin/tar -xvvof -
drwxrwxr-x lq/lq             0 2022-04-30 03:59 myhello-1.0.0/
-rw-rw-r-- lq/lq          2157 2022-04-30 03:27 myhello-1.0.0/makefile
drwxrwxr-x lq/lq             0 2022-04-30 03:28 myhello-1.0.0/user/
-rw-rw-r-- lq/lq           103 2022-04-30 03:30 myhello-1.0.0/user/myhello.c
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd myhello-1.0.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
正在执行(%build):/bin/sh -e /var/tmp/rpm-tmp.E74kek
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd myhello-1.0.0
+ make -j4 'OPTIMIZE=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
gcc -c -g -Wall -O3  -I user -I bsp/inc -o build/temp/myhello.o user/myhello.c
gcc -o build/bin/myhello build/temp/myhello.o
+ exit 0
[lq@laptop-7nmg10e6 ~]$ 
[lq@laptop-7nmg10e6 ~]$ tree rpmbuild/
rpmbuild/
├── BUILD
│   └── myhello-1.0.0
│       ├── build
│       │   ├── bin
│       │   │   └── myhello
│       │   └── temp
│       │       └── myhello.o
│       ├── makefile
│       └── user
│           └── myhello.c
├── BUILDROOT
├── RPMS
├── SOURCES
│   └── myhello-1.0.0.tar.bz2
├── SPECS
│   └── myhello.spec
└── SRPMS

11 directories, 6 files
[lq@laptop-7nmg10e6 ~]$

4、执行到 %install 阶段

rpmbuild -bi xxx.spec
[lq@laptop-7nmg10e6 ~]$ rpmbuild -bi rpmbuild/SPECS/myhello.spec 
正在执行(%prep):/bin/sh -e /var/tmp/rpm-tmp.ldXnJ9
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd /home/lq/rpmbuild/BUILD
+ rm -rf myhello-1.0.0
+ /usr/bin/bzip2 -dc /home/lq/rpmbuild/SOURCES/myhello-1.0.0.tar.bz2
+ /usr/bin/tar -xvvof -
drwxrwxr-x lq/lq             0 2022-04-30 03:59 myhello-1.0.0/
-rw-rw-r-- lq/lq          2157 2022-04-30 03:27 myhello-1.0.0/makefile
drwxrwxr-x lq/lq             0 2022-04-30 03:28 myhello-1.0.0/user/
-rw-rw-r-- lq/lq           103 2022-04-30 03:30 myhello-1.0.0/user/myhello.c
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd myhello-1.0.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
正在执行(%build):/bin/sh -e /var/tmp/rpm-tmp.rc0aR9
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd myhello-1.0.0
+ make -j4 'OPTIMIZE=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
gcc -c -g -Wall -O3  -I user -I bsp/inc -o build/temp/myhello.o user/myhello.c
gcc -o build/bin/myhello build/temp/myhello.o
+ exit 0
正在执行(%install):/bin/sh -e /var/tmp/rpm-tmp.St6Esb
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ '[' /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64 '!=' / ']'
+ rm -rf /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
++ dirname /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ mkdir -p /home/lq/rpmbuild/BUILDROOT
+ mkdir /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ cd myhello-1.0.0
+ rm -rf /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ mkdir -p /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64/usr/myhello/bin/
+ /usr/bin/install -p /home/lq/rpmbuild/BUILD/myhello-1.0.0/build/bin/myhello /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64/usr/myhello/bin/
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip /usr/bin/strip
+ /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile '' 1
+ /usr/lib/rpm/brp-python-hardlink
+ PYTHON3=/usr/libexec/platform-python
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
处理文件:myhello-1.0.0-1.el8.x86_64
Provides: myhello = 1.0.0-1.el8 myhello(x86-64) = 1.0.0-1.el8
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) rtld(GNU_HASH)
检查未打包文件:/usr/lib/rpm/check-files /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
[lq@laptop-7nmg10e6 ~]$ 

特别说明:最后一行不是错误。

[lq@laptop-7nmg10e6 ~]$ tree rpmbuild/
rpmbuild/
├── BUILD
│   └── myhello-1.0.0
│       ├── build
│       │   ├── bin
│       │   │   └── myhello
│       │   └── temp
│       │       └── myhello.o
│       ├── makefile
│       └── user
│           └── myhello.c
├── BUILDROOT
│   └── myhello-1.0.0-1.el8.x86_64
│       └── usr
│           ├── lib
│           └── myhello
│               └── bin
│                   └── myhello
├── RPMS
├── SOURCES
│   └── myhello-1.0.0.tar.bz2
├── SPECS
│   └── myhello.spec
└── SRPMS

16 directories, 7 files
[lq@laptop-7nmg10e6 ~]$ 

5、构建源代码和二进制软件包

rpmbuild -ba xxx.spec
[lq@laptop-7nmg10e6 ~]$ rpmbuild -ba rpmbuild/SPECS/myhello.spec 
正在执行(%prep):/bin/sh -e /var/tmp/rpm-tmp.CnA840
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd /home/lq/rpmbuild/BUILD
+ rm -rf myhello-1.0.0
+ /usr/bin/bzip2 -dc /home/lq/rpmbuild/SOURCES/myhello-1.0.0.tar.bz2
+ /usr/bin/tar -xvvof -
drwxrwxr-x lq/lq             0 2022-04-30 03:59 myhello-1.0.0/
-rw-rw-r-- lq/lq          2157 2022-04-30 03:27 myhello-1.0.0/makefile
drwxrwxr-x lq/lq             0 2022-04-30 03:28 myhello-1.0.0/user/
-rw-rw-r-- lq/lq           103 2022-04-30 03:30 myhello-1.0.0/user/myhello.c
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd myhello-1.0.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
正在执行(%build):/bin/sh -e /var/tmp/rpm-tmp.Xns80X
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd myhello-1.0.0
+ make -j4 'OPTIMIZE=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
gcc -c -g -Wall -O3  -I user -I bsp/inc -o build/temp/myhello.o user/myhello.c
gcc -o build/bin/myhello build/temp/myhello.o
+ exit 0
正在执行(%install):/bin/sh -e /var/tmp/rpm-tmp.Nbcdg0
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ '[' /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64 '!=' / ']'
+ rm -rf /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
++ dirname /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ mkdir -p /home/lq/rpmbuild/BUILDROOT
+ mkdir /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ cd myhello-1.0.0
+ rm -rf /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ mkdir -p /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64/usr/myhello/bin/
+ /usr/bin/install -p /home/lq/rpmbuild/BUILD/myhello-1.0.0/build/bin/myhello /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64/usr/myhello/bin/
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip /usr/bin/strip
+ /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile '' 1
+ /usr/lib/rpm/brp-python-hardlink
+ PYTHON3=/usr/libexec/platform-python
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
处理文件:myhello-1.0.0-1.el8.x86_64
Provides: myhello = 1.0.0-1.el8 myhello(x86-64) = 1.0.0-1.el8
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) rtld(GNU_HASH)
检查未打包文件:/usr/lib/rpm/check-files /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
已写至:/home/lq/rpmbuild/SRPMS/myhello-1.0.0-1.el8.src.rpm
已写至:/home/lq/rpmbuild/RPMS/x86_64/myhello-1.0.0-1.el8.x86_64.rpm
正在执行(%clean):/bin/sh -e /var/tmp/rpm-tmp.6Q76MX
+ umask 022
+ cd /home/lq/rpmbuild/BUILD
+ cd myhello-1.0.0
+ rm -rf /home/lq/rpmbuild/BUILDROOT/myhello-1.0.0-1.el8.x86_64
+ exit 0
[lq@laptop-7nmg10e6 ~]$ 
[lq@laptop-7nmg10e6 ~]$ tree rpmbuild/
rpmbuild/
├── BUILD
│   └── myhello-1.0.0
│       ├── build
│       │   ├── bin
│       │   │   └── myhello
│       │   └── temp
│       │       └── myhello.o
│       ├── makefile
│       └── user
│           └── myhello.c
├── BUILDROOT
├── RPMS
│   └── x86_64
│       └── myhello-1.0.0-1.el8.x86_64.rpm
├── SOURCES
│   └── myhello-1.0.0.tar.bz2
├── SPECS
│   └── myhello.spec
└── SRPMS
    └── myhello-1.0.0-1.el8.src.rpm

12 directories, 8 files
[lq@laptop-7nmg10e6 ~]$

6、执行 %clean 阶段

十二、安装验证

1、安装前检测

[lq@laptop-7nmg10e6 ~]$ ls /usr/ -l
总用量 264
dr-xr-xr-x.   2 root root 49152 430 03:29 bin
drwxr-xr-x.   2 root root    22 430 04:37 config
drwxr-xr-x.   2 root root     6 622 2021 games
drwxr-xr-x.  35 root root  4096 430 03:29 include
dr-xr-xr-x.  38 root root  4096 430 03:29 lib
dr-xr-xr-x. 126 root root 86016 430 03:29 lib64
drwxr-xr-x.  50 root root 12288 430 03:29 libexec
drwxr-xr-x.  12 root root   131 430 04:33 local
dr-xr-xr-x.   2 root root 20480 430 04:38 sbin
drwxr-xr-x. 226 root root  8192 430 02:54 share
drwxr-xr-x.   5 root root    49 430 03:29 src
lrwxrwxrwx.   1 root root    10 622 2021 tmp -> ../var/tmp
[lq@laptop-7nmg10e6 ~]$

2、安装

rpm -ivh packge.rpm
[root@laptop-7nmg10e6 ~]# rpm -ivh /home/lq/rpmbuild/RPMS/x86_64/myhello-1.0.0-1.el8.x86_64.rpm 
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:myhello-1.0.0-1.el8              ################################# [100%]
[root@laptop-7nmg10e6 ~]#

3、安装后检测

[lq@laptop-7nmg10e6 ~]$ ls /usr/ -l
总用量 264
dr-xr-xr-x.   2 root root 49152 430 03:29 bin
drwxr-xr-x.   2 root root    22 430 04:37 config
drwxr-xr-x.   2 root root     6 622 2021 games
drwxr-xr-x.  35 root root  4096 430 03:29 include
dr-xr-xr-x.  38 root root  4096 430 03:29 lib
dr-xr-xr-x. 126 root root 86016 430 03:29 lib64
drwxr-xr-x.  50 root root 12288 430 03:29 libexec
drwxr-xr-x.  12 root root   131 430 04:33 local
drwxr-xr-x.   3 root root    17 51 02:39 myhello
dr-xr-xr-x.   2 root root 20480 430 04:38 sbin
drwxr-xr-x. 226 root root  8192 430 02:54 share
drwxr-xr-x.   5 root root    49 430 03:29 src
lrwxrwxrwx.   1 root root    10 622 2021 tmp -> ../var/tmp
[lq@laptop-7nmg10e6 ~]$
[lq@laptop-7nmg10e6 ~]$ tree /usr/myhello/
/usr/myhello/
└── bin
    └── myhello

1 directory, 1 file
[lq@laptop-7nmg10e6 ~]$

4、执行测试

[lq@laptop-7nmg10e6 ~]$ /usr/myhello/bin/myhello 
hello world!
[lq@laptop-7nmg10e6 ~]$

5、卸载

rpm -e package.rpm 
[root@laptop-7nmg10e6 ~]# rpm -e myhello
[root@laptop-7nmg10e6 ~]#

6、卸载后检测

[lq@laptop-7nmg10e6 ~]$ ls /usr/ -l
总用量 264
dr-xr-xr-x.   2 root root 49152 430 03:29 bin
drwxr-xr-x.   2 root root    22 430 04:37 config
drwxr-xr-x.   2 root root     6 622 2021 games
drwxr-xr-x.  35 root root  4096 430 03:29 include
dr-xr-xr-x.  38 root root  4096 430 03:29 lib
dr-xr-xr-x. 126 root root 86016 430 03:29 lib64
drwxr-xr-x.  50 root root 12288 430 03:29 libexec
drwxr-xr-x.  12 root root   131 430 04:33 local
drwxr-xr-x.   3 root root    17 51 02:39 myhello
dr-xr-xr-x.   2 root root 20480 430 04:38 sbin
drwxr-xr-x. 226 root root  8192 430 02:54 share
drwxr-xr-x.   5 root root    49 430 03:29 src
lrwxrwxrwx.   1 root root    10 622 2021 tmp -> ../var/tmp
[lq@laptop-7nmg10e6 ~]$ tree /usr/myhello/
/usr/myhello/
└── bin

1 directory, 0 files
[lq@laptop-7nmg10e6 ~]$

7、不安装查看安装目录

rpm -qpl *.rpm
;