分析tree rpmbuild spec文件

379 阅读2分钟

[toc]

简介

V0.5.1.20220513

用一款比较简单的软件 tree 来学习rpm的解包,分析tree软件的编译、安装

当前版本

[kira@localhost ~]$ uname -a
Linux localhost.localdomain 3.10.0-1160.62.1.el7.x86_64 #1 SMP Tue Apr 5 16:57:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
[kira@localhost ~]$ rpmbuild --version
RPM 版本 4.11.3
[kira@localhost ~]$ 

下载tree SRPM包

[kira@localhost ~]$ yumdownloader --source tree
已加载插件:fastestmirror
Enabling updates-source repository
Enabling base-source repository
Enabling extras-source repository
Loading mirror speeds from cached hostfile
base                                                                                              | 3.6 kB  00:00:00
base-source                                                                                       | 2.9 kB  00:00:00
extras                                                                                            | 2.9 kB  00:00:00
extras-source                                                                                     | 2.9 kB  00:00:00
updates                                                                                           | 2.9 kB  00:00:00
updates-source                                                                                    | 2.9 kB  00:00:00
[kira@localhost ~]$
  • yumdownland 工具可能需要额外安装
    yum install yum-utils
    

rpm包安装、解包

[root@localhost ~]# rpm -ivh tree-1.6.0-10.el7.src.rpm
正在升级/安装...
   1:tree-1.6.0-10.el7                ################################# [100%]
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
警告:用户mockbuild 不存在 - 使用root
警告:群组mockbuild 不存在 - 使用root
[root@localhost ~]#
  • 操作完后tree并不在系统中,src并不能直接安装,安装会先展开,展开后如下文所示目录结构(需先rpmdev-newinit一下建立rpm包空间)

分析

目录结构

[root@localhost ~]# tree ./rpmbuild/
./rpmbuild/
├── SOURCES
│   ├── tree-1.6.0.tgz                  源码
│   ├── tree-args.patch                 patch 补丁包
│   ├── tree-fixbufsiz.patch
│   ├── tree-no-color-by-default.patch
│   ├── tree-no-strip.patch
│   └── tree-preserve-timestamps.patch
└── SPECS
    └── tree.spec                       rpm描述文件

2 directories, 7 files
[root@localhost ~]#

spec文件分析

Summary: File system tree viewer            # 简要描述
Name: tree                                  # 程序名
Version: 1.6.0                              # 版本号
Release: 10%{?dist}                         # 发布序号
Group: Applications/File                    # 软件分组
License: GPLv2+                             # 授权协议
Url: http://mama.indstate.edu/users/ice/tree/                       # 主页
Source: ftp://mama.indstate.edu/linux/tree/tree-%{version}.tgz      # 源码包
Patch1: tree-no-strip.patch                                         # 补丁包
Patch2: tree-preserve-timestamps.patch
Patch3: tree-no-color-by-default.patch
Patch4: tree-args.patch
Patch5: tree-fixbufsiz.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)       # make install 测试目录

%description                                                        # 详细描述
The tree utility recursively displays the contents of directories in a
tree-like format.  Tree is basically a UNIX port of the DOS tree
utility.

%prep                               # build前操作,例如解压源码
%setup -q                           # rpm内置的解压缩命令
# Don't strip binary in the Makefile -- let rpmbuild do it.
%patch1 -p1 -b .no-strip            # 应用补丁,-b 打补丁前备份源码

# Preserve timestamp on man page.
%patch2 -p1 -b .preserve-timestamps

# Disable color output by default.
%patch3 -p1 -b .no-color-by-default

# Document --du and --prune options in help output (bug #948991).
%patch4 -p1 -b .args

# Handle large UID/GID values (bug #980945).
%patch5 -p1 -b .fixbufsiz

%build                              # 编译
make CFLAGS="$RPM_OPT_FLAGS $(getconf LFS_CFLAGS)" %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT%{_bindir}

make	BINDIR=$RPM_BUILD_ROOT%{_bindir} \
	MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1 \
	install

chmod -x $RPM_BUILD_ROOT%{_mandir}/man1/tree.1

%clean
rm -rf $RPM_BUILD_ROOT

%files                              # 最终安装到系统的软件
%defattr(-,root,root)
%{_bindir}/tree
%{_mandir}/man1/tree.1*
%doc README LICENSE

%changelog
* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 1.6.0-10
- Mass rebuild 2014-01-24

* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 1.6.0-9
- Mass rebuild 2013-12-27

...... 巴拉巴拉 往后是更新日志省略
  • 查询spec文件下变量
    [root@localhost SPECS]# rpmbuild --eval "%{_tmppath}"
    /var/tmp
    

根据spec文件构建项目

[root@localhost ~]# cd rpmbuild/SPECS/
[root@localhost SPECS]# rpmbuild -bp tree.spec
执行(%prep): /bin/sh -e /var/tmp/rpm-tmp.mtGtgy
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf tree-1.6.0
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/tree-1.6.0.tgz
+ /usr/bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd tree-1.6.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ echo 'Patch #1 (tree-no-strip.patch):'
Patch #1 (tree-no-strip.patch):
+ /usr/bin/cat /root/rpmbuild/SOURCES/tree-no-strip.patch
+ /usr/bin/patch -p1 -b --suffix .no-strip --fuzz=0
patching file Makefile
+ echo 'Patch #2 (tree-preserve-timestamps.patch):'
Patch #2 (tree-preserve-timestamps.patch):
+ /usr/bin/cat /root/rpmbuild/SOURCES/tree-preserve-timestamps.patch
+ /usr/bin/patch -p1 -b --suffix .preserve-timestamps --fuzz=0
patching file Makefile
+ echo 'Patch #3 (tree-no-color-by-default.patch):'
Patch #3 (tree-no-color-by-default.patch):
+ /usr/bin/cat /root/rpmbuild/SOURCES/tree-no-color-by-default.patch
+ /usr/bin/patch -p1 -b --suffix .no-color-by-default --fuzz=0
patching file tree.c
+ echo 'Patch #4 (tree-args.patch):'
Patch #4 (tree-args.patch):
+ /usr/bin/cat /root/rpmbuild/SOURCES/tree-args.patch
+ /usr/bin/patch -p1 -b --suffix .args --fuzz=0
patching file tree.c
+ echo 'Patch #5 (tree-fixbufsiz.patch):'
Patch #5 (tree-fixbufsiz.patch):
+ /usr/bin/cat /root/rpmbuild/SOURCES/tree-fixbufsiz.patch
+ /usr/bin/patch -p1 -b --suffix .fixbufsiz --fuzz=0
patching file hash.c
patching file tree.h
+ exit 0
[root@localhost SPECS]#

生成rpm包

[root@localhost SPECS]# rpmbuild --bb tree.spec

安装rpm包

[root@localhost x86_64]# pwd
/root/rpmbuild/RPMS/x86_64
[root@localhost x86_64]# rpm -ivh tree-1.6.0-10.el7.x86_64.rpm

最终目录结构

[root@localhost rpmbuild]# tree
.
├── BUILD                               源代码与构建项目
│   └── tree-1.6.0
│       ├── CHANGES
│       ├── color.c
│       ├── color.o
│       ├── debugfiles.list
│       ├── debuglinks.list
│       ├── debugsources.list
│       ├── doc
│       │   ├── tree.1
│       │   ├── tree.1.fr
│       │   └── xml.dtd
│       ├── elfbins.list
│       ├── hash.c
│       ├── hash.c.fixbufsiz
│       ├── hash.o
│       ├── html.c
│       ├── html.o
│       ├── INSTALL
│       ├── LICENSE
│       ├── Makefile
│       ├── Makefile.no-strip
│       ├── Makefile.preserve-timestamps
│       ├── README
│       ├── strverscmp.c
│       ├── TODO
│       ├── tree
│       ├── tree.c
│       ├── tree.c.args
│       ├── tree.c.no-color-by-default
│       ├── tree.h
│       ├── tree.h.fixbufsiz
│       ├── tree.o
│       ├── unix.c
│       ├── unix.o
│       ├── xml.c
│       └── xml.o
├── BUILDROOT
├── RPMS                生成rpm包
│   └── x86_64
│       ├── tree-1.6.0-10.el7.x86_64.rpm
│       └── tree-debuginfo-1.6.0-10.el7.x86_64.rpm
├── SOURCES             源码
│   ├── tree-1.6.0.tgz
│   ├── tree-args.patch
│   ├── tree-fixbufsiz.patch
│   ├── tree-no-color-by-default.patch
│   ├── tree-no-strip.patch
│   └── tree-preserve-timestamps.patch
├── SPECS               spec文件
│   └── tree.spec
└── SRPMS

9 directories, 43 files

为rpm添加补丁

  • 修改源码 BUILD/tree.c,添加一行打印

    int main(int argc, char **argv)
    {
      char **dirname = NULL;
      int i,j=0,n,p,q,dtotal,ftotal,colored = FALSE;
      struct stat st;
      char sizebuf[64];
      off_t size = 0;
      mode_t mt;
    
      printf("new patch by kira");
    
  • 备份、添加patch文件

    [root@localhost BUILD]# cp -rf tree-1.6.0/ tree-1.6.0.orgin/
    先拷贝,再修改,再生成补丁
    [root@localhost BUILD]# diff -upNr tree-1.6.0.orgin/ tree-1.6.0/  > ../SOURCES/tree-by-kira.patch
    
  • 修改spec文件

    • 刷新个版本号
      Release: 11%{?dist}
      
    • Patch5后面添加
      Patch6: tree-by-kira.patch
      
    • %patch5后面添加一个新补丁
      # by kira
      %patch6 -p1 -b .by_kira
      
  • 再次构建二进制rpm

    [root@localhost SPECS]# rpmbuild -ba tree.spec
    
  • 升级tree

    [root@localhost x86_64]# rpm -Uvh tree-1.6.0-11.el7.x86_64.rpm
    准备中...                          ################################# [100%]
    正在升级/安装...
       1:tree-1.6.0-11.el7                ################################# [ 50%]
    正在清理/删除...
       2:tree-1.6.0-10.el7                ################################# [100%]
    [root@localhost x86_64]#
    
  • 最终效果

    [root@localhost x86_64]# tree
    new patch by kira
    ├── tree-1.6.0-10.el7.x86_64.rpm
    ├── tree-1.6.0-11.el7.x86_64.rpm
    ├── tree-debuginfo-1.6.0-10.el7.x86_64.rpm
    └── tree-debuginfo-1.6.0-11.el7.x86_64.rpm
    
    0 directories, 4 files
    [root@localhost x86_64]#