Skip to content

How to Build RPM Package on Anolis OS

Eason edited this page Sep 12, 2024 · 3 revisions

Anoils lkvs RPM package

CPU:EMR Anoils version: Anolis OS release 23

Preliminary preparation

  1. Network
  2. Install RPM package tool
yum install rpm-build
yum install rpmdevtools
  1. Create a workspace
rpmdev-setuptree

Rpmbuild directory will be added to the $HOME directory. The directory structure is as follows:

$ tree rpmbuild
rpmbuild
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS

Make RPM software package

  1. SOURCES requires lkvs source code package: lkvs.tar kernel source code package: linux-6.10.tar.xz idxd-config source: idxd-config.tar

  2. SPECS Command rpmdev-newspec will create a spec template.

Name:  lkvs
Version:  1.0
Release:  1%{?dist}
Summary:  LKVS RPM package

License:  GPL
URL:      https://github.com/intel/lkvs
Source0:  lkvs.tar
Source1:  linux-6.10.tar.xz
Source2:  idxd-config.tar

BuildRequires:  gcc make gcc-c++ automake kernel-devel libcap-devel automake m4 libtool asciidoc xmlto uuid uuid-devel libuuid-devel json-c-devel zlib-devel openssl-devel python3-pip pciutils-devel gettext
Requires: msr-tools stress perf hwloc-gui gcc cpuid python3-pip

# Disable the debugging package
%global debug_package %{nil}

%description
The Linux Kernel Validation Suite (LKVS) is a Linux Kernel test suite. It is a working project created by the Intel Core Linux Kernel Val Team. The purpose is to improve the quality of Intel-contributed Linux Kernel code. Furthermore, it shows the customer how to use or validate the features.

%prep
# Unzip the source code
%setup -c -T -a 0
mv lkvs %{_builddir}/
%setup -c -T -a 1
mv linux-6.10 %{_builddir}/
%setup -c -T -a 2
mv idxd-config %{_builddir}/

%build
# Compile Linux kernel tools cpupower and turbostat
pushd %{_builddir}/linux-6.10/tools/power/cpupower
%make_build
popd

pushd %{_builddir}/linux-6.10/tools/power/x86/turbostat
%make_build
popd

# If you need to compile more kernel tools, you can continue to add here.

# Compile idxd-config
pushd %{_builddir}/idxd-config
./autogen.sh 
%configure --disable-static --disable-silent-rules --enable-test
popd

# To compile lkvs, only the executable files required for tests under scenario/emr-oe are compiled here; if you need executable files in other lkvs, you can continue to add them.
pushd %{_builddir}/lkvs/BM/tools
%make_build
popd

pushd %{_builddir}/lkvs/BM/amx/tmul
%make_build
popd

pushd %{_builddir}/lkvs/BM/avx512vbmi
%make_build
popd

pushd %{_builddir}/lkvs/BM/telemetry
%make_build
popd

pushd %{_builddir}/lkvs/BM/umip
%make_build
popd

pushd %{_builddir}/lkvs/BM/xsave
%make_build
popd

%install
# Install the compiled executable file, __brp_mangle_shebangs is to prevent BRP scripts from checking and modifying interpreter instructions.
%undefine __brp_mangle_shebangs

# install cpupower and turbostat
pushd %{_builddir}/linux-6.10/tools/power/cpupower
make install DESTDIR=%{buildroot}
popd

pushd %{_builddir}/linux-6.10/tools/power/x86/turbostat
make install DESTDIR=%{buildroot}
popd

pushd %{_builddir}/idxd-config
make install DESTDIR=%{buildroot}
popd

# Since lkvs does not have an install process and is designed with multiple executable scripts, all relevant files are directly packaged into the RPM package.
mkdir -p %{buildroot}/usr/local
cp -a %{_builddir}/lkvs %{buildroot}/usr/local

