summaryrefslogtreecommitdiff
path: root/tools/perf/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/scripts')
-rwxr-xr-xtools/perf/scripts/install-build-deps.sh220
1 files changed, 197 insertions, 23 deletions
diff --git a/tools/perf/scripts/install-build-deps.sh b/tools/perf/scripts/install-build-deps.sh
index aaaf315516f0..d003e7fab2be 100755
--- a/tools/perf/scripts/install-build-deps.sh
+++ b/tools/perf/scripts/install-build-deps.sh
@@ -37,11 +37,33 @@
# distrobox create --image debian:trixie
# distrobox enter debian-trixie
#
-# Running inside a container keeps the host system unmodified.
+# - 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:
#
-# RHEL support, whose package mapping is largely similar to Fedora's,
-# is the next planned distro, to be enabled once that mapping is
-# validated there.
+# - 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]
#
@@ -49,7 +71,8 @@
# --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, ubuntu, debian (default: auto-detect)
+# --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.
@@ -71,13 +94,19 @@ 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, ubuntu, debian
+ --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, and Debian (apt-get), reusing the Ubuntu mapping,
-validated in a distrobox container on Debian 13 (trixie).
+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
}
@@ -181,6 +210,72 @@ fedora_pkg_for() {
}
# ---------------------------------------------------------------------
+# 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,
@@ -277,6 +372,11 @@ fedora_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers python3
# 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
@@ -290,11 +390,12 @@ detect_distro() {
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" ;;
- # RHEL and its derivatives share most Fedora package names, but the
- # mapping is only validated on Fedora, so don't auto-detect them.
- rhel|centos|rocky|alma|ol) echo "" ;;
*) echo "" ;;
esac
}
@@ -316,41 +417,88 @@ feature_tests() {
# 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.
+# 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
+ 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
- if [ "$distro" = "fedora" ]; then
- pkg=$(fedora_pkg_for "$feat")
- else
- pkg=$(debian_pkg_for "$feat")
- fi
+ 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)
+ fedora|rhel)
echo "dnf install -y $*"
;;
ubuntu|debian)
@@ -371,7 +519,7 @@ main() {
# 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
+ local srcdir distro pkgs cmd missing_file missing_pkgs
while [ $# -gt 0 ]; do
case "$1" in
@@ -391,23 +539,48 @@ main() {
srcdir=$(cd "$(dirname "$0")/../../.." && pwd)
distro=$(detect_distro)
case "$distro" in
- fedora|ubuntu|debian) ;;
+ 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)." >&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
- pkgs=$(package_set "$distro" "$srcdir")
+ # 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
@@ -424,6 +597,7 @@ main() {
echo "error: the install command failed, see the output above" >&2
exit 1
}
+ note_missing "$missing_pkgs"
}
main "$@"