mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
With the Fedora mapping in place, this patch extends it to the RHEL
family (RHEL, CentOS Stream, Rocky Linux, AlmaLinux, Oracle Linux),
which shares most Fedora package names and runs dnf (RHEL 8 and
later). The names that differ are handled by probing the enabled
repos:
- zlib.h comes from zlib-ng-compat-devel on the RHEL 10 family,
zlib-devel on RHEL 9 and earlier;
- there is no java-latest-openjdk-devel: the JDK devel package is
versioned per release, java-21-openjdk-devel on the RHEL 10
family, java-17-openjdk-devel on RHEL 9, java-11-openjdk-devel
on RHEL 8;
- libbpf-devel and capstone-devel live in the CRB repo on RHEL and
CentOS Stream 10, in EPEL on RHEL 9 and earlier;
- libbabeltrace2-devel is not packaged on the RHEL 10 family.
Packages not available on the enabled repos are skipped instead of
aborting the dnf transaction, and are listed at the end of the run, with
the repo that provides them pointed out in the header comment and help
text: a distro with CRB/EPEL enabled gets the full set, one without them
still installs what it can.
This also holds for the base set: e.g. 'rust' exists only as the
rust-toolset AppStream module on RHEL 8 and 9, where it is not
installable as a plain package, so it is skipped and noted there instead
of failing the whole dnf transaction.
The base set lists pkgconf-pkg-config instead of pkgconfig: both
families have been on pkgconf since Fedora 26 / RHEL 8, where
'pkgconfig' lives only as a virtual Provides of that subpackage, and
a minimal RHEL-family container may not have it preinstalled.
Validated on a fresh CentOS Stream 10 distrobox container, with the
CRB repo enabled, so the host system is not modified:
distrobox create --image quay.io/centos/centos:stream10
distrobox enter centos-stream10
dnf config-manager --set-enabled crb
make -C tools/perf install-build-deps
which installed the 28 available mapped packages; libbabeltrace2-devel, the
only mapped package with no RHEL 10 package, is reported at the end
of the run.
A subsequent 'make -C tools/perf feature-dump' enabled every feature
with an external dependency the RHEL 10 family provides, including
libbpf and libcapstone from the CRB repo, with only
babeltrace2-ctf-writer left out along with the deliberately unmapped
opt-in features.
Re-running the target is a no-op (dnf reports "Nothing to do"); with the
CRB repo disabled, the skipped packages are instead listed in the
end-of-run note, whose header comment and help text point out which repo
provides them.
Members of the family without dnf (RHEL 7 and earlier, e.g. Oracle
Linux 7, a yum-only distro) are rejected with an explicit error while
the dnf-based members get the full mapping.
Example of its --list:
$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Fedora Linux 44 (Toolbx Container Image)"
$ tools/perf/scripts/install-build-deps.sh --list --distro rhel
bison
capstone-devel
clang-devel
elfutils-debuginfod-client-devel
elfutils-devel
elfutils-libelf-devel
flex
gcc
gcc-c++
glibc-devel
java-latest-openjdk-devel
kernel-headers
libbabeltrace2-devel
libbpf-devel
libpfm-devel
libstdc++-devel
libtraceevent-devel
libzstd-devel
llvm-devel
make
numactl-devel
openssl-devel
pkgconf-pkg-config
python3-devel
python3-setuptools
rust
slang-devel
systemtap-sdt-devel
xz-devel
zlib-ng-compat-devel
$
Assisted-by: opencode:deepseek-v4-flash-free
Assisted-by: claude:claude-opus-4-7
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
604 lines
20 KiB
Bash
Executable File
604 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
#
|
|
# No 'set -e': the script uses explicit checks for its error paths, and
|
|
# is also run via '$(SHELL) .../install-build-deps.sh' from the make
|
|
# target in tools/perf/Makefile.perf, where a shebang option would be
|
|
# ignored anyway, so direct and make-driven runs behave the same.
|
|
#
|
|
# Install the development packages needed to build tools/perf.
|
|
#
|
|
# The package set is derived from the feature tests in tools/build/feature/:
|
|
# each feature test that perf may compile is mapped to the devel package
|
|
# that provides the headers/libraries it checks, so that a subsequent
|
|
# 'make -C tools/perf' build enables the corresponding perf features.
|
|
#
|
|
# Currently supported distros, each validated in a fresh container:
|
|
#
|
|
# - Fedora, on dnf, validated on Fedora 44, in a toolbx container:
|
|
#
|
|
# toolbox create fedora:44
|
|
# toolbox enter fedora:44
|
|
#
|
|
# - Ubuntu, on apt-get, validated on Ubuntu 26.04, in a distrobox
|
|
# container:
|
|
#
|
|
# distrobox create --image ubuntu:26.04
|
|
# distrobox enter ubuntu-26-04
|
|
#
|
|
# The apt-get install runs with a noninteractive debconf frontend:
|
|
# default-jdk, needed by the jvmti feature tests, pulls in tzdata,
|
|
# which prompts for the timezone on a terminal and would block the
|
|
# install, e.g. in a container shared with an interactive session.
|
|
#
|
|
# - Debian, on apt-get, reusing the Ubuntu mapping, validated on
|
|
# Debian 13 (trixie), in a distrobox container:
|
|
#
|
|
# distrobox create --image debian:trixie
|
|
# distrobox enter debian-trixie
|
|
#
|
|
# - RHEL and its variants (RHEL, CentOS Stream, Rocky Linux, AlmaLinux,
|
|
# Oracle Linux), on dnf (RHEL 8 and later), validated on CentOS
|
|
# Stream 10, in a distrobox container:
|
|
#
|
|
# distrobox create --image quay.io/centos/centos:stream10
|
|
# distrobox enter centos-stream10
|
|
#
|
|
# The RHEL family reuses most Fedora package names, with these
|
|
# differences, handled by probing the enabled repos:
|
|
#
|
|
# - zlib.h comes from zlib-ng-compat-devel on the RHEL 10 family,
|
|
# zlib-devel on RHEL 9 and earlier;
|
|
# - the JDK devel package is versioned, there is no
|
|
# java-latest-openjdk-devel: java-21-openjdk-devel on the RHEL
|
|
# 10 family, java-17-openjdk-devel on RHEL 9, java-11-openjdk-
|
|
# devel on RHEL 8;
|
|
# - libbpf-devel and capstone-devel are in the CRB repo on RHEL
|
|
# and CentOS Stream 10 ('dnf config-manager --set-enabled crb')
|
|
# and in EPEL on RHEL 9 and earlier;
|
|
# - libbabeltrace2-devel is not packaged on the RHEL 10 family.
|
|
#
|
|
# On the RHEL family, packages not available on the enabled repos
|
|
# are skipped and listed at the end of the run, so that a distro
|
|
# with CRB/EPEL enabled gets the full set, and a distro without
|
|
# them still installs what it can.
|
|
#
|
|
# Running inside a container keeps the host system unmodified.
|
|
#
|
|
# Usage: install-build-deps.sh [OPTIONS]
|
|
#
|
|
# Options:
|
|
# --list list the packages that would be installed, then exit
|
|
# --dry-run show the install command that would be run, without
|
|
# running it
|
|
# --distro ID force a distro: fedora, rhel, ubuntu, debian
|
|
# (default: auto-detect)
|
|
# -h, --help print this help message
|
|
#
|
|
# Requires root (or passwordless sudo) to actually install packages.
|
|
|
|
set -u
|
|
|
|
DISTRO=""
|
|
|
|
help() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") [--list] [--dry-run] [--distro ID] [-h|--help]
|
|
|
|
Install the development packages needed to build tools/perf.
|
|
|
|
The package set is derived from the feature tests in tools/build/feature/,
|
|
mapping each one with an external dependency to the devel package providing
|
|
it, so the corresponding feature gets enabled on a build.
|
|
|
|
Options:
|
|
--list list the packages that would be installed, then exit
|
|
--dry-run show the install command that would be run, without running it
|
|
--distro ID force a distro: fedora, rhel, ubuntu, debian
|
|
-h, --help print this help message
|
|
|
|
Distros supported: Fedora (dnf), validated in a toolbx container on
|
|
Fedora 44, Ubuntu (apt-get), validated in a distrobox container on
|
|
Ubuntu 26.04, Debian (apt-get), reusing the Ubuntu mapping, validated
|
|
in a distrobox container on Debian 13 (trixie), and the RHEL family
|
|
(dnf, RHEL 8 and later), validated on CentOS Stream 10 in a distrobox
|
|
container. On the RHEL family, packages not available on the enabled
|
|
repos are skipped and listed at the end; some there, e.g.
|
|
libbpf-devel and capstone-devel, come from the CRB repo on RHEL and
|
|
CentOS Stream 10 ('dnf config-manager --set-enabled crb') and from
|
|
EPEL on RHEL 9 and earlier.
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Return the Fedora package(s) providing the devel requirements of a
|
|
# feature test in tools/build/feature/. Multiple packages are separated
|
|
# by spaces; an empty result means the test has no external devel
|
|
# dependency (pure toolchain/glibc, or no equivalent Fedora package).
|
|
#
|
|
# The mapping was built by checking, for each feature test, which Fedora
|
|
# devel package provides the headers the test compiles against.
|
|
# ---------------------------------------------------------------------
|
|
fedora_pkg_for() {
|
|
local feat="$1"
|
|
case "$feat" in
|
|
libelf|libelf-getphdrnum|libelf-gelf_getnote|libelf-getshdrstrndx)
|
|
echo "elfutils-libelf-devel"
|
|
;;
|
|
libelf-zstd)
|
|
echo "elfutils-libelf-devel libzstd-devel"
|
|
;;
|
|
libdw)
|
|
echo "elfutils-devel"
|
|
;;
|
|
# test-libdebuginfod.c includes <elfutils/debuginfod.h>, which is
|
|
# provided by elfutils-debuginfod-client-devel, not elfutils-devel.
|
|
libdebuginfod)
|
|
echo "elfutils-debuginfod-client-devel"
|
|
;;
|
|
libnuma|numa_num_possible_cpus)
|
|
echo "numactl-devel"
|
|
;;
|
|
libzstd)
|
|
echo "libzstd-devel"
|
|
;;
|
|
zlib)
|
|
echo "zlib-devel"
|
|
;;
|
|
lzma)
|
|
echo "xz-devel"
|
|
;;
|
|
libslang)
|
|
echo "slang-devel"
|
|
;;
|
|
libcapstone)
|
|
echo "capstone-devel"
|
|
;;
|
|
libpython)
|
|
echo "python3-devel"
|
|
;;
|
|
libtraceevent)
|
|
echo "libtraceevent-devel"
|
|
;;
|
|
cxa-demangle)
|
|
echo "libstdc++-devel"
|
|
;;
|
|
libbpf)
|
|
echo "libbpf-devel"
|
|
;;
|
|
babeltrace2-ctf-writer)
|
|
echo "libbabeltrace2-devel"
|
|
;;
|
|
libopenssl)
|
|
echo "openssl-devel"
|
|
;;
|
|
libpfm4)
|
|
echo "libpfm-devel"
|
|
;;
|
|
sdt)
|
|
echo "systemtap-sdt-devel"
|
|
;;
|
|
clang-bpf-co-re)
|
|
echo "clang-devel"
|
|
;;
|
|
llvm|llvm-perf)
|
|
echo "llvm-devel"
|
|
;;
|
|
jvmti|jvmti-cmlr)
|
|
echo "java-latest-openjdk-devel"
|
|
;;
|
|
esac
|
|
# Pure toolchain/libc features (backtrace, eventfd, fortify-source,
|
|
# gettid, glibc, hello, reallocarray, pthread-*, stackprotector-all,
|
|
# timerfd, scandirat, sched_getcpu, setns, file-handle,
|
|
# bionic...) need no external package: their
|
|
# requirements are covered by the base packages below. Features that
|
|
# perf's own build does not check (libcap, libcheck, libcpupower,
|
|
# libtracefs, whose feature tests exist for rtla/bpftool/rv) and the
|
|
# opt-in features, which a default build does not enable: the libbfd
|
|
# disassembler family (libbfd, libbfd-threadsafe, libbfd-liberty,
|
|
# disassembler-*, cplus-demangle), only linked on BUILD_NONDISTRO
|
|
# builds and deprecated in favor of capstone, GTK2, LIBPERL and
|
|
# LIBUNWIND support (ifdef GTK2 / ifdef LIBPERL / LIBUNWIND=1),
|
|
# and CoreSight (ifdef CORESIGHT), are deliberately not mapped.
|
|
# libaio is not mapped either: its
|
|
# test uses the POSIX AIO API (aio.h, aio_*, -lrt), provided by
|
|
# glibc headers (pulled in by the libc headers package) in the
|
|
# base set, not the native libaio.h/io_submit API that
|
|
# libaio-devel provides.
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Check whether the first argument is provided by the enabled repos, or
|
|
# is already installed, returning 0 if so and printing nothing.
|
|
#
|
|
# dnf repoquery exits 0 even when the pattern does not match anything,
|
|
# so availability is judged by the output being non-empty, not by the
|
|
# exit code.
|
|
# ---------------------------------------------------------------------
|
|
pkg_available() {
|
|
local p out
|
|
for p in "$@"; do
|
|
out=$(dnf repoquery --quiet --available "$p" 2>/dev/null)
|
|
[ -n "$out" ] || out=$(dnf repoquery --quiet --installed "$p" 2>/dev/null)
|
|
[ -n "$out" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Return the first of its arguments that pkg_available() accepts.
|
|
# ---------------------------------------------------------------------
|
|
pick_available() {
|
|
local p
|
|
for p in "$@"; do
|
|
if pkg_available "$p"; then
|
|
echo "$p"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Return the RHEL-family package(s) providing the devel requirements of
|
|
# a feature test. This family reuses the Fedora mapping, whose names
|
|
# apply to it as well, except for the features whose Fedora package
|
|
# does not exist there, kept in the case below.
|
|
#
|
|
# Whether the resulting package is actually installable is checked in
|
|
# package_set(), as some of these names live in the CRB or EPEL repos,
|
|
# which may not be enabled: on the RHEL 10 family libbpf-devel and
|
|
# capstone-devel come from CRB, and libbabeltrace2-devel is not
|
|
# packaged at all.
|
|
# ---------------------------------------------------------------------
|
|
rhel_pkg_for() {
|
|
local feat="$1"
|
|
case "$feat" in
|
|
zlib)
|
|
# zlib-ng-compat-devel on the RHEL 10 family, zlib-devel on
|
|
# RHEL 9 and earlier. If neither is on the enabled repos,
|
|
# fall back to the first candidate so that package_set()
|
|
# reports it as missing instead of silently dropping the
|
|
# feature from the end-of-run note.
|
|
pick_available zlib-devel zlib-ng-compat-devel || echo "zlib-devel"
|
|
;;
|
|
jvmti|jvmti-cmlr)
|
|
# No java-latest-openjdk-devel on the RHEL family: the JDK
|
|
# devel package is versioned per release.
|
|
pick_available java-latest-openjdk-devel java-21-openjdk-devel java-17-openjdk-devel java-11-openjdk-devel || echo "java-latest-openjdk-devel"
|
|
;;
|
|
*)
|
|
fedora_pkg_for "$feat"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Return the Debian/Ubuntu package(s) providing the devel requirements
|
|
# of a feature test in tools/build/feature/. This mapping is shared by
|
|
# Debian and Ubuntu, whose package names for these devel packages match,
|
|
# and is validated on Ubuntu 26.04 and Debian 13 (trixie).
|
|
# ---------------------------------------------------------------------
|
|
debian_pkg_for() {
|
|
local feat="$1"
|
|
case "$feat" in
|
|
libelf|libelf-getphdrnum|libelf-gelf_getnote|libelf-getshdrstrndx)
|
|
echo "libelf-dev"
|
|
;;
|
|
libelf-zstd)
|
|
echo "libelf-dev libzstd-dev"
|
|
;;
|
|
libdw)
|
|
echo "libdw-dev"
|
|
;;
|
|
libdebuginfod)
|
|
echo "libdebuginfod-dev"
|
|
;;
|
|
libnuma|numa_num_possible_cpus)
|
|
echo "libnuma-dev"
|
|
;;
|
|
libzstd)
|
|
echo "libzstd-dev"
|
|
;;
|
|
zlib)
|
|
echo "zlib1g-dev"
|
|
;;
|
|
lzma)
|
|
echo "liblzma-dev"
|
|
;;
|
|
libslang)
|
|
echo "libslang2-dev"
|
|
;;
|
|
libcapstone)
|
|
echo "libcapstone-dev"
|
|
;;
|
|
libpython)
|
|
echo "python3-dev"
|
|
;;
|
|
libtraceevent)
|
|
echo "libtraceevent-dev"
|
|
;;
|
|
# The cxa-demangle feature test links against libstdc++ builtin
|
|
# demangling, so on Debian-derived distros it is covered by the
|
|
# g++ base package below, which pulls in libstdc++-*-dev.
|
|
cxa-demangle)
|
|
;;
|
|
libbpf)
|
|
echo "libbpf-dev"
|
|
;;
|
|
babeltrace2-ctf-writer)
|
|
echo "libbabeltrace2-dev"
|
|
;;
|
|
libopenssl)
|
|
echo "libssl-dev"
|
|
;;
|
|
libpfm4)
|
|
echo "libpfm4-dev"
|
|
;;
|
|
sdt)
|
|
echo "systemtap-sdt-dev"
|
|
;;
|
|
# test-clang-bpf-co-re.c invokes the clang binary (not libclang-cpp),
|
|
# so clang suffices; llvm-dev brings llvm-config, needed by the
|
|
# llvm/llvm-perf tests below.
|
|
clang-bpf-co-re)
|
|
echo "clang llvm-dev"
|
|
;;
|
|
llvm|llvm-perf)
|
|
echo "llvm-dev"
|
|
;;
|
|
jvmti|jvmti-cmlr)
|
|
echo "default-jdk"
|
|
;;
|
|
esac
|
|
# Same rationale as in fedora_pkg_for() above for unmapped tests.
|
|
}
|
|
|
|
# Base packages needed by any perf build, regardless of feature tests:
|
|
# compiler, libc headers, flex/bison for the parser, kernel headers
|
|
# for UAPI headers with no in-tree copy, e.g. <linux/capability.h>, and
|
|
# gcc-c++ (dnf) / g++ (apt) is needed by the C++-based feature tests
|
|
# (cxa-demangle, llvm, llvm-perf), compiled with $(CXX), and
|
|
# pulls in libstdc++-devel / libstdc++-*-dev.
|
|
# python3-setuptools is needed to build the python binding (perf's
|
|
# util/setup.py uses it; without it binding is skipped with a warning).
|
|
# rust is not a header-based feature test: test-rust.bin just checks
|
|
# "$(RUSTC) --version" (tools/build/feature/Makefile), so it is mapped
|
|
# here like the other toolchain packages.
|
|
fedora_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers python3-setuptools rust"
|
|
# pkg-config mirrors the pkgconf-pkg-config package that Fedora
|
|
# installs by default, needed by the babeltrace2 feature test and
|
|
# libopenssl's pkg-config checks.
|
|
debian_base_pkgs="gcc g++ make pkg-config flex bison libc6-dev linux-libc-dev python3-setuptools rustc"
|
|
# pkg-config: like Fedora, on pkgconf since Fedora 26 / RHEL 8, with
|
|
# 'pkgconfig' live only as a virtual Provides of the pkgconf-pkg-config
|
|
# subpackage. List it explicitly because, unlike Fedora, a minimal
|
|
# RHEL-family container may not have it preinstalled.
|
|
rhel_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers pkgconf-pkg-config python3-setuptools rust"
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Distro detection
|
|
# ---------------------------------------------------------------------
|
|
detect_distro() {
|
|
if [ -n "$DISTRO" ]; then
|
|
echo "$DISTRO"
|
|
return
|
|
fi
|
|
local id
|
|
id=$( . /etc/os-release 2>/dev/null && echo "${ID:-}" )
|
|
case "$id" in
|
|
fedora) echo "fedora" ;;
|
|
rhel|centos|rocky|almalinux|ol)
|
|
# All share the Fedora package names (with the exceptions
|
|
# handled by rhel_pkg_for()) and dnf.
|
|
echo "rhel" ;;
|
|
ubuntu) echo "ubuntu" ;;
|
|
debian) echo "debian" ;;
|
|
*) echo "" ;;
|
|
esac
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Feature test enumeration: mirror of the tests checked during a build,
|
|
# from the actual test-*.c / test-*.cpp sources in tools/build/feature/.
|
|
# ---------------------------------------------------------------------
|
|
feature_tests() {
|
|
local srcdir="$1"
|
|
local f
|
|
for f in "$srcdir"/tools/build/feature/test-*.c "$srcdir"/tools/build/feature/test-*.cpp; do
|
|
[ -e "$f" ] || continue
|
|
basename "$f" | sed -e 's/^test-//' -e 's/\.c$//' -e 's/\.cpp$//'
|
|
done
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Assemble the unique package list. Since the full feature set is mapped
|
|
# unconditionally, this installs the complete devel environment; installing
|
|
# an already-present package is a no-op for both dnf and apt-get, making
|
|
# this idempotent. On the RHEL family, packages not available on the
|
|
# enabled repos are skipped and echoed on stderr, reported at the end of
|
|
# the run by the caller (package_set() runs in a subshell, so a variable
|
|
# would not survive it).
|
|
# ---------------------------------------------------------------------
|
|
package_set() {
|
|
local distro="$1" srcdir="$2"
|
|
local feat pkg pkgs base_pkgs missing_pkgs=""
|
|
case "$distro" in
|
|
fedora) pkgs="$fedora_base_pkgs" ;;
|
|
rhel) pkgs="$rhel_base_pkgs" ;;
|
|
ubuntu|debian) pkgs="$debian_base_pkgs" ;;
|
|
esac
|
|
|
|
# The base set must be checked against the enabled repos as well:
|
|
# e.g. 'rust' is only shipped as the rust-toolset AppStream module
|
|
# on RHEL 8 and 9, where dnf would abort the whole transaction
|
|
# with "No match for argument: rust" instead of skipping it, so
|
|
# unavailable base packages are skipped and noted like the mapped
|
|
# ones below.
|
|
if [ "$distro" = "rhel" ]; then
|
|
base_pkgs="$pkgs"
|
|
pkgs=""
|
|
for pkg in $base_pkgs; do
|
|
if pkg_available "$pkg"; then
|
|
pkgs="$pkgs $pkg"
|
|
else
|
|
missing_pkgs="$missing_pkgs $pkg"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
for feat in $(feature_tests "$srcdir"); do
|
|
case "$distro" in
|
|
fedora) pkg=$(fedora_pkg_for "$feat") ;;
|
|
rhel) pkg=$(rhel_pkg_for "$feat") ;;
|
|
*) pkg=$(debian_pkg_for "$feat") ;;
|
|
esac
|
|
# An empty result means the feature test has no external devel
|
|
# dependency (see the unmapped list in fedora_pkg_for()), so
|
|
# there is nothing to install and nothing to report as missing:
|
|
# packages that are genuinely unavailable on the RHEL family
|
|
# surface through rhel_pkg_for() falling back to its first
|
|
# candidate, so that the pkg_available() check below catches
|
|
# them and adds them to missing_pkgs.
|
|
[ -n "$pkg" ] || continue
|
|
for pkg in $pkg; do
|
|
if [ "$distro" = "rhel" ] && ! pkg_available "$pkg"; then
|
|
missing_pkgs="$missing_pkgs $pkg"
|
|
continue
|
|
fi
|
|
case " $pkgs " in
|
|
*" $pkg "*) ;;
|
|
*) pkgs="$pkgs $pkg" ;;
|
|
esac
|
|
done
|
|
done
|
|
[ -n "$missing_pkgs" ] && echo "$missing_pkgs" >&2
|
|
echo "$pkgs"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Report the RHEL-family packages that were skipped because the enabled
|
|
# repos do not provide them.
|
|
# ---------------------------------------------------------------------
|
|
note_missing() {
|
|
[ -n "$1" ] || return 0
|
|
echo "Note: these packages are not available on the enabled repos" >&2
|
|
echo "and were not installed, so the features they enable will stay" >&2
|
|
echo "off in a perf build:" >&2
|
|
echo "$1" | tr ' ' '\n' | grep -v '^$' | sort -u | sed 's/^/ /' >&2
|
|
echo >&2
|
|
}
|
|
|
|
# ---------------------------------------------------------------------
|
|
# The install command proper for each supported package manager, plus
|
|
# the command massaged for --dry-run.
|
|
# ---------------------------------------------------------------------
|
|
install_cmd() {
|
|
local distro="$1"; shift
|
|
case "$distro" in
|
|
fedora|rhel)
|
|
echo "dnf install -y $*"
|
|
;;
|
|
ubuntu|debian)
|
|
# a fresh container has no package index, so update first; run
|
|
# with a noninteractive debconf frontend: default-jdk, used by
|
|
# the jvmti feature tests, pulls in tzdata, which prompts for
|
|
# the timezone on a terminal and would block the install. The
|
|
# env var prefix works with the 'sh -c' invocation below, and
|
|
# shows up in --dry-run.
|
|
echo "DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y $*"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main() {
|
|
local action="install"
|
|
# Package accumulation happens in package_set(), which, together
|
|
# with the *_pkg_for() helpers, declares the per-feature 'pkg'
|
|
# locals; main() holds no per-feature package state, just the
|
|
# distro-wide list assembled by package_set().
|
|
local srcdir distro pkgs cmd missing_file missing_pkgs
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--list) action="list"; shift ;;
|
|
--dry-run) action="dry-run"; shift ;;
|
|
--distro)
|
|
[ $# -ge 2 ] || {
|
|
echo "error: --distro requires an argument (fedora, rhel, ubuntu, debian)" >&2
|
|
exit 1
|
|
}
|
|
DISTRO="$2"; shift 2 ;;
|
|
-h|--help) help ;;
|
|
*) echo "error: unknown argument: $1" >&2; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
srcdir=$(cd "$(dirname "$0")/../../.." && pwd)
|
|
distro=$(detect_distro)
|
|
case "$distro" in
|
|
fedora|rhel|ubuntu|debian) ;;
|
|
*)
|
|
echo "error: unsupported distro (got '$distro'); the package mapping is not validated on other distros." >&2
|
|
echo "Supported and validated: Fedora 44 (toolbx container), Ubuntu 26.04 and Debian 13 (distrobox containers), and CentOS Stream 10 (distrobox container)." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# The RHEL family mapping probes the enabled repos with dnf
|
|
# repoquery and installs with dnf, so reject the yum-only members of
|
|
# the family (RHEL 7 and earlier, e.g. Oracle Linux 7) with a clear
|
|
# error instead of silently judging every package as unavailable.
|
|
if [ "$distro" = "rhel" ] && ! command -v dnf >/dev/null 2>&1; then
|
|
echo "error: dnf not found, the RHEL family package mapping requires dnf (RHEL 8 and later)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
missing_file=$(mktemp) || {
|
|
echo "error: cannot create a temporary file (mktemp failed)" >&2
|
|
exit 1
|
|
}
|
|
# package_set() runs in a subshell, doing dnf repoquery loops that
|
|
# may be interrupted: a Ctrl-C during those loops hits these traps,
|
|
# turning SIGINT/SIGTERM into an exit that triggers the EXIT trap,
|
|
# removing the temp file, so the script terminates instead of
|
|
# resuming after the interrupted command, leaving no file behind.
|
|
trap 'rm -f "$missing_file"' EXIT
|
|
trap 'exit 1' INT TERM
|
|
pkgs=$(package_set "$distro" "$srcdir" 2>"$missing_file")
|
|
missing_pkgs=$(cat "$missing_file")
|
|
rm -f "$missing_file"
|
|
trap - EXIT INT TERM
|
|
|
|
case "$action" in
|
|
list)
|
|
echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort
|
|
note_missing "$missing_pkgs"
|
|
exit 0
|
|
;;
|
|
dry-run)
|
|
install_cmd "$distro" $pkgs
|
|
note_missing "$missing_pkgs"
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
echo "The following packages will be installed to enable perf features:"
|
|
echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort | sed 's/^/ /'
|
|
echo
|
|
cmd=$(install_cmd "$distro" $pkgs)
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
sh -c "$cmd"
|
|
else
|
|
sudo sh -c "$cmd"
|
|
fi || {
|
|
echo "error: the install command failed, see the output above" >&2
|
|
exit 1
|
|
}
|
|
note_missing "$missing_pkgs"
|
|
}
|
|
|
|
main "$@"
|