%files
/usr/bin/cpupower
/usr/bin/turbostat
/usr/local/lkvs/*
/etc/cpufreq-bench.conf
/usr/bin/cpufreq-bench_plot.sh
/usr/include/cpufreq.h
/usr/include/cpuidle.h
/usr/include/powercap.h
/usr/lib64/libcpupower.so
/usr/lib64/libcpupower.so.0.0.1
/usr/lib64/libcpupower.so.1
/usr/local/lkvs/.git/HEAD
/usr/local/lkvs/.git/config
/usr/local/lkvs/.git/description
/usr/local/lkvs/.git/hooks/applypatch-msg.sample
/usr/local/lkvs/.git/hooks/commit-msg.sample
/usr/local/lkvs/.git/hooks/fsmonitor-watchman.sample
/usr/local/lkvs/.git/hooks/post-update.sample
/usr/local/lkvs/.git/hooks/pre-applypatch.sample
/usr/local/lkvs/.git/hooks/pre-commit.sample
/usr/local/lkvs/.git/hooks/pre-merge-commit.sample
/usr/local/lkvs/.git/hooks/pre-push.sample
/usr/local/lkvs/.git/hooks/pre-rebase.sample
/usr/local/lkvs/.git/hooks/pre-receive.sample
/usr/local/lkvs/.git/hooks/prepare-commit-msg.sample
/usr/local/lkvs/.git/hooks/push-to-checkout.sample
/usr/local/lkvs/.git/hooks/sendemail-validate.sample
/usr/local/lkvs/.git/hooks/update.sample
/usr/local/lkvs/.git/index
/usr/local/lkvs/.git/info/exclude
/usr/local/lkvs/.git/logs/HEAD
/usr/local/lkvs/.git/logs/refs/heads/main
/usr/local/lkvs/.git/logs/refs/remotes/origin/HEAD
/usr/local/lkvs/.git/objects/pack/pack-c6e530c94fb3358dd377f28c31a72dfa23da237f.idx
/usr/local/lkvs/.git/objects/pack/pack-c6e530c94fb3358dd377f28c31a72dfa23da237f.pack
/usr/local/lkvs/.git/objects/pack/pack-c6e530c94fb3358dd377f28c31a72dfa23da237f.rev
/usr/local/lkvs/.git/packed-refs
/usr/local/lkvs/.git/refs/heads/main
/usr/local/lkvs/.git/refs/remotes/origin/HEAD
/usr/local/lkvs/.github/scripts/build_check
/usr/local/lkvs/.github/scripts/cfg-lint-check.py
/usr/local/lkvs/.github/scripts/pr_check
/usr/local/lkvs/.github/scripts/requirements-ci.txt
/usr/local/lkvs/.github/workflows/pull_request.yml
/usr/local/lkvs/.gitmodules
/usr/man/man1/cpupower-frequency-info.1.zst
/usr/man/man1/cpupower-frequency-set.1.zst
/usr/man/man1/cpupower-idle-info.1.zst
/usr/man/man1/cpupower-idle-set.1.zst
/usr/man/man1/cpupower-info.1.zst
/usr/man/man1/cpupower-monitor.1.zst
/usr/man/man1/cpupower-powercap-info.1.zst
/usr/man/man1/cpupower-set.1.zst
/usr/man/man1/cpupower.1.zst
/usr/sbin/cpufreq-bench
/usr/share/bash-completion/completions/cpupower
/usr/share/doc/packages/cpupower/README-BENCH
/usr/share/doc/packages/cpupower/cpufreq-bench_script.sh
/usr/share/locale/cs/LC_MESSAGES/cpupower.mo
/usr/share/locale/de/LC_MESSAGES/cpupower.mo
/usr/share/locale/fr/LC_MESSAGES/cpupower.mo
/usr/share/locale/it/LC_MESSAGES/cpupower.mo
/usr/share/locale/ka/LC_MESSAGES/cpupower.mo
/usr/share/locale/pt/LC_MESSAGES/cpupower.mo
/usr/share/man/man8/turbostat.8.zst
/etc/accel-config/contrib/configs/app_profile.conf
/etc/accel-config/contrib/configs/net_profile.conf
/etc/accel-config/contrib/configs/os_profile.conf
/etc/accel-config/contrib/configs/profilenote.txt
/etc/accel-config/contrib/configs/storage_profile.conf
/etc/accel-config/contrib/configs/user_default_profile.conf
/usr/bin/accel-config
/usr/include/accel-config/libaccel_config.h
/usr/lib64/libaccel-config.so
/usr/lib64/libaccel-config.so.1
/usr/lib64/libaccel-config.so.1.0.0
/usr/lib64/pkgconfig/libaccel-config.pc
/usr/share/man/man1/accel-config-config-device.1.zst
/usr/share/man/man1/accel-config-config-engine.1.zst
/usr/share/man/man1/accel-config-config-group.1.zst
/usr/share/man/man1/accel-config-config-user-default.1.zst
/usr/share/man/man1/accel-config-config-wq.1.zst
/usr/share/man/man1/accel-config-disable-device.1.zst
/usr/share/man/man1/accel-config-disable-wq.1.zst
/usr/share/man/man1/accel-config-enable-device.1.zst
/usr/share/man/man1/accel-config-enable-wq.1.zst
/usr/share/man/man1/accel-config-list.1.zst
/usr/share/man/man1/accel-config-load-config.1.zst
/usr/share/man/man1/accel-config-save-config.1.zst
/usr/share/man/man1/accel-config.1.zst
/usr/libexec/accel-config/test/common
/usr/libexec/accel-config/test/configs/2g2q_user_1.conf
/usr/libexec/accel-config/test/configs/2g2q_user_2.conf
/usr/libexec/accel-config/test/dsa_config_test_runner.sh
/usr/libexec/accel-config/test/dsa_test
/usr/libexec/accel-config/test/dsa_user_test_runner.sh
/usr/libexec/accel-config/test/iaa_test
/usr/libexec/accel-config/test/iaa_user_test_runner.sh

%changelog
- Initial RPM release.
  1. Generate RPM package Command rpmbuild -bb SPECS/lkvs.spec creates an RPM package, the created package is inrpmbuild/RPMS.

Command rpmbuild -bs SPECS/lkvs.spec creates an SRPM package, the created package is inrpmbuild/SRPMS.

  1. tips:
  • All dependent packages in the BuildRequires field need to be installed on this machine, otherwise the following error will be reported:
[root@emr-anolis rpmbuild]# rpmbuild -bb SPECS/lkvs.spec
setting SOURCE_DATE_EPOCH=1722507469
error: Failed build dependencies:
        asciidoc is needed by lkvs-1.0-1.an23.x86_64
        automake is needed by lkvs-1.0-1.an23.x86_64
        gcc is needed by lkvs-1.0-1.an23.x86_64
        gcc-c++ is needed by lkvs-1.0-1.an23.x86_64
        json-c-devel is needed by lkvs-1.0-1.an23.x86_64
        kernel-devel is needed by lkvs-1.0-1.an23.x86_64
        libcap-devel is needed by lkvs-1.0-1.an23.x86_64
        libtool is needed by lkvs-1.0-1.an23.x86_64
        libuuid-devel is needed by lkvs-1.0-1.an23.x86_64
        m4 is needed by lkvs-1.0-1.an23.x86_64
        openssl-devel is needed by lkvs-1.0-1.an23.x86_64
        pciutils-devel is needed by lkvs-1.0-1.an23.x86_64
        uuid is needed by lkvs-1.0-1.an23.x86_64
        uuid-devel is needed by lkvs-1.0-1.an23.x86_64
        xmlto is needed by lkvs-1.0-1.an23.x86_64
  • In the %file field of the SPEC, you need to list all the files in the RPM package, otherwise the following error will be reported:
RPM build errors:
Installed (but unpackaged) file(s) found:       
/etc/cpufreq-bench.conf
/usr/bin/cpufreq-bench_plot.sh

A quick solution is to add all the listed files to the %file field.

  • In order to reduce the number of files in the %file field, you can delete the .git and .github directory under lkvs. By doing this, the %file field can be stripped of files starting with /usr/local/lkvs/.git or /usr/local/lkvs/.github.

  • In order to be able to execute all test cases with one click, an execution script is required, which may be similar to:

#!/usr/bin/env python3

import os
import subprocess
import sys

intel_dir = os.path.dirname(os.path.realpath(__file__))

tests = [
            ["amx/tmul", "tests-amx"],
            ["avx512vbmi", "tests-avx512vbmi"],
            ["cstate", "tests-cstate"],
            ["dsa", "tests-dsa1"],
            ["ifs", "tests-ifs"],
            ["pmu", "tests-pmu"],
            ["pstate", "tests-pstate"],
            ["rapl", "tests-rapl"],
            ["telemetry", "tests-telemetry"],
            ["topology", "tests-topology"],
            ["umip", "tests-umip"],
            ["xsave", "tests-xsave"]]

# Mapping of CPU family IDs to platform names
cpu_family_mapping = {
        '143': 'spr',
        '207': 'emr',
        '173': 'gnr',
}

def get_cpu_family_id():
    # Run the 'lscpu' command and capture its output
    result = subprocess.run(['/usr/bin/lscpu'], capture_output=True, text=True, check=True)

    # Split the output into lines
    output_lines = result.stdout.splitlines()

    # Find the line containing "Model:" and extract the family ID
    for line in output_lines:
        if "Model:" in line:
            # Assuming the family ID follows 'Model:' and is separated by spaces
            family_id = line.split(':')[1].strip()
            return family_id

    # If "Model:" line is not found, raise an exception
    raise ValueError("'Model:' entry not found in lscpu output")

def install_package(package):
    log_file = os.path.join(intel_dir, "log.txt")
    with open(log_file, 'w') as log_file:
        subprocess.check_call(
            [sys.executable, "-m", "pip", "install", package],
            stdout=log_file,
            stderr=log_file
        )

def set_up():
    install_package("avocado-framework")
    DIR_CONFIG_AVOCADO = "/root/.config/avocado"
    CONFIG_AVOCADO = os.path.join(DIR_CONFIG_AVOCADO, "avocado.conf")
    
    os.makedirs(DIR_CONFIG_AVOCADO, exist_ok=True)
    
    with open(CONFIG_AVOCADO, 'w') as config_file:
        config_file.write("[run]\n")
        config_file.write("max_parallel_tasks=1\n")

def run_test():
    ret = 0
    log_file = os.path.join(intel_dir, "log.txt")
    os.chdir(f'{intel_dir}/BM')
    platform = cpu_family_mapping.get(get_cpu_family_id())

    with open(log_file, 'a') as log_file:
        for t in tests:
            result = subprocess.run(
                ["python3", "runtests.py", "-f", t[0], "-t", f"{intel_dir}/scenario/{platform}-oe/{t[1]}"],
                stdout=log_file,
                stderr=log_file
            )
            if result.returncode == 0:
                print("[PASS]%s: %s test successfully!" % (t[0], t[1]))
            else:
                print("[FAIL]%s: %s test failed!" % (t[0], t[1]))
                ret += 1

    if ret != 0:
        print("Test failed!")
    else:
        print("Test successfully!")

if __name__ == "__main__":
    print("Satrt install the execution framework.")
    set_up()
    print()
    print("Start tests!")
    run_test()

Note: the script above should in lkvs.tar.

Use RPM package

  1. install the RPM package: rpm -ivp lkvs*.rpm --force