【Linux】How to be a rpms maker

Reference:

https://bbs.huaweicloud.com/forum/thread-38327-1-1.html

Prerequisites
1
2
3
4
5
6
7
On Fedora, CentOS 8, and RHEL 8:
$ dnf install gcc rpm-build rpm-devel rpmlint make python bash coreutils diffutils
patch rpmdevtools
On CentOS 7 and RHEL 7:
$ yum install gcc rpm-build rpm-devel rpmlint make python bash coreutils diffutils
patch rpmdevtools
3
My First RPM Package

1.spec file with several things skipped and simplified:(put a bash script in /usr/bin)

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
Name:   hello-world
Version: 1
Release: 1
Summary: Most simple RPM package
License: FIXME

%description
this is my first RPM package ,which does nothing.

%prep
#we have no source ,so nothing here.

%build
cat > hello-world.sh << EOF
#!/usr/bin/bash
echo hello world
EOF

%install
mkdir -p %{buildroot}/usr/bin
install -m 755 hello-world.sh %{buildroot}/usr/bin/hello-world.sh

%files
/usr/bin/hello-world.sh

%changelog
* Sat Jun 25 2022 root

2.rpmbuild

1
rpmbuild -ba rpmbuild/SPECS/hello_world.spec

3.install her

1
rpm -ivh rpmbuild/RPMS/x86_64/hello-world-1-1.x86_64.rpm

4.validate her

1
2
3
4
[root@hik ~]# ll /usr/bin/hello-world.sh 
-rwxr-xr-x. 1 root root 35 Jun 25 19:56 /usr/bin/hello-world.sh
[root@hik ~]# /usr/bin/hello-world.sh
hello world
Preparing Software For Packaging
  1. Source codes including Makefile

  2. Patch Software

  3. Installing arbitrary Artifacts

    In the context of this guide, an Arbitrary Artifact is anything installed from an RPM to the system.

    For RPM and for the system it can be a script, a binary compiled from the package’s source code, a
    pre-compiled binary, or any other file.

    We will explore two popular ways of placing Arbitrary Artifacts in the system: using the install
    command and using the make install command.

    • Using the install command

      Sometimes using build automation tooling such as GNU make is not optimal - for example, if the
      packaged program is simple and does not need extra overhead. In these cases, packagers often use
      the install command (provided to the system by coreutils), which places the artifact to the
      specified directory in the filesystem with a specified set of permissions.

      eg.

      1
      $ sudo install -m 0755 bello /usr/bin/bello
    • Using the make install command

      A popular automated way to install built software to the system is to use the make install
      command. It requires you to specify how to install the arbitrary artifacts to the system in the
      Makefile.
      NOTE Usually Makefile is written by the developer and not by the packager.
      Add the install section to the Makefile:

      1
      2
      3
      4
      5
      6
      7
      cello:
      gcc -g -o cello cello.c
      clean:
      rm cello
      install:
      mkdir -p $(DESTDIR)/usr/bin
      install -m 0755 cello $(DESTDIR)/usr/bin/cello
  4. Preparing Source Code for Packaging

    My eg.

    1
    2
    3
    4
    5
    6
    7
    [root@hik hello_rpm-1.0]# ll 
    total 36
    -rwxr-xr-x. 1 root root 27560 Jun 25 20:48 hello_rpms
    -rw-r--r--. 1 root root 411 Jun 25 20:39 hello_rpms.c
    -rw-r--r--. 1 root root 160 Jun 25 20:47 Makefile
    [root@hik hello_rpm-1.0]#

    Makefile:

    1
    2
    3
    4
    5
    6
    7
    make:
    gcc -g hello_rpms.c -o hello_rpms
    clean:
    rm hello_rpms
    install:
    mkdir -p ${DESTDIR}/usr/bin
    install -m 0755 hello_rpms ${DESTDIR}/usr/bin/hello_rpms

    validate her:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@hik hello_rpm-1.0]# make
    gcc -g hello_rpms.c -o hello_rpms
    [root@hik hello_rpm-1.0]# make install
    mkdir -p /usr/bin
    install -m 0755 hello_rpms /usr/bin/hello_rpms
    [root@hik hello_rpm-1.0]# hello_rpms #test for double pointer
    old p =(nil)
    *p=4
    new p =0x11ee6b0
  5. Putting Source Code Into Tarball

    Prepare the cello project for distribution:

    1
    2
    3
    4
    5
    6
    1.Put the files into a single directory hello_rpm-1.0 and Create the archive for distribution
    [root@hik SOURCES]# tar -czvf hello_rpm-1.0.tar.gz hello_rpm-1.0/*
    hello_rpm-1.0/hello_rpms.c
    hello_rpm-1.0/Makefile
    2.Move her to ~/rpmbuild/SOURCES/
    3. Add the patch: (later blog version)
Packaging Software

