From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
James Clark <james.clark@linaro.org>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Clark Williams <williams@redhat.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 2/7] perf build: Add install-build-deps framework to install devel packages
Date: Mon, 10 Aug 2026 16:35:01 -0300 [thread overview]
Message-ID: <20260810193506.18949-3-acme@kernel.org> (raw)
In-Reply-To: <20260810193506.18949-1-acme@kernel.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Installing the development packages needed to build perf is
error-prone on a fresh distro install: the packages are scattered
across the feature tests in tools/build/feature/, each checking for a
specific header/library, and the build only tells you what's missing
after failing a check.
This series adds a 'make -C tools/perf install-build-deps' target to
install them in one go, deriving the package list from the feature tests
themselves.
This commit adds the framework, on top of the parse-time compiler
probe guard from the previous commit:
- the install-build-deps target in tools/perf/Makefile.perf, exempted
from the config/feature detection pass, since it must run in a fresh
container, before gcc or pkg-config exist, to install them;
- the install-build-deps.sh script, with --list, --dry-run and
--distro options, distro detection (Fedora and Ubuntu), dnf and
apt-get drivers, root/passwordless-sudo handling, and the base
packages common to any build: compiler, C++ compiler, make, flex,
bison, libc and kernel headers, python3-setuptools (needed by the
python binding) and rust (checked by the rust feature test);
- the parse-time probes for optional tools, like pkg-config, use
'command -v' with stderr discarded, so a fresh container without
them gets no 'which: no pkg-config in (...)' spew from make;
- the script does not rely on 'set -e': its error paths are explicit,
since the make target runs it via $(SHELL), where a shebang option
would be ignored anyway, so direct and make-driven runs behave the
same.
The per-feature mappings, from each feature test to the devel package
providing its headers on a given distro, are added by the follow-up
patches, one per distro, together with the validation of each mapping
in a fresh container: until then the target installs just the base
toolchain.
Assisted-by: opencode:deepseek-v4-flash-free
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/Makefile.perf | 20 ++-
tools/perf/scripts/install-build-deps.sh | 173 +++++++++++++++++++++++
2 files changed, 190 insertions(+), 3 deletions(-)
create mode 100755 tools/perf/scripts/install-build-deps.sh
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index acc6309a84a1eeb1..49a58d714e42dded 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -177,7 +177,7 @@ LD += $(EXTRA_LDFLAGS)
# Some distros provide the command $(CROSS_COMPILE)pkg-config for
# searching packges installed with Multiarch. Use it for cross
# compilation if it is existed.
-ifneq (, $(shell which $(CROSS_COMPILE)pkg-config))
+ifneq (, $(shell command -v $(CROSS_COMPILE)pkg-config 2>/dev/null))
PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
else
PKG_CONFIG ?= pkg-config
@@ -214,7 +214,12 @@ AWK = awk
# non-config cases
config := 1
-NON_CONFIG_TARGETS := clean python-clean TAGS tags cscope help
+# install-build-deps runs the install-build-deps.sh script, which
+# derives the package list from the feature test sources in
+# tools/build/feature/, so it needs neither the fixdep build nor a
+# config/feature detection pass: in a fresh container without gcc or
+# pkg-config those would fail before the script could install them.
+NON_CONFIG_TARGETS := clean python-clean TAGS tags cscope help install-build-deps
ifdef MAKECMDGOALS
ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
@@ -748,6 +753,7 @@ help:
@echo ' HINT: use "prefix" or "DESTDIR" to install to a particular'
@echo ' path like "make prefix=/usr/local install install-doc"'
@echo ' install - install compiled binaries'
+ @echo ' install-build-deps - install the development packages needed to build'
@echo ' install-doc - install *all* documentation'
@echo ' install-man - install manpage documentation'
@echo ' install-html - install html documentation'
@@ -892,6 +898,14 @@ install-bin: install-tools install-tests
install: install-bin try-install-man
+# Install the development packages needed to build perf, derived from the
+# feature tests in tools/build/feature/. This first installs just the
+# base toolchain; per-distro package mappings are added by the follow-up
+# commits. INSTALL_BUILD_DEPS_ARGS, when set, is passed to the script, so
+# extra options like --list, --dry-run or --distro can be given from make.
+install-build-deps:
+ $(Q)$(SHELL) $(srctree)/tools/perf/scripts/install-build-deps.sh $(INSTALL_BUILD_DEPS_ARGS)
+
install-python_ext:
$(PYTHON_WORD) util/setup.py $(python_setup_quiet) install --root='/$(DESTDIR_SQ)'
@@ -960,7 +974,7 @@ endif
FORCE:
-.PHONY: all install clean config-clean strip install-gtk
+.PHONY: all install install-build-deps clean config-clean strip install-gtk
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
.PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope FORCE prepare bpf-skel-prepare
.PHONY: python_perf_target
diff --git a/tools/perf/scripts/install-build-deps.sh b/tools/perf/scripts/install-build-deps.sh
new file mode 100755
index 0000000000000000..6b9a1142f32acf03
--- /dev/null
+++ b/tools/perf/scripts/install-build-deps.sh
@@ -0,0 +1,173 @@
+#!/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.
+#
+# This initial version installs the base toolchain needed by any build;
+# the per-feature package mapping is added, per supported distro, by the
+# follow-up patches in this series, which also validate each mapping in a
+# fresh container, so the host system is not modified.
+#
+# 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, ubuntu (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.
+
+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
+ -h, --help print this help message
+EOF
+ exit 0
+}
+
+# ---------------------------------------------------------------------
+# Distro detection. The install command that follows only differs in
+# the package manager, which here is keyed off the distro ID; the
+# per-feature package mapping is added per distro by the follow-up
+# patches.
+# ---------------------------------------------------------------------
+detect_distro() {
+ if [ -n "$DISTRO" ]; then
+ echo "$DISTRO"
+ return
+ fi
+ local id
+ id=$( . /etc/os-release && echo "${ID:-}" )
+ case "$id" in
+ fedora) echo "fedora" ;;
+ ubuntu) echo "ubuntu" ;;
+ # 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
+}
+
+# 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) for 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"
+debian_base_pkgs="gcc g++ make flex bison libc6-dev linux-libc-dev python3-setuptools rustc"
+
+# ---------------------------------------------------------------------
+# Assemble the unique package list. While the per-feature mapping is
+# being added per distro, only the base toolchain above is installed.
+# ---------------------------------------------------------------------
+package_set() {
+ local distro="$1" srcdir="$2"
+ case "$distro" in
+ fedora) echo "$fedora_base_pkgs" ;;
+ ubuntu) echo "$debian_base_pkgs" ;;
+ esac
+}
+
+# ---------------------------------------------------------------------
+# 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)
+ echo "dnf install -y $*"
+ ;;
+ ubuntu)
+ # a fresh container has no package index, so update first.
+ echo "apt-get update && apt-get install -y $*"
+ ;;
+ esac
+}
+
+main() {
+ local action="install"
+ local srcdir distro pkgs pkg cmd
+
+ 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|ubuntu) ;;
+ *)
+ echo "error: unsupported distro (got '$distro'); the package mapping is not validated on other distros." >&2
+ exit 1
+ ;;
+ esac
+
+ pkgs=$(package_set "$distro" "$srcdir")
+
+ case "$action" in
+ list)
+ echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort
+ exit 0
+ ;;
+ dry-run)
+ install_cmd "$distro" $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
+ }
+}
+
+main "$@"
\ No newline at end of file
--
2.55.0
next prev parent reply other threads:[~2026-08-10 19:35 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 19:34 [PATCHES v4 0/7] perf build: Add target to install devel packages needed to build perf Arnaldo Carvalho de Melo
2026-08-10 19:35 ` [PATCH 1/7] tools build: Only probe the compiler at parse time when it is installed Arnaldo Carvalho de Melo
2026-08-10 19:35 ` Arnaldo Carvalho de Melo [this message]
2026-08-10 19:35 ` [PATCH 3/7] perf build: install-build-deps: add Fedora devel package mapping Arnaldo Carvalho de Melo
2026-08-10 19:35 ` [PATCH 4/7] perf build: install-build-deps: add Ubuntu " Arnaldo Carvalho de Melo
2026-08-10 19:35 ` [PATCH 5/7] perf build: install-build-deps: add Debian " Arnaldo Carvalho de Melo
2026-08-10 19:35 ` [PATCH 6/7] perf build: Remove leftover feature tests for removed cxx and clang support Arnaldo Carvalho de Melo
2026-08-10 19:35 ` [PATCH 7/7] perf build: install-build-deps: add RHEL family devel package mapping Arnaldo Carvalho de Melo
-- strict thread matches above, loose matches on Subject: below --
2026-08-10 18:15 [PATCHES v3 0/7] perf build: Add target to install devel packages needed to build perf Arnaldo Carvalho de Melo
2026-08-10 18:15 ` [PATCH 2/7] perf build: Add install-build-deps framework to install devel packages Arnaldo Carvalho de Melo
2026-08-10 15:44 [PATCHES v2 0/7] perf build: Add target to install devel packages needed to build perf Arnaldo Carvalho de Melo
2026-08-10 15:44 ` [PATCH 2/7] perf build: Add install-build-deps framework to install devel packages Arnaldo Carvalho de Melo
2026-08-10 0:51 [PATCHES v1 0/7] perf build: Add target to install devel packages needed to build perf Arnaldo Carvalho de Melo
2026-08-10 0:51 ` [PATCH 2/7] perf build: Add install-build-deps framework to install devel packages Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260810193506.18949-3-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=tglx@linutronix.de \
--cc=williams@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox