Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604#!/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 <<EOFUsage: $(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 providingit, 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 onFedora 44, Ubuntu (apt-get), validated in a distrobox container onUbuntu 26.04, Debian (apt-get), reusing the Ubuntu mapping, validatedin a distrobox container on Debian 13 (trixie), and the RHEL family(dnf, RHEL 8 and later), validated on CentOS Stream 10 in a distroboxcontainer. On the RHEL family, packages not available on the enabledrepos are skipped and listed at the end; some there, e.g.libbpf-devel and capstone-devel, come from the CRB repo on RHEL andCentOS Stream 10 ('dnf config-manager --set-enabled crb') and fromEPEL 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 "$@"