From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4AB85443AA3; Mon, 10 Aug 2026 21:46:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786398404; cv=none; b=WHnDlq2N7zlSnrmUnI5F0noYOdJdbIua4PNnvHz/PKuJZzloEJz02PYuxnKsGAEN9bJXV5vHmAptf8lfRtByHpubir+RHh3CCOfYaby434gyKeSjtvZNSUO9N+qojVAhJjdlXgJzyDipg+vqs+zwmTJfn/ai1UqDxfcS7UXUl1w= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786398404; c=relaxed/simple; bh=nWnDnM3pWSIewjt3RoM7MClp+Lcs/f3JGJ5i3Wqhdxs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tVivNblgVYcvv9JDUs9jh1+ziSsoXjJgf9koGD4khkzgVTSL0NC4HVkrNfNbaUt6+Qf2eAm1/B5P9WAy7i4ujLNR+Lo0QAdmxMvB7qbsGFNxuUkZ2K5rs6H/TACd7y07X5vYS330cGCpQce64qmTSaFgy6NgiwiGdF54Z1d8n4o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nWEgyuk+; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nWEgyuk+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D41E1F000E9; Mon, 10 Aug 2026 21:46:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786398403; bh=sFPx+INbflFZHlIpaNsJlC5frWHNUm61KvSA/x2ZKwg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=nWEgyuk+GinsimZevbFyjY92vhHk0QzEIV3/Blxiwd1HIEkkjoUvETaFKyFwaK3Kd AsW0KOH6LTvxbcV80cUUUexm+Me4uLEA/+xWY1Q4gmBGphDA7W+wBfMWpAK+MNx6Tv 6I22M5mGwLEFxqkorM7U5DeJh0hRUZZzc23TRxFQSDmyX4s7aa9IVpZJBc0AgItJ2X IqGS5/DltJMNNPHC33CetTnNW+emlUvNyWqxnowLvhF1ZKy1Eu24YSoSfZLVhLpHeE tzl99sFkRO+EbbwrSvyMNnntoC4E61Wc0jfviKZMAXW2F2Zi5SQfWLliOIImhxM6PS qgj2xY0mb1qwA== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH 2/7] perf build: Add install-build-deps framework to install devel packages Date: Mon, 10 Aug 2026 18:46:19 -0300 Message-ID: <20260810214624.21156-3-acme@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260810214624.21156-1-acme@kernel.org> References: <20260810214624.21156-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Arnaldo Carvalho de Melo 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 --- 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 <, 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