1.RPM Packages

  • What is an RPM?

    An RPM package is simply a file containing other files and information about them needed by the
    system. Specifically, an RPM package consists of the cpio archive, which contains the files, and the
    RPM header, which contains metadata about the package. The rpm package manager uses this
    metadata to determine dependencies, where to install files, and other information.
    There are two types of RPM packages:

    • source RPM (SRPM)
    • binary RPM
    

    SRPMs and binary RPMs share the file format and tooling, but have different contents and serve
    different purposes. An SRPM contains source code, optionally patches to it, and a SPEC file, which
    describes how to build the source code into a binary RPM. A binary RPM contains the binaries built
    from the sources and patches.

  • RPM Packaging Tools

    rpmdevtools

  • RPM Packaging Workspace

    To set up a directory layout that is the RPM packaging workspace, use the rpmdev-setuptree utility:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ rpmdev-setuptree  #生成 目录
    $ tree ~/rpmbuild/ #查看
    /home/user/rpmbuild/
    |-- BUILD
    |-- RPMS
    |-- SOURCES
    |-- SPECS
    `-- SRPMS
    5 directories, 0 files

    The created directories serve these purposes:

    DirectoryPurpose
    BUILDWhen packages are built, various %buildroot directories are created here. This
    is useful for investigating a failed build if the logs output do not provide
    enough information.
    RPMSBinary RPMs are created here, in subdirectories for different architectures, for
    example in subdirectories x86_64 and noarch.
    SOURCESHere, the packager puts compressed source code archives and patches. The
    rpmbuild command looks for them here.
    SPECSThe packager puts SPEC files here.
    SRPMSWhen rpmbuild is used to build an SRPM instead of a binary RPM, the resulting
    SRPM is created here.
  • What is a SPEC File?

    A SPEC file can be thought of as the “recipe” that the rpmbuild utility uses to actually build an RPM.
    It tells the build system what to do by defining instructions in a series of sections. The sections are
    defined in the Preamble and the Body. The Preamble contains a series of metadata items that are
    used in the Body. The Body contains the main part of the instructions.

    • Preamble Items

      This table lists the items used in the Preamble section of the RPM SPEC file:

      SPEC DirectiveDefinition
      NameThe base name of the package, which should match the SPEC file
      name.
      VersionThe upstream version number of the software.
      ReleaseThe number of times this version of the software was released.
      Normally, set the initial value to 1%{?dist}, and increment it with
      each new release of the package. Reset to 1 when a new Version of
      the software is built.
      SummaryA brief, one-line summary of the package.
      LicenseThe license of the software being packaged. For packages distributed
      in community distributions such as Fedora this must be an open
      source license abiding by the specific distribution’s licensing
      guidelines.
      URLThe full URL for more information about the program. Most often
      this is the upstream project website for the software being packaged.
      Source0Path or URL to the compressed archive of the upstream source code
      (unpatched, patches are handled elsewhere). This should point to an
      accessible and reliable storage of the archive, for example, the
      upstream page and not the packager’s local storage. If needed, more
      SourceX directives can be added, incrementing the number each
      time, for example: Source1, Source2, Source3, and so on.
      Patch0The name of the first patch to apply to the source code if necessary.
      If needed, more PatchX directives can be added, incrementing the
      number each time, for example: Patch1, Patch2, Patch3, and so on.
      BuildArchIf the package is not architecture dependent, for example, if written
      entirely in an interpreted programming language, set this to
      BuildArch: noarch. If not set, the package automatically inherits the
      Architecture of the machine on which it is built, for example x86_64.
      BuildRequiresA comma- or whitespace-separated list of packages required for
      building the program written in a compiled language. There can be
      multiple entries of BuildRequires, each on its own line in the SPEC
      file.
      RequiresA comma- or whitespace-separated list of packages required by the
      software to run once installed. There can be multiple entries of
      Requires, each on its own line in the SPEC file.
      ExcludeArchIf a piece of software can not operate on a specific processor
      architecture, you can exclude that architecture here.

      RPM package filenames have the NAME-VERSION-RELEASE format:

      eg.python-2.7.5-34.el7.x86_64

    • Body Items

      This table lists the items used in the Body section of the RPM SPEC file:

      SPEC DirectiveDefinition
      %descriptionfull description of the software packaged in the RPM. This description can
      span multiple lines and can be broken into paragraphs.
      %prepCommand or series of commands to prepare the software to be built, for
      example, unpacking the archive in Source0. This directive can contain a shell
      script.
      %buildCommand or series of commands for actually building the software into
      machine code (for compiled languages) or byte code (for some interpreted
      languages).
      %installCommand or series of commands for copying the desired build artifacts from
      the %builddir (where the build happens) to the %buildroot directory (which
      contains the directory structure with the files to be packaged). This usually
      means copying files from ~/rpmbuild/BUILD to ~/rpmbuild/BUILDROOT and
      creating the necessary directories in ~/rpmbuild/BUILDROOT. This is only run
      when creating a package, not when the end-user installs the package. See
      Working with SPEC files for details.
      %checkCommand or series of commands to test the software. This normally includes
      things such as unit tests.
      %filesThe list of files that will be installed in the end user’s system
      %changelogA record of changes that have happened to the package between different
      Version or Release builds.
    • Advanced items

      The SPEC file can also contain advanced items. For example, a SPEC file can have scriptlets and
      triggers. They take effect at different points during the installation process on the end user’s system
      (not the build process).
      See the Scriptlets and Triggers for advanced topics.

  • BuildRoots

  • RPM Macros

    rpm –eval %{_MACRO} #check for a Macro

    Macros
    %{version}
    %{?dist}distribution tag
  • More on Macros

  • Working with SPEC files

  • FAQ