• 如何创建rpm包


    本文展示如何将脚本打包成rpm格式的文件

    什么是RPM包?

    RPM是Red Hat Package Manager的简称,rpm包可以在redhat系列的系统轻松安装,更新,卸载。包括Fedora, CentOS, RHEL, etc.

    RPM包使用.rpm扩展名,是一个压缩包,包含

    • 二进制文件(nmap, stat, xattr, ssh, sshd, and so on)
    • 配置文件 (sshd.conf, updatedb.conf, logrotate.conf, etc.)
    • 文档 (README, TODO, AUTHOR, etc)

    rpm包的名字一般格式:

    <name>-<version>-<release>.<arch>.rpm
    
    • 1

    例如:

    bdsync-0.11.1-1.x86_64.rpm
    
    • 1

    一些包也包含rpm的适用平台:

    bdsync-0.11.1-1.el8.x86_64.rpm
    
    • 1

    如何创建rpm包

    1. 安装rpm开发工具

     yum install -y rpmdevtools rpmlint
    
    • 1

    2. 创建rpm包开发目录

    创建rpm包的开发目录,位置一般在$HOME/rpmbuild

    $ rpmdev-setuptree
    
    • 1

    开发目录结构及作用如下:

    rpmbuild/
    ├── BUILD
    ├── RPMS
    ├── SOURCES
    ├── SPECS
    └── SRPMS
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • BUILD 目录用于存放rpm构建过程中产生的临时文件
    • RPMS 目录存放成果rpm包
    • SOURCES 目录存放源码。 可以是简单的脚本,需要编译的复杂的C项目。源码的格式通常是.tar.gz或者.tgz
    • SPEC 目录存放.spec文件, .spec文件用于定义如何打包rpm
    • SPRPMS 存放.src.rpm包,源码包不属于任何架构或者Linux发行版。 实际的.rpm包是基于.src.rpm包构建的。

    创建一个简单的rpm包

    1. 创建一个简单的脚本
    $ cat << EOF >> hello.sh
    #!/bin/sh
    echo "Hello world"
    EOF
    
    • 1
    • 2
    • 3
    • 4
    1. 创建源码包
    mkdir hello-0.0.1
    mv hello.sh hello-0.0.1
    tar --create --file hello-0.0.1.tar.gz hello-0.0.1
    mv hello-0.0.1.tar.gz $HOME/rpmbuild/SOURCES
    
    • 1
    • 2
    • 3
    • 4
    1. 创建spec文件

    如下命令生成模板spec

    rpmdev-newspec hello
    
    • 1

    现在的目录机构如下所示:

    /root/rpmbuild/
    ├── BUILD
    ├── BUILDROOT
    ├── RPMS
    ├── SOURCES
    │   └── hello-0.0.1.tar.gz
    ├── SPECS
    │   └── hello.spec
    └── SRPMS
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • hello.spec
    Name:           hello
    Version:        0.0.1
    Release:        1%{?dist}
    Summary:        A simple hello world script   
    BuildArch:      noarch      # noarch代表任何芯片架构或者发行版都可以安装
    
    License:        GPL
    Source0:        %{name}-%{version}.tar.gz  # 源码包名字,此处为hello-0.0.1.tar.gz
    
    Requires:       bash   # 此软件安装的前提是需要bash,多个的话用","分隔,比如gcc,gcc-c++
    
    %description
    A demo RPM build
    
    %prep
    %setup -q    # 这一步是解压SOURCES目录的源码包
    
    %install
    rm -rf $RPM_BUILD_ROOT    # RPM_BUILD_ROOT是构建当前目录,宏常量
    mkdir -p $RPM_BUILD_ROOT/%{_bindir}
    cp %{name}.sh $RPM_BUILD_ROOT/%{_bindir}  # 拷贝到rpm包的%{_bindir}的目录下,%{_bindir}为宏常量,通常为/usr/bin
    
    %clean
    rm -rf $RPM_BUILD_ROOT
    
    %files
    %{_bindir}/%{name}.sh  #  /usr/bin/hello.sh 相当于把rpm包里的hello.sh放到/usr/bin下
    
    %changelog
    * Sun Nov  18 2020 Valentin Bajrami <valentin.bajrami@slimmer.ai> - 0.0.1
    - First version being packaged
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    宏常量的查看方式

    $ rpm --eval '%{_bindir}'
    /usr/bin
    Other useful macros:
    
    • 1
    • 2
    • 3

    其他常用宏常量:

    • %{name} name of the package (as defined in the Name: field)
    • %{version} version of the package (as defined in the Version: field)
    • %{_datadir} shared data (/usr/sbin by default)
    • %{_sysconfdir} configuration directory (/etc by default)
    1. 检测spec文件有效性
    $ rpmlint ~/rpmbuild/SPECS/hello.spec
    SPECS/hello.spec: W: no-%build-section
    SPECS/hello.spec: W: invalid-url Source0: hello-0.0.1.tar.gz
    0 packages and 1 specfiles checked; 0 errors, 2 warnings.
    
    • 1
    • 2
    • 3
    • 4
    1. 构建rpm包
    rpmbuild -ba hello.spec
    
    • 1
    • -b build
    • -a both source and binary packages
    1. 测试安装包
    cd ~/rpmbuild/RPMS
    rpm -ivh hello-0.0.1.rpm
    
    • 1
    • 2

    检测rpm是否成功:

    rpm -qi hello
    
    • 1

    Troubleshoting

    1. 缺少so文件

    在一些场景下,.so文件包含于rpm包中,但是运行rpm -ivh时出现,如下报错:

    $ rpm -ivh hello.rpm
    error: Failed dependencies:
            lib3ds-2.so()(64bit) is needed by cips-22.05.06-1.el7.x86_64
            libAltova.so()(64bit) is needed by cips-22.05.06-1.el7.x86_64
            libAltovaXML.so()(64bit) is needed by cips-22.05.06-1.el7.x86_64
            libGLEW.so.2.1()(64bit) is needed by cips-22.05.06-1.el7.x86_64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这是因为rpmbuild过程中会自动检测软件所需的.so依赖,但是仅检测通过rpm方式安装的。假如.so文件在rpm里,安装可以使用--nodeps选项来跳过检测, 这并不会影响软件正常运行。

    rpm -ivh --nodeps *.rpm
    
    • 1

    Reference List

    1. 翻译
      How to create a Linux RPM package

    2. 参考:

      • https://www.cnblogs.com/dissipate/p/13050646.html
      • https://www.thegeekstuff.com/2015/02/rpm-build-package-example/#:~:text=To%20build%20an%20rpm%20file%20based%20on%20the,rpm-build%20package.%20Install%20it%20as%20shown%20show%20below.
  • 相关阅读:
    VS Code里使用Debugger for Unity插件进行调试(2023最新版)
    【软件与系统安全笔记】二、软件与系统安全基础
    【Java成王之路】EE初阶第十七篇: maven 工具
    百度Apolo自动驾驶_百度车载小程序
    leetcode_2558 从数量最多的堆取走礼物
    思科、华为、华三、锐捷网络设备巡检命令
    [云原生2.] Kurbernetes资源管理 ---- (陈述式资源管理方式)
    el-tooltip中 content点击事件 弹窗闪烁引发的思考
    9.1.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-道路分割分析
    【实习小tip】el-form设置label文字宽度、设置el-label和el-input等高、服务器端(接口)方式URL Scheme获取
  • 原文地址:https://blog.csdn.net/qq_33745102/article/details/126144536