• rpm打包新手入门


    rpm介绍

    RPM(Red Hat Package Manager)是一种软件包管理工具,主要用于Red Hat及其衍生发行版如Fedora、CentOS等。RPM可以帮助用户方便地安装、升级、删除软件包。RPM包主要由以下几部分组成:

    • 包名:软件包的名称,如httpd。
    • 版本:软件的版本号,如2.4.6。
    • 发行号:针对特定版本的软件制作的RPM包的版本,如1.el7。
    • 架构:软件包适用的硬件架构,如x86_64、i386等。 一个完整的RPM包名示例:httpd-2.4.6-1.el7.x86_64.rpm

    通过学习rpm包的相关知识,我们可以将自己的软件打包成rpm包,以便于在基于Red Hat的Linux发行版(如Fedora、CentOS等)上进行分发和安装。将软件打包成RPM包有以下优点:

    • 管理依赖关系:RPM包可以包含构建和运行时所需的依赖信息,这有助于确保在安装过程中自动满足所有必要的依赖关系。
    • 一致性和可重复性:RPM包提供了一种标准化的方法来构建和安装软件,从而确保在不同的系统上具有一致性和可重复性。
    • 方便的安装和升级:用户可以通过rpm命令或者包管理工具(如yum或dnf)轻松地安装、升级或删除RPM包,而无需手动下载和解压源代码或二进制文件。
    • 软件包的元数据和文档:RPM包包含了软件的元数据(如名称、版本、许可证等)以及描述、变更日志等信息,这有助于用户了解软件包的内容和历史。

    rpm打包

    为了将我们的软件打包成rpm包,我们需要使用rpm-build工具:

    sudo yum install rpm-build
    
    • 1

    在使用rpm-build工具构建RPM包时,需要按照一定的目录结构组织软件。这些目录通常位于~/rpmbuild(用户的主目录下的rpmbuild文件夹),包含BUILD,RPMS,SOURCES,SPECS,SRPMS子目录。

    • SPECS:这个目录用于存储.spec(SPECifications)文件,即RPM包的规范文件。.spec文件包含了软件包的元数据、描述、变更日志以及在各个构建阶段需要执行的命令。rpmbuild命令会读取这个目录中的.spec文件以执行构建过程。一个.spec文件主要包括以下两部分内容:
      a. 软件包的元信息:这部分包括软件包的名称、版本、发行号、许可证等元数据,以及构建和运行时所需的依赖。这些信息用于描述软件包的基本属性,以及在安装和构建过程中需要满足的依赖关系。
      b.详细信息和构建命令:这部分通过不同的标签(如%description、%changelog、%prep、%build、%install 和 %files)记录了软件包的详细描述、变更日志以及在各个构建阶段需要执行的操作。这些标签定义了软件包的构建过程,并提供了有关软件包内容和历史的详细信息。通过组合这两部分内容,.spec文件为RPM包提供了完整的描述和构建指南。这使得RPM包可以在不同的系统上进行一致的构建和安装。

      • %description:这个标签用于提供软件包的详细描述。在这个标签下的文本会被视为软件包的描述信息,通常用于向用户介绍软件包的功能、用途等。这部分信息会在查询软件包信息时显示,例如使用 rpm -qi 命令。
      • %changelog:这个标签用于记录软件包的变更历史。在这个标签下,你需要按照特定的格式添加每个版本的变更记录,包括日期、维护者的姓名和电子邮件地址、软件包的版本和发行号以及变更描述。这部分信息对于跟踪软件包的发展和了解各个版本之间的差异非常有用。
      • %prep:准备阶段,通常用于解压源代码文件并应用任何补丁。在这个阶段可以执行一些准备工作,例如清理目录、检查环境等。
      • %build:构建阶段,用于编译源代码并生成可执行文件、库文件等。在这个阶段可以执行编译命令,如make,以及其他与构建过程相关的命令。
      • %install:安装阶段,用于将编译好的文件安装到构建根目录(%{buildroot})下的相应位置。在这个阶段可以执行安装命令,如make install,以及其他与安装过程相关的命令。
      • %files:文件列表阶段,用于指定RPM包中包含的文件。在这个阶段需要列出所有要包含在最终RPM包中的文件和目录。
    • SOURCES:这个目录用于存储软件包的源代码文件,例如源代码的压缩文件(如hello-rpm-1.0.tar.gz)、补丁文件等。在构建过程中,%prep阶段会从这个目录中提取源代码文件。

    • BUILD:这个目录用于存储在构建过程中产生的临时文件。当执行%prep和%build阶段时,源代码会被解压并编译在这个目录下。完成构建过程后,这个目录下的文件通常会被丢弃,因为它们不会包含在最终的RPM包中。

    • RPMS:这个目录用于存储构建完成后的二进制RPM包。在%install和%files阶段完成后,生成的RPM包会被放入这个目录。RPMS目录下通常还会根据不同的硬件架构分成子目录,例如x86_64、i386等。

    • SRPMS:这个目录用于存储源代码RPM包(Source RPM)。源代码RPM包包含了软件的源代码以及构建该软件所需的.spec文件。与二进制RPM包相比,源代码RPM包允许用户在本地环境中自行构建和安装软件,有时这对于定制软件或解决特定问题是很有帮助的。

    在打包完成得到rpm包后,用户可以通过rpm命令或者包管理工具(如yum或dnf)轻松地安装、升级或删除RPM包

    打包示例
    下面将会用一个简单的示例向大家具体地展示如何进行rpm打包。

    假定我们有一个C++程序,使用cmake进行构建:

    hello-rpm-1.0
    ├── CMakeLists.txt
    └── hello-rpm.cpp
    
    • 1
    • 2
    • 3

    hello-rpm.cpp

    #include 
    
    using namespace std;
    
    int main() {
    	cout << "Hello RPM!" << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    project(hello-rpm)
    
    set(CMAKE_CXX_STANDARD 11)
    
    add_executable(hello-rpm hello-rpm.cpp)
    
    install(TARGETS hello-rpm DESTINATION /usr/bin)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    将程序源码进行压缩:

    tar -zcvf hello-rpm-1.0.tar.gz hello-rpm-1.0/
    
    • 1

    创建rpmbuild目录结构:

    mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
    
    • 1

    在使用rpm-build工具构建RPM包时,一般会要求在用户的/(用户主目录)下创建rpmbuild目录。这是因为rpmbuild工具默认会在/rpmbuild目录下查找源代码、构建规范文件和构建结果等文件。

    将源代码压缩文件复制到~/rpmbuild/SOURCES目录下:

    cp hello-rpm-1.0.tar.gz ~/rpmbuild/SOURCES/
    
    • 1

    在~/rpmbuild/SPECS目录下创建hello-rpm.spec文件:除了%description这些阶段标签,其他以%开头的都是一些rpm-build提供的宏,辅助完成打包工作

    # 软件包名称
    Name:           hello-rpm     
    # 版本号
    Version:        1.0           
    # 发行版本号,是一个宏用来获取系统发行版本号
    Release:        1%{?dist}     
    # 简短描述
    Summary:        A simple C++ program built with cmake
    
    # 许可证类型
    License:        GPLv3+        
    # 软件包的官方网址
    URL:            https://www.example.com/  
    # 定义了源代码文件的位置
    # %{name}和%{version}分别对应之前定义的软件包名称和版本号,即"hello-rpm-1.0.tar.gz"
    # rpmbuild工具通常期望源代码文件夹的名称也符合%{name}-%{version}格式。
    Source0:        %{name}-%{version}.tar.gz 
                                              
    # 构建时依赖
    BuildRequires:  gcc-c++, cmake, make   
    
    # 详细描述
    %description    
    This is a simple C++ program built with cmake, as an example of creating an RPM package.
    
    # 准备阶段
    %prep    
    # 解压缩源代码文件,并将当前工作目录切换到解压后的源代码目录       
    %setup -q       
    
    # 构建阶段
    %build          
    # 运行cmake命令,自动处理一些常见的构建参数
    %cmake          
    # 运行make工具,根据之前生成的Makefile来编译源代码。%{?_smp_mflags}宏会根据系统的可用处理器核心数自动设置make命令的-j选项,以便在编译过程中充分利用系统资源,加快编译速度。
    make %{?_smp_mflags}  
      
    # 安装阶段
    %install        
    # 将编译好的文件安装到%{buildroot}目录下
    # %{buildroot}表示构建过程中的临时安装目录
    make install DESTDIR=%{buildroot} 
                                      
    # 文件列表阶段
    %files          
    %{_bindir}/hello-rpm
    # 指定与软件包相关的文档文件,允许用户仅安装软件包的文档,而不是整个软件包。这可以通过在安装时使用rpm命令的--excludedocs选项来实现。
    %doc       
         
    %changelog
    * Wed Oct 11 2023 Your Name  - 1.0-1
    - Initial release
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    在%files部分,%{_bindir}/hello-rpm表示应该将名为hello-rpm的文件包含在最终的RPM包中。这个文件在%install阶段已经被安装到了构建根目录(%{buildroot})下的%{_bindir}目录中。%{_bindir}宏通常会被替换为/usr/bin。

    因此,在RPM包被安装到系统时,hello文件将从构建根目录(%{buildroot})下的/usr/bin目录被复制到系统的/usr/bin目录下。这样,用户就可以在命令行中直接运行hello-rpm命令。
    在完成上面的工作后,使用rpmbuild工具进行打包:

    rpmbuild -ba ~/rpmbuild/SPECS/hello-rpm.spec
    
    • 1

    在RPMS和SRPMS目录下查看打包完成的rpm二进制包和源码包:

    $ tree RPMS/
    RPMS/
    └── x86_64
        ├── hello-rpm-1.0-1.el7.x86_64.rpm
        └── hello-rpm-debuginfo-1.0-1.el7.x86_64.rpm
    
    1 directory, 2 files
    
    tree SRPMS/
    SRPMS/
    └── hello-rpm-1.0-1.el7.src.rpm
    
    0 directories, 1 file
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    然后我们就可以使用rpm命令或者yum/dnf包管理工具进行安装:

    $ sudo yum install ~/rpmbuild/RPMS/x86_64/hello-rpm-1.0-1.el7.x86_64.rpm
    Loaded plugins: fastestmirror, langpacks
    Examining /home/edward/rpmbuild/RPMS/x86_64/hello-rpm-1.0-1.el7.x86_64.rpm: hello-rpm-1.0-1.el7.x86_64
    Marking /home/edward/rpmbuild/RPMS/x86_64/hello-rpm-1.0-1.el7.x86_64.rpm to be installed
    Resolving Dependencies
    --> Running transaction check
    ---> Package hello-rpm.x86_64 0:1.0-1.el7 will be installed
    --> Finished Dependency Resolution
    
    Dependencies Resolved
    
    ===========================================================================================================================================
     Package                      Arch                      Version                       Repository                                      Size
    ===========================================================================================================================================
    Installing:
     hello-rpm                    x86_64                    1.0-1.el7                     /hello-rpm-1.0-1.el7.x86_64                    7.0 k
    
    Transaction Summary
    ===========================================================================================================================================
    Install  1 Package
    
    Total size: 7.0 k
    Installed size: 7.0 k
    Is this ok [y/d/N]: y
    Downloading packages:
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
      Installing : hello-rpm-1.0-1.el7.x86_64                                                                                              1/1 
      Verifying  : hello-rpm-1.0-1.el7.x86_64                                                                                              1/1 
    
    Installed:
      hello-rpm.x86_64 0:1.0-1.el7                                                                                                             
    
    Complete!
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36

    运行hello-rpm:

    $ hello-rpm 
    Hello RPM!
    
    • 1
    • 2

    运行成功!!!
    我们也可以再使用yum卸载:

    $ sudo yum remove hello-rpm.x86_64 
    Loaded plugins: fastestmirror, langpacks
    Resolving Dependencies
    --> Running transaction check
    ---> Package hello-rpm.x86_64 0:1.0-1.el7 will be erased
    --> Finished Dependency Resolution
    
    Dependencies Resolved
    
    ===========================================================================================================================================
     Package                      Arch                      Version                      Repository                                       Size
    ===========================================================================================================================================
    Removing:
     hello-rpm                    x86_64                    1.0-1.el7                    @/hello-rpm-1.0-1.el7.x86_64                    7.0 k
    
    Transaction Summary
    ===========================================================================================================================================
    Remove  1 Package
    
    Installed size: 7.0 k
    Is this ok [y/N]: y
    Downloading packages:
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
      Erasing    : hello-rpm-1.0-1.el7.x86_64                                                                                              1/1 
      Verifying  : hello-rpm-1.0-1.el7.x86_64                                                                                              1/1 
    
    Removed:
      hello-rpm.x86_64 0:1.0-1.el7                                                                                                             
    
    Complete!
    $ hello-rpm
    bash: hello-rpm: command not found...
    
    • 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
    • 32
    • 33
    • 34
    • 35

    大功告成!

  • 相关阅读:
    Python 继承和子类示例:从 Person 到 Student 的演示
    【零基础入门MyBatis系列】第十二篇——高级映射、延迟加载
    MySQL数据库读取外部文件
    多寄存器内存访问指令的寻址方式
    【问题思考总结】CPU怎么访问磁盘?CPU只有32位,最多只能访问4GB的空间吗?
    MySQL系列----什么是MySQL?
    嵌入式实操----基于RT1170 移植memtester做SDRAM测试(二十五)
    微机----------LED显示接口
    C++中的继承
    【数据结构】ArrayList详解
  • 原文地址:https://blog.csdn.net/T_T233333333/article/details/133770250