mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes
@ 2026-10-01  2:34 Ian Rogers
  2026-10-01  2:34 ` [PATCH 1/4] perf test: Update attr.py to use argparse Ian Rogers
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  2:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	Leo Yan, linux-perf-users, linux-kernel

This series includes a small Python test cleanup alongside build system
improvements for linter parallelism and clean/install target
dependencies:

1. Update tools/perf/tests/shell/lib/attr.py to use argparse instead of
   the deprecated optparse module, avoiding a pylint deprecated-module
   warning.

2. Building on Leo Yan's recent change to run pylint checks on
   standalone scripts and tests in parallel with linking perf, move the
   remaining shellcheck, mypy, and pylint rules (in tools/perf/Build,
   tools/perf/tests/Build, tools/perf/util/Build, and
   tools/perf/pmu-events/Build) into top-level phony targets in
   Makefile.perf so they no longer serialize archive creation, jevents
   generation, or final linking, nor wait on $(LANG_BINDINGS).

3. Clear GTK4 via 'override GTK4 :=' in Makefile.config when the gtk4
   feature check fails instead of setting the unused 'NO_GTK4 := 1'
   variable left over from commit 4751bddd3f98 ("perf tools: Make GTK2
   support opt-in").

4. Fix missing dependencies and target ordering for clean and install
   targets across Makefile, Makefile.perf, and
   Documentation/build-docdep.perl.

Ian Rogers (4):
  perf test: Update attr.py to use argparse
  perf build: Run shellcheck, mypy, and remaining pylint checks in
    parallel
  perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is
    missing
  perf build: Fix clean and install target dependencies

 tools/perf/Build                           |  8 ++-
 tools/perf/Documentation/build-docdep.perl |  2 +-
 tools/perf/Makefile                        |  9 ++-
 tools/perf/Makefile.config                 |  2 +-
 tools/perf/Makefile.perf                   | 75 ++++++++++++++++++----
 tools/perf/pmu-events/Build                | 66 ++++++++++---------
 tools/perf/tests/Build                     |  8 ++-
 tools/perf/tests/shell/lib/attr.py         | 37 ++++-------
 tools/perf/util/Build                      |  8 ++-
 9 files changed, 138 insertions(+), 77 deletions(-)

-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] perf test: Update attr.py to use argparse
  2026-10-01  2:34 [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
@ 2026-10-01  2:34 ` Ian Rogers
  2026-10-01  2:34 ` [PATCH 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel Ian Rogers
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  2:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	Leo Yan, linux-perf-users, linux-kernel

optparse is deprecated since Python 3.2 and triggers a pylint
deprecated-module warning on newer versions of pylint. Replace
optparse.OptionParser in tools/perf/tests/shell/lib/attr.py with
argparse.ArgumentParser.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/tests/shell/lib/attr.py | 37 +++++++++++-------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/lib/attr.py
index 7f3d5b64b00d..68f06df9565a 100644
--- a/tools/perf/tests/shell/lib/attr.py
+++ b/tools/perf/tests/shell/lib/attr.py
@@ -4,7 +4,7 @@ import configparser
 import os
 import sys
 import glob
-import optparse
+import argparse
 import platform
 import tempfile
 import logging
@@ -426,29 +426,20 @@ def setup_log(verbose):
     ch.setFormatter(formatter)
     log.addHandler(ch)
 
-USAGE = '''%s [OPTIONS]
-  -d dir  # tests dir
-  -p path # perf binary
-  -t test # single test
-  -v      # verbose level
-''' % sys.argv[0]
-
 def main():
-    parser = optparse.OptionParser(usage=USAGE)
-
-    parser.add_option("-t", "--test",
-                      action="store", type="string", dest="test")
-    parser.add_option("-d", "--test-dir",
-                      action="store", type="string", dest="test_dir")
-    parser.add_option("-p", "--perf",
-                      action="store", type="string", dest="perf")
-    parser.add_option("-v", "--verbose",
-                      default=0, action="count", dest="verbose")
-
-    options, args = parser.parse_args()
-    if args:
-        parser.error('FAILED wrong arguments %s' %  ' '.join(args))
-        return -1
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument("-t", "--test",
+                        action="store", dest="test", help="single test")
+    parser.add_argument("-d", "--test-dir",
+                        action="store", dest="test_dir", help="tests dir")
+    parser.add_argument("-p", "--perf",
+                        action="store", dest="perf", help="perf binary")
+    parser.add_argument("-v", "--verbose",
+                        default=0, action="count", dest="verbose",
+                        help="verbose level")
+
+    options = parser.parse_args()
 
     setup_log(options.verbose)
 
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel
  2026-10-01  2:34 [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
  2026-10-01  2:34 ` [PATCH 1/4] perf test: Update attr.py to use argparse Ian Rogers
@ 2026-10-01  2:34 ` Ian Rogers
  2026-10-01  2:34 ` [PATCH 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing Ian Rogers
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  2:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	Leo Yan, linux-perf-users, linux-kernel

Following the approach used for pylint on standalone scripts and tests,
move the shellcheck and mypy checks in tools/perf/Build and
tools/perf/tests/Build, as well as the mypy and pylint checks in
tools/perf/util/Build and tools/perf/pmu-events/Build, into dedicated
phony targets invoked as top-level sub-makes from Makefile.perf.

Also add 'perf' to pylint's --ignored-modules (leaving perf module
type-checking to mypy via perf.pyi), since astroid's ImportlibFinder
only resolves .pyi stubs for package directories (__init__.pyi) rather
than single-file stubs like perf.pyi and does not introspect C
extensions by default. This removes the need for pylint to wait on
building $(LANG_BINDINGS).

This avoids blocking jevents code generation, archive creation
(libperf-util.a, libperf-test.a, libpmu-events.a), and final linking of
the perf binary and Python extension on linter execution.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Build            |  8 +++--
 tools/perf/Makefile.perf    | 56 ++++++++++++++++++++++++++-----
 tools/perf/pmu-events/Build | 66 +++++++++++++++++++------------------
 tools/perf/tests/Build      |  8 +++--
 tools/perf/util/Build       |  8 +++--
 5 files changed, 99 insertions(+), 47 deletions(-)

diff --git a/tools/perf/Build b/tools/perf/Build
index 09fd88f5aca5..dcba5ba55206 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -76,7 +76,9 @@ $(OUTPUT)%.shellcheck_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(SHELLCHECK) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-y += $(SHELL_TEST_LOGS)
+.PHONY: shellcheck
+shellcheck: $(addprefix $(OUTPUT),$(SHELL_TEST_LOGS))
+	@:
 
 ifdef MYPY
   PY_TESTS := $(shell find python -type f -name '*.py')
@@ -89,7 +91,9 @@ $(OUTPUT)%.mypy_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-y += $(MYPY_TEST_LOGS)
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT),$(MYPY_TEST_LOGS))
+	@:
 
 ifdef PYLINT
   PY_TESTS := $(shell find python -type f -name '*.py')
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7ceefc1da774..836225b08649 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -283,8 +283,12 @@ ifneq ($(force_fixdep),1)
 endif
 
 # Runs pylint on perf python files.
-# Require pylint >= 2.16.0 (which introduced W0718 broad-exception-caught and
-# astroid .pyi stub support for perf.pyi).
+# Require pylint >= 2.16.0 (which introduced W0718 broad-exception-caught).
+# Note: astroid's ImportlibFinder only resolves .pyi stubs for package
+# directories (__init__.pyi), not single-file stubs like perf.pyi, and does not
+# introspect C extensions by default. Pass 'perf' in --ignored-modules (leaving
+# perf module type-checking to mypy via perf.pyi) so pylint does not depend on
+# building the perf Python C extension first.
 # Disabled warnings:
 #   W0123 (eval-used): Use of eval()
 #   W0311 (bad-indentation): Non-4-space indentation
@@ -310,9 +314,9 @@ ifneq ($(force_fixdep),1)
       $(warning Warning: pylint version is older than 2.16.0, skipping pylint checks.)
       override PYLINT :=
     else
-      override PYLINT := PYTHONPATH=$(abspath $(OUTPUT)python):$(srctree)/tools/perf/python:$(srctree)/tools/perf/pmu-events \
+      override PYLINT := PYTHONPATH=$(srctree)/tools/perf/python:$(srctree)/tools/perf/pmu-events \
         $(PYLINT) --disable=all --enable=E,W --disable=W0123,W0311,W0511,W0603,W0622,W0718 \
-        --ignored-modules=textual,setproctitle
+        --ignored-modules=perf,textual,setproctitle
     endif
   endif
 endif
@@ -634,18 +638,52 @@ $(SCRIPTS) : $(OUTPUT)% : %.sh
 $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
 	$(Q)$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
 
-ifdef PYLINT
-# Run Python checks after the extension is ready, independently of C builds.
-all: pylint-perf pylint-tests
-.PHONY: pylint-perf pylint-tests
+ifdef SHELLCHECK
+# Run shellcheck independently of C builds.
+all: shellcheck-perf shellcheck-tests
+.PHONY: shellcheck-perf shellcheck-tests
+
+shellcheck-perf:
+	$(Q)$(MAKE) $(build)=perf shellcheck
+
+shellcheck-tests:
+	$(Q)$(MAKE) $(build)=perf-test dir=tests shellcheck
+endif
+
+ifdef MYPY
+# Run mypy independently of C builds.
+all: mypy-perf mypy-tests mypy-util mypy-pmu-events
+.PHONY: mypy-perf mypy-tests mypy-util mypy-pmu-events
+
+mypy-perf:
+	$(Q)$(MAKE) $(build)=perf mypy
+
+mypy-tests:
+	$(Q)$(MAKE) $(build)=perf-test dir=tests mypy
 
-pylint-perf pylint-tests: | $(LANG_BINDINGS)
+mypy-util:
+	$(Q)$(MAKE) $(build)=perf-util dir=util mypy
+
+mypy-pmu-events:
+	$(Q)$(MAKE) $(build)=pmu-events dir=pmu-events mypy
+endif
+
+ifdef PYLINT
+# Run pylint independently of C builds.
+all: pylint-perf pylint-tests pylint-util pylint-pmu-events
+.PHONY: pylint-perf pylint-tests pylint-util pylint-pmu-events
 
 pylint-perf:
 	$(Q)$(MAKE) $(build)=perf pylint
 
 pylint-tests:
 	$(Q)$(MAKE) $(build)=perf-test dir=tests pylint
+
+pylint-util:
+	$(Q)$(MAKE) $(build)=perf-util dir=util pylint
+
+pylint-pmu-events:
+	$(Q)$(MAKE) $(build)=pmu-events dir=pmu-events pylint
 endif
 
 # These can record PERF_VERSION
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index 01f5a00f2125..5147139bbb6f 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -183,38 +183,6 @@ $(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C)
 # Dependencies for jevents.py
 JEVENTS_DEPS := $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY) $(EMPTY_PMU_EVENTS_TEST_LOG) $(METRIC_TEST_LOG)
 
-# Rules to run mypy if enabled.
-ifdef MYPY
-define MYPY_RULE
-$(2): $(1)
-	$$(Q)$$(call echo-cmd,test)$$(MYPY) $(1) > $(2) || (cat $(2) && rm $(2) && false)
-endef
-$(foreach src,$(wildcard pmu-events/*.py), \
-    $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(src))) \
-    $(eval $(call MYPY_RULE,$(src),$(dest))) \
-)
-
-MYPY_INPUTS := $(wildcard pmu-events/*.py)
-MYPY_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(MYPY_INPUTS))
-JEVENTS_DEPS += $(MYPY_OUTPUTS)
-endif
-
-# Rules to run pylint if enabled.
-ifdef PYLINT
-define PYLINT_RULE
-$(2): $(1)
-	$$(Q)$$(call echo-cmd,test)$$(PYLINT) $(1) > $(2) || (cat $(2) && rm $(2) && false)
-endef
-$(foreach src,$(wildcard pmu-events/*.py), \
-    $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(src))) \
-    $(eval $(call PYLINT_RULE,$(src),$(dest))) \
-)
-
-PYLINT_INPUTS := $(wildcard pmu-events/*.py)
-PYLINT_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(PYLINT_INPUTS))
-JEVENTS_DEPS += $(PYLINT_OUTPUTS)
-endif
-
 # If there are orphaned files remove them.
 ifneq ($(strip $(ORPHAN_FILES)),)
 .PHONY: prune_orphans
@@ -243,3 +211,37 @@ $(PMU_EVENTS_STRING_C): $(PMU_EVENTS_C)
 	@:
 
 endif # ifeq ($(NO_JEVENTS),1)
+
+ifneq ($(NO_JEVENTS),1)
+  PY_TESTS := $(wildcard pmu-events/*.py)
+else
+  PY_TESTS :=
+endif
+
+ifdef MYPY
+  MYPY_TEST_LOGS := $(PY_TESTS:%=%.mypy_log)
+else
+  MYPY_TEST_LOGS :=
+endif
+
+$(OUTPUT)%.mypy_log: %
+	$(call rule_mkdir)
+	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
+
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT),$(MYPY_TEST_LOGS))
+	@:
+
+ifdef PYLINT
+  PYLINT_TEST_LOGS := $(PY_TESTS:%=%.pylint_log)
+else
+  PYLINT_TEST_LOGS :=
+endif
+
+$(OUTPUT)%.pylint_log: %
+	$(call rule_mkdir)
+	$(Q)$(call echo-cmd,test)$(PYLINT) "$<" > $@ || (cat $@ && rm $@ && false)
+
+.PHONY: pylint
+pylint: $(addprefix $(OUTPUT),$(PYLINT_TEST_LOGS))
+	@:
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 05c545aac732..395f2866094a 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -93,7 +93,9 @@ $(OUTPUT)%.shellcheck_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(SHELLCHECK) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-test-y += $(SHELL_TEST_LOGS)
+.PHONY: shellcheck
+shellcheck: $(addprefix $(OUTPUT)tests/,$(SHELL_TEST_LOGS))
+	@:
 
 ifdef MYPY
   PY_TESTS := $(shell find tests/shell -type f -name '*.py')
@@ -106,7 +108,9 @@ $(OUTPUT)%.mypy_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-test-y += $(MYPY_TEST_LOGS)
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT)tests/,$(MYPY_TEST_LOGS))
+	@:
 
 ifdef PYLINT
   PY_TESTS := $(shell find tests/shell -type f -name '*.py')
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 512f2ca0cd1a..2c1f880c4c47 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -425,7 +425,9 @@ $(OUTPUT)%.mypy_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-util-y += $(MYPY_TEST_LOGS)
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT)util/,$(MYPY_TEST_LOGS))
+	@:
 
 ifdef PYLINT
   PYLINT_TEST_LOGS := $(PY_TESTS:%=%.pylint_log)
@@ -437,7 +439,9 @@ $(OUTPUT)%.pylint_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(PYLINT) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-util-y += $(PYLINT_TEST_LOGS)
+.PHONY: pylint
+pylint: $(addprefix $(OUTPUT)util/,$(PYLINT_TEST_LOGS))
+	@:
 
 ifeq ($(CONFIG_PERF_BPF_SKEL),y)
 include $(srctree)/tools/perf/bpf_skel.mak
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing
  2026-10-01  2:34 [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
  2026-10-01  2:34 ` [PATCH 1/4] perf test: Update attr.py to use argparse Ian Rogers
  2026-10-01  2:34 ` [PATCH 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel Ian Rogers
@ 2026-10-01  2:34 ` Ian Rogers
  2026-10-01  2:34 ` [PATCH 4/4] perf build: Fix clean and install target dependencies Ian Rogers
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  2:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	Leo Yan, linux-perf-users, linux-kernel

Commit 4751bddd3f98 ("perf tools: Make GTK2 support opt-in") switched
Makefile.config and Makefile.perf from checking 'ifndef NO_GTK2' to
'ifdef GTK2' (now 'ifdef GTK4'), leaving 'NO_GTK4 := 1' in
Makefile.config unused. As a result, when building with GTK4=1 on a
system without gtk4 development headers, Makefile.perf still attempted
to build and install libperf-gtk.so under 'ifdef GTK4'.

Replace 'NO_GTK4 := 1' with 'override GTK4 :=' so that 'ifdef GTK4' in
Makefile.perf evaluates to false when the gtk4 feature check fails.

Fixes: 4751bddd3f98 ("perf tools: Make GTK2 support opt-in")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Makefile.config | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 8f46885d6df5..cafc7be79643 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -786,7 +786,7 @@ ifdef GTK4
   $(call feature_check,gtk4)
   ifneq ($(feature-gtk4), 1)
     $(warning GTK4 not found, disables GTK4 support. Please install gtk4-devel or libgtk-4-dev)
-    NO_GTK4 := 1
+    override GTK4 :=
   else
     CFLAGS += -DHAVE_GTK4_SUPPORT
     GTK_CFLAGS += $(shell $(PKG_CONFIG) --cflags gtk4 2>/dev/null)
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/4] perf build: Fix clean and install target dependencies
  2026-10-01  2:34 [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
                   ` (2 preceding siblings ...)
  2026-10-01  2:34 ` [PATCH 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing Ian Rogers
@ 2026-10-01  2:34 ` Ian Rogers
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  2:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	Leo Yan, linux-perf-users, linux-kernel

Fix several missing dependencies and ordering issues for clean and
install targets:

1. In tools/perf/Makefile, order 'install*' goals after 'all' when both
   are passed on the command line (e.g. 'make -j clean all install') so
   two concurrent Makefile.perf sub-makes do not race in the same build
   directory, and mark 'all' and 'clean' as .PHONY.

2. In tools/perf/Makefile.perf, when 'clean' is passed alongside build
   or install goals (e.g. 'make -f Makefile.perf clean install'), run
   'clean' sequentially before 'fixdep' and 'sub-make' rather than
   running 'clean' in parallel with the build inside 'sub-make'.

3. Ensure '$(OUTPUT)python' is created inside the recipe for
   '$(OUTPUT)python/perf$(PYTHON_EXTENSION_SUFFIX)' rather than only at
   Makefile parse time, in case 'clean' removed the directory.

4. Add '$(LANG_BINDINGS)' as a prerequisite of 'install-python_ext' so
   the Python C extension is built with the proper compiler/linker flags
   and perf libraries before 'setup.py install' runs.

5. Add 'install-bin', 'install-tools', 'install-tests',
   'install-python_ext', '$(DOC_TARGETS)', and '$(INSTALL_DOC_TARGETS)'
   to .PHONY in Makefile.perf.

6. Prefix targets emitted by Documentation/build-docdep.perl with
   '$(OUTPUT)' so '$(OUTPUT)doc.dep' matches out-of-tree documentation
   targets when 'O=' is specified.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Documentation/build-docdep.perl |  2 +-
 tools/perf/Makefile                        |  9 ++++++++-
 tools/perf/Makefile.perf                   | 19 +++++++++++++++----
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/build-docdep.perl b/tools/perf/Documentation/build-docdep.perl
index ba4205e0302a..f19f5107fe0f 100755
--- a/tools/perf/Documentation/build-docdep.perl
+++ b/tools/perf/Documentation/build-docdep.perl
@@ -41,6 +41,6 @@ while ($changed) {
 while (my ($text, $included) = each %include) {
     if (! exists $included{$text} &&
 	(my $base = $text) =~ s/\.txt$//) {
-	print "$base.html $base.xml : ", join(" ", keys %$included), "\n";
+	print "\$(OUTPUT)$base.html \$(OUTPUT)$base.xml : ", join(" ", keys %$included), "\n";
     }
 }
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index b8d38728306a..a0d7035cd97b 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -93,6 +93,13 @@ ifeq ($(has_clean),1)
 $(rest): clean
   endif # rest
 endif # has_clean
+
+ifneq ($(filter all,$(MAKECMDGOALS)),)
+  install_goals := $(filter install%,$(MAKECMDGOALS))
+  ifneq ($(install_goals),)
+$(install_goals): all
+  endif
+endif
 endif # MAKECMDGOALS
 
 #
@@ -130,4 +137,4 @@ check-headers:
 	$(print_msg)
 	$(make)
 
-.PHONY: tags TAGS FORCE Makefile build-test build-test-tarball check-headers
+.PHONY: all clean tags TAGS FORCE Makefile build-test build-test-tarball check-headers
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 836225b08649..d90bdd319c72 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -327,9 +327,17 @@ export HOSTCC HOSTLD HOSTAR HOSTCFLAGS SHELLCHECK MYPY PYLINT CONFIG_PERF_BPF_SK
 include $(srctree)/tools/build/Makefile.include
 
 ifeq ($(force_fixdep),1)
-goals := $(filter-out all sub-make, $(MAKECMDGOALS))
+goals := $(filter-out all sub-make clean, $(MAKECMDGOALS))
 
-$(goals) all: sub-make
+ifneq ($(filter clean,$(MAKECMDGOALS)),)
+clean-make:
+	$(Q)$(MAKE) -f Makefile.perf -j1 clean
+
+fixdep: clean-make
+.PHONY: clean-make
+endif
+
+$(goals) all clean: sub-make
 
 sub-make: fixdep
 	$(Q)$(MAKE) FIXDEP_BUILT=1 -f Makefile.perf $(goals)
@@ -565,6 +573,7 @@ $(OUTPUT)python/perf$(PYTHON_EXTENSION_SUFFIX): util/python.c util/setup.py pyth
         CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBS_PY)' \
 	  $(PYTHON_WORD) util/setup.py \
 	  $(python_setup_quiet) build_ext; \
+	$(MKDIR) -p $(OUTPUT)python; \
 	cp $(PYTHON_EXTBUILD_LIB)perf*.so $(OUTPUT)python/; \
 	if [ "$(abspath python/perf.pyi)" != "$(abspath $(OUTPUT)python/perf.pyi)" ]; then \
 		cp python/perf.pyi $(OUTPUT)python/; \
@@ -994,7 +1003,7 @@ install: install-bin try-install-man
 install-build-deps:
 	$(Q)$(SHELL) $(srctree)/tools/perf/scripts/install-build-deps.sh $(INSTALL_BUILD_DEPS_ARGS)
 
-install-python_ext:
+install-python_ext: $(LANG_BINDINGS)
 	$(PYTHON_WORD) util/setup.py $(python_setup_quiet) \
 		$(if $(OUTPUT),egg_info --egg-base $(OUTPUT)) \
 		install --root='/$(DESTDIR_SQ)'
@@ -1070,7 +1079,9 @@ endif
 
 FORCE:
 
-.PHONY: all install install-build-deps clean config-clean strip install-gtk
+.PHONY: all install install-bin install-tools install-tests install-build-deps
+.PHONY: install-gtk install-python_ext $(DOC_TARGETS) $(INSTALL_DOC_TARGETS)
+.PHONY: clean config-clean strip
 .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
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes
  2026-10-01  2:34 [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
                   ` (3 preceding siblings ...)
  2026-10-01  2:34 ` [PATCH 4/4] perf build: Fix clean and install target dependencies Ian Rogers
@ 2026-10-01  5:41 ` Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 1/4] perf test: Update attr.py to use argparse Ian Rogers
                     ` (4 more replies)
  4 siblings, 5 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  5:41 UTC (permalink / raw)
  To: irogers, acme, leo.yan, namhyung
  Cc: adrian.hunter, james.clark, jolsa, linux-kernel,
	linux-perf-users, mingo, peterz

This series includes a small Python test cleanup alongside build system
improvements for linter parallelism and clean/install target
dependencies:

1. Update tools/perf/tests/shell/lib/attr.py to use argparse instead of
   the deprecated optparse module, avoiding a pylint deprecated-module
   warning.

2. Building on Leo Yan's recent change to run pylint checks on
   standalone scripts and tests in parallel with linking perf, move the
   remaining shellcheck, mypy, and pylint rules (in tools/perf/Build,
   tools/perf/tests/Build, tools/perf/util/Build, and
   tools/perf/pmu-events/Build) into top-level phony targets in
   Makefile.perf so they no longer serialize archive creation, jevents
   generation, or final linking, nor wait on $(LANG_BINDINGS).

3. Clear GTK4 via 'override GTK4 :=' in Makefile.config when the gtk4
   feature check fails instead of setting the unused 'NO_GTK4 := 1'
   variable left over from commit 4751bddd3f98 ("perf tools: Make GTK2
   support opt-in").

4. Fix missing dependencies and target ordering for clean and install
   targets across Makefile, Makefile.perf, and
   Documentation/build-docdep.perl.

v2: In patch 4, exclude 'install-build-deps' from 'install_goals' in
    tools/perf/Makefile so it is not ordered after 'all', and explicitly
    order non-'clean' targets after 'install-build-deps' when present.

Ian Rogers (4):
  perf test: Update attr.py to use argparse
  perf build: Run shellcheck, mypy, and remaining pylint checks in
    parallel
  perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is
    missing
  perf build: Fix clean and install target dependencies

 tools/perf/Build                           |  8 ++-
 tools/perf/Documentation/build-docdep.perl |  2 +-
 tools/perf/Makefile                        | 16 ++++-
 tools/perf/Makefile.config                 |  2 +-
 tools/perf/Makefile.perf                   | 75 ++++++++++++++++++----
 tools/perf/pmu-events/Build                | 66 ++++++++++---------
 tools/perf/tests/Build                     |  8 ++-
 tools/perf/tests/shell/lib/attr.py         | 37 ++++-------
 tools/perf/util/Build                      |  8 ++-
 9 files changed, 145 insertions(+), 77 deletions(-)

-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/4] perf test: Update attr.py to use argparse
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
@ 2026-10-01  5:41   ` Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel Ian Rogers
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  5:41 UTC (permalink / raw)
  To: irogers, acme, leo.yan, namhyung
  Cc: adrian.hunter, james.clark, jolsa, linux-kernel,
	linux-perf-users, mingo, peterz

optparse is deprecated since Python 3.2 and triggers a pylint
deprecated-module warning on newer versions of pylint. Replace
optparse.OptionParser in tools/perf/tests/shell/lib/attr.py with
argparse.ArgumentParser.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/tests/shell/lib/attr.py | 37 +++++++++++-------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/lib/attr.py
index 7f3d5b64b00d..68f06df9565a 100644
--- a/tools/perf/tests/shell/lib/attr.py
+++ b/tools/perf/tests/shell/lib/attr.py
@@ -4,7 +4,7 @@ import configparser
 import os
 import sys
 import glob
-import optparse
+import argparse
 import platform
 import tempfile
 import logging
@@ -426,29 +426,20 @@ def setup_log(verbose):
     ch.setFormatter(formatter)
     log.addHandler(ch)
 
-USAGE = '''%s [OPTIONS]
-  -d dir  # tests dir
-  -p path # perf binary
-  -t test # single test
-  -v      # verbose level
-''' % sys.argv[0]
-
 def main():
-    parser = optparse.OptionParser(usage=USAGE)
-
-    parser.add_option("-t", "--test",
-                      action="store", type="string", dest="test")
-    parser.add_option("-d", "--test-dir",
-                      action="store", type="string", dest="test_dir")
-    parser.add_option("-p", "--perf",
-                      action="store", type="string", dest="perf")
-    parser.add_option("-v", "--verbose",
-                      default=0, action="count", dest="verbose")
-
-    options, args = parser.parse_args()
-    if args:
-        parser.error('FAILED wrong arguments %s' %  ' '.join(args))
-        return -1
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument("-t", "--test",
+                        action="store", dest="test", help="single test")
+    parser.add_argument("-d", "--test-dir",
+                        action="store", dest="test_dir", help="tests dir")
+    parser.add_argument("-p", "--perf",
+                        action="store", dest="perf", help="perf binary")
+    parser.add_argument("-v", "--verbose",
+                        default=0, action="count", dest="verbose",
+                        help="verbose level")
+
+    options = parser.parse_args()
 
     setup_log(options.verbose)
 
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 1/4] perf test: Update attr.py to use argparse Ian Rogers
@ 2026-10-01  5:41   ` Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing Ian Rogers
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  5:41 UTC (permalink / raw)
  To: irogers, acme, leo.yan, namhyung
  Cc: adrian.hunter, james.clark, jolsa, linux-kernel,
	linux-perf-users, mingo, peterz

Following the approach used for pylint on standalone scripts and tests,
move the shellcheck and mypy checks in tools/perf/Build and
tools/perf/tests/Build, as well as the mypy and pylint checks in
tools/perf/util/Build and tools/perf/pmu-events/Build, into dedicated
phony targets invoked as top-level sub-makes from Makefile.perf.

Also add 'perf' to pylint's --ignored-modules (leaving perf module
type-checking to mypy via perf.pyi), since astroid's ImportlibFinder
only resolves .pyi stubs for package directories (__init__.pyi) rather
than single-file stubs like perf.pyi and does not introspect C
extensions by default. This removes the need for pylint to wait on
building $(LANG_BINDINGS).

This avoids blocking jevents code generation, archive creation
(libperf-util.a, libperf-test.a, libpmu-events.a), and final linking of
the perf binary and Python extension on linter execution.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Build            |  8 +++--
 tools/perf/Makefile.perf    | 56 ++++++++++++++++++++++++++-----
 tools/perf/pmu-events/Build | 66 +++++++++++++++++++------------------
 tools/perf/tests/Build      |  8 +++--
 tools/perf/util/Build       |  8 +++--
 5 files changed, 99 insertions(+), 47 deletions(-)

diff --git a/tools/perf/Build b/tools/perf/Build
index 09fd88f5aca5..dcba5ba55206 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -76,7 +76,9 @@ $(OUTPUT)%.shellcheck_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(SHELLCHECK) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-y += $(SHELL_TEST_LOGS)
+.PHONY: shellcheck
+shellcheck: $(addprefix $(OUTPUT),$(SHELL_TEST_LOGS))
+	@:
 
 ifdef MYPY
   PY_TESTS := $(shell find python -type f -name '*.py')
@@ -89,7 +91,9 @@ $(OUTPUT)%.mypy_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-y += $(MYPY_TEST_LOGS)
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT),$(MYPY_TEST_LOGS))
+	@:
 
 ifdef PYLINT
   PY_TESTS := $(shell find python -type f -name '*.py')
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7ceefc1da774..836225b08649 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -283,8 +283,12 @@ ifneq ($(force_fixdep),1)
 endif
 
 # Runs pylint on perf python files.
-# Require pylint >= 2.16.0 (which introduced W0718 broad-exception-caught and
-# astroid .pyi stub support for perf.pyi).
+# Require pylint >= 2.16.0 (which introduced W0718 broad-exception-caught).
+# Note: astroid's ImportlibFinder only resolves .pyi stubs for package
+# directories (__init__.pyi), not single-file stubs like perf.pyi, and does not
+# introspect C extensions by default. Pass 'perf' in --ignored-modules (leaving
+# perf module type-checking to mypy via perf.pyi) so pylint does not depend on
+# building the perf Python C extension first.
 # Disabled warnings:
 #   W0123 (eval-used): Use of eval()
 #   W0311 (bad-indentation): Non-4-space indentation
@@ -310,9 +314,9 @@ ifneq ($(force_fixdep),1)
       $(warning Warning: pylint version is older than 2.16.0, skipping pylint checks.)
       override PYLINT :=
     else
-      override PYLINT := PYTHONPATH=$(abspath $(OUTPUT)python):$(srctree)/tools/perf/python:$(srctree)/tools/perf/pmu-events \
+      override PYLINT := PYTHONPATH=$(srctree)/tools/perf/python:$(srctree)/tools/perf/pmu-events \
         $(PYLINT) --disable=all --enable=E,W --disable=W0123,W0311,W0511,W0603,W0622,W0718 \
-        --ignored-modules=textual,setproctitle
+        --ignored-modules=perf,textual,setproctitle
     endif
   endif
 endif
@@ -634,18 +638,52 @@ $(SCRIPTS) : $(OUTPUT)% : %.sh
 $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
 	$(Q)$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
 
-ifdef PYLINT
-# Run Python checks after the extension is ready, independently of C builds.
-all: pylint-perf pylint-tests
-.PHONY: pylint-perf pylint-tests
+ifdef SHELLCHECK
+# Run shellcheck independently of C builds.
+all: shellcheck-perf shellcheck-tests
+.PHONY: shellcheck-perf shellcheck-tests
+
+shellcheck-perf:
+	$(Q)$(MAKE) $(build)=perf shellcheck
+
+shellcheck-tests:
+	$(Q)$(MAKE) $(build)=perf-test dir=tests shellcheck
+endif
+
+ifdef MYPY
+# Run mypy independently of C builds.
+all: mypy-perf mypy-tests mypy-util mypy-pmu-events
+.PHONY: mypy-perf mypy-tests mypy-util mypy-pmu-events
+
+mypy-perf:
+	$(Q)$(MAKE) $(build)=perf mypy
+
+mypy-tests:
+	$(Q)$(MAKE) $(build)=perf-test dir=tests mypy
 
-pylint-perf pylint-tests: | $(LANG_BINDINGS)
+mypy-util:
+	$(Q)$(MAKE) $(build)=perf-util dir=util mypy
+
+mypy-pmu-events:
+	$(Q)$(MAKE) $(build)=pmu-events dir=pmu-events mypy
+endif
+
+ifdef PYLINT
+# Run pylint independently of C builds.
+all: pylint-perf pylint-tests pylint-util pylint-pmu-events
+.PHONY: pylint-perf pylint-tests pylint-util pylint-pmu-events
 
 pylint-perf:
 	$(Q)$(MAKE) $(build)=perf pylint
 
 pylint-tests:
 	$(Q)$(MAKE) $(build)=perf-test dir=tests pylint
+
+pylint-util:
+	$(Q)$(MAKE) $(build)=perf-util dir=util pylint
+
+pylint-pmu-events:
+	$(Q)$(MAKE) $(build)=pmu-events dir=pmu-events pylint
 endif
 
 # These can record PERF_VERSION
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index 01f5a00f2125..5147139bbb6f 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -183,38 +183,6 @@ $(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C)
 # Dependencies for jevents.py
 JEVENTS_DEPS := $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY) $(EMPTY_PMU_EVENTS_TEST_LOG) $(METRIC_TEST_LOG)
 
-# Rules to run mypy if enabled.
-ifdef MYPY
-define MYPY_RULE
-$(2): $(1)
-	$$(Q)$$(call echo-cmd,test)$$(MYPY) $(1) > $(2) || (cat $(2) && rm $(2) && false)
-endef
-$(foreach src,$(wildcard pmu-events/*.py), \
-    $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(src))) \
-    $(eval $(call MYPY_RULE,$(src),$(dest))) \
-)
-
-MYPY_INPUTS := $(wildcard pmu-events/*.py)
-MYPY_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(MYPY_INPUTS))
-JEVENTS_DEPS += $(MYPY_OUTPUTS)
-endif
-
-# Rules to run pylint if enabled.
-ifdef PYLINT
-define PYLINT_RULE
-$(2): $(1)
-	$$(Q)$$(call echo-cmd,test)$$(PYLINT) $(1) > $(2) || (cat $(2) && rm $(2) && false)
-endef
-$(foreach src,$(wildcard pmu-events/*.py), \
-    $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(src))) \
-    $(eval $(call PYLINT_RULE,$(src),$(dest))) \
-)
-
-PYLINT_INPUTS := $(wildcard pmu-events/*.py)
-PYLINT_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(PYLINT_INPUTS))
-JEVENTS_DEPS += $(PYLINT_OUTPUTS)
-endif
-
 # If there are orphaned files remove them.
 ifneq ($(strip $(ORPHAN_FILES)),)
 .PHONY: prune_orphans
@@ -243,3 +211,37 @@ $(PMU_EVENTS_STRING_C): $(PMU_EVENTS_C)
 	@:
 
 endif # ifeq ($(NO_JEVENTS),1)
+
+ifneq ($(NO_JEVENTS),1)
+  PY_TESTS := $(wildcard pmu-events/*.py)
+else
+  PY_TESTS :=
+endif
+
+ifdef MYPY
+  MYPY_TEST_LOGS := $(PY_TESTS:%=%.mypy_log)
+else
+  MYPY_TEST_LOGS :=
+endif
+
+$(OUTPUT)%.mypy_log: %
+	$(call rule_mkdir)
+	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
+
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT),$(MYPY_TEST_LOGS))
+	@:
+
+ifdef PYLINT
+  PYLINT_TEST_LOGS := $(PY_TESTS:%=%.pylint_log)
+else
+  PYLINT_TEST_LOGS :=
+endif
+
+$(OUTPUT)%.pylint_log: %
+	$(call rule_mkdir)
+	$(Q)$(call echo-cmd,test)$(PYLINT) "$<" > $@ || (cat $@ && rm $@ && false)
+
+.PHONY: pylint
+pylint: $(addprefix $(OUTPUT),$(PYLINT_TEST_LOGS))
+	@:
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 05c545aac732..395f2866094a 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -93,7 +93,9 @@ $(OUTPUT)%.shellcheck_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(SHELLCHECK) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-test-y += $(SHELL_TEST_LOGS)
+.PHONY: shellcheck
+shellcheck: $(addprefix $(OUTPUT)tests/,$(SHELL_TEST_LOGS))
+	@:
 
 ifdef MYPY
   PY_TESTS := $(shell find tests/shell -type f -name '*.py')
@@ -106,7 +108,9 @@ $(OUTPUT)%.mypy_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-test-y += $(MYPY_TEST_LOGS)
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT)tests/,$(MYPY_TEST_LOGS))
+	@:
 
 ifdef PYLINT
   PY_TESTS := $(shell find tests/shell -type f -name '*.py')
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 512f2ca0cd1a..2c1f880c4c47 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -425,7 +425,9 @@ $(OUTPUT)%.mypy_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(MYPY) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-util-y += $(MYPY_TEST_LOGS)
+.PHONY: mypy
+mypy: $(addprefix $(OUTPUT)util/,$(MYPY_TEST_LOGS))
+	@:
 
 ifdef PYLINT
   PYLINT_TEST_LOGS := $(PY_TESTS:%=%.pylint_log)
@@ -437,7 +439,9 @@ $(OUTPUT)%.pylint_log: %
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,test)$(PYLINT) "$<" > $@ || (cat $@ && rm $@ && false)
 
-perf-util-y += $(PYLINT_TEST_LOGS)
+.PHONY: pylint
+pylint: $(addprefix $(OUTPUT)util/,$(PYLINT_TEST_LOGS))
+	@:
 
 ifeq ($(CONFIG_PERF_BPF_SKEL),y)
 include $(srctree)/tools/perf/bpf_skel.mak
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 1/4] perf test: Update attr.py to use argparse Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel Ian Rogers
@ 2026-10-01  5:41   ` Ian Rogers
  2026-10-01  5:41   ` [PATCH v2 4/4] perf build: Fix clean and install target dependencies Ian Rogers
  2026-10-01 15:54   ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  5:41 UTC (permalink / raw)
  To: irogers, acme, leo.yan, namhyung
  Cc: adrian.hunter, james.clark, jolsa, linux-kernel,
	linux-perf-users, mingo, peterz

Commit 4751bddd3f98 ("perf tools: Make GTK2 support opt-in") switched
Makefile.config and Makefile.perf from checking 'ifndef NO_GTK2' to
'ifdef GTK2' (now 'ifdef GTK4'), leaving 'NO_GTK4 := 1' in
Makefile.config unused. As a result, when building with GTK4=1 on a
system without gtk4 development headers, Makefile.perf still attempted
to build and install libperf-gtk.so under 'ifdef GTK4'.

Replace 'NO_GTK4 := 1' with 'override GTK4 :=' so that 'ifdef GTK4' in
Makefile.perf evaluates to false when the gtk4 feature check fails.

Fixes: 4751bddd3f98 ("perf tools: Make GTK2 support opt-in")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Makefile.config | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 8f46885d6df5..cafc7be79643 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -786,7 +786,7 @@ ifdef GTK4
   $(call feature_check,gtk4)
   ifneq ($(feature-gtk4), 1)
     $(warning GTK4 not found, disables GTK4 support. Please install gtk4-devel or libgtk-4-dev)
-    NO_GTK4 := 1
+    override GTK4 :=
   else
     CFLAGS += -DHAVE_GTK4_SUPPORT
     GTK_CFLAGS += $(shell $(PKG_CONFIG) --cflags gtk4 2>/dev/null)
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 4/4] perf build: Fix clean and install target dependencies
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
                     ` (2 preceding siblings ...)
  2026-10-01  5:41   ` [PATCH v2 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing Ian Rogers
@ 2026-10-01  5:41   ` Ian Rogers
  2026-10-01 15:54   ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 11+ messages in thread
From: Ian Rogers @ 2026-10-01  5:41 UTC (permalink / raw)
  To: irogers, acme, leo.yan, namhyung
  Cc: adrian.hunter, james.clark, jolsa, linux-kernel,
	linux-perf-users, mingo, peterz

Fix several missing dependencies and ordering issues for clean and
install targets:

1. In tools/perf/Makefile, order 'install*' goals (excluding
   'install-build-deps', which is ordered before build/install goals)
   after 'all' when both are passed on the command line (e.g.
   'make -j clean all install') so two concurrent Makefile.perf
   sub-makes do not race in the same build directory, and mark 'all' and
   'clean' as .PHONY.

2. In tools/perf/Makefile.perf, when 'clean' is passed alongside build
   or install goals (e.g. 'make -f Makefile.perf clean install'), run
   'clean' sequentially before 'fixdep' and 'sub-make' rather than
   running 'clean' in parallel with the build inside 'sub-make'.

3. Ensure '$(OUTPUT)python' is created inside the recipe for
   '$(OUTPUT)python/perf$(PYTHON_EXTENSION_SUFFIX)' rather than only at
   Makefile parse time, in case 'clean' removed the directory.

4. Add '$(LANG_BINDINGS)' as a prerequisite of 'install-python_ext' so
   the Python C extension is built with the proper compiler/linker flags
   and perf libraries before 'setup.py install' runs.

5. Add 'install-bin', 'install-tools', 'install-tests',
   'install-python_ext', '$(DOC_TARGETS)', and '$(INSTALL_DOC_TARGETS)'
   to .PHONY in Makefile.perf.

6. Prefix targets emitted by Documentation/build-docdep.perl with
   '$(OUTPUT)' so '$(OUTPUT)doc.dep' matches out-of-tree documentation
   targets when 'O=' is specified.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Documentation/build-docdep.perl |  2 +-
 tools/perf/Makefile                        | 16 +++++++++++++++-
 tools/perf/Makefile.perf                   | 19 +++++++++++++++----
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/build-docdep.perl b/tools/perf/Documentation/build-docdep.perl
index ba4205e0302a..f19f5107fe0f 100755
--- a/tools/perf/Documentation/build-docdep.perl
+++ b/tools/perf/Documentation/build-docdep.perl
@@ -41,6 +41,6 @@ while ($changed) {
 while (my ($text, $included) = each %include) {
     if (! exists $included{$text} &&
 	(my $base = $text) =~ s/\.txt$//) {
-	print "$base.html $base.xml : ", join(" ", keys %$included), "\n";
+	print "\$(OUTPUT)$base.html \$(OUTPUT)$base.xml : ", join(" ", keys %$included), "\n";
     }
 }
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index b8d38728306a..c1818bd5f287 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -93,6 +93,20 @@ ifeq ($(has_clean),1)
 $(rest): clean
   endif # rest
 endif # has_clean
+
+ifneq ($(filter install-build-deps,$(MAKECMDGOALS)),)
+  after_deps := $(filter-out clean install-build-deps,$(MAKECMDGOALS))
+  ifneq ($(after_deps),)
+$(after_deps): install-build-deps
+  endif
+endif
+
+ifneq ($(filter all,$(MAKECMDGOALS)),)
+  install_goals := $(filter-out install-build-deps,$(filter install%,$(MAKECMDGOALS)))
+  ifneq ($(install_goals),)
+$(install_goals): all
+  endif
+endif
 endif # MAKECMDGOALS
 
 #
@@ -130,4 +144,4 @@ check-headers:
 	$(print_msg)
 	$(make)
 
-.PHONY: tags TAGS FORCE Makefile build-test build-test-tarball check-headers
+.PHONY: all clean tags TAGS FORCE Makefile build-test build-test-tarball check-headers
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 836225b08649..d90bdd319c72 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -327,9 +327,17 @@ export HOSTCC HOSTLD HOSTAR HOSTCFLAGS SHELLCHECK MYPY PYLINT CONFIG_PERF_BPF_SK
 include $(srctree)/tools/build/Makefile.include
 
 ifeq ($(force_fixdep),1)
-goals := $(filter-out all sub-make, $(MAKECMDGOALS))
+goals := $(filter-out all sub-make clean, $(MAKECMDGOALS))
 
-$(goals) all: sub-make
+ifneq ($(filter clean,$(MAKECMDGOALS)),)
+clean-make:
+	$(Q)$(MAKE) -f Makefile.perf -j1 clean
+
+fixdep: clean-make
+.PHONY: clean-make
+endif
+
+$(goals) all clean: sub-make
 
 sub-make: fixdep
 	$(Q)$(MAKE) FIXDEP_BUILT=1 -f Makefile.perf $(goals)
@@ -565,6 +573,7 @@ $(OUTPUT)python/perf$(PYTHON_EXTENSION_SUFFIX): util/python.c util/setup.py pyth
         CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBS_PY)' \
 	  $(PYTHON_WORD) util/setup.py \
 	  $(python_setup_quiet) build_ext; \
+	$(MKDIR) -p $(OUTPUT)python; \
 	cp $(PYTHON_EXTBUILD_LIB)perf*.so $(OUTPUT)python/; \
 	if [ "$(abspath python/perf.pyi)" != "$(abspath $(OUTPUT)python/perf.pyi)" ]; then \
 		cp python/perf.pyi $(OUTPUT)python/; \
@@ -994,7 +1003,7 @@ install: install-bin try-install-man
 install-build-deps:
 	$(Q)$(SHELL) $(srctree)/tools/perf/scripts/install-build-deps.sh $(INSTALL_BUILD_DEPS_ARGS)
 
-install-python_ext:
+install-python_ext: $(LANG_BINDINGS)
 	$(PYTHON_WORD) util/setup.py $(python_setup_quiet) \
 		$(if $(OUTPUT),egg_info --egg-base $(OUTPUT)) \
 		install --root='/$(DESTDIR_SQ)'
@@ -1070,7 +1079,9 @@ endif
 
 FORCE:
 
-.PHONY: all install install-build-deps clean config-clean strip install-gtk
+.PHONY: all install install-bin install-tools install-tests install-build-deps
+.PHONY: install-gtk install-python_ext $(DOC_TARGETS) $(INSTALL_DOC_TARGETS)
+.PHONY: clean config-clean strip
 .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
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes
  2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
                     ` (3 preceding siblings ...)
  2026-10-01  5:41   ` [PATCH v2 4/4] perf build: Fix clean and install target dependencies Ian Rogers
@ 2026-10-01 15:54   ` Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 11+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-10-01 15:54 UTC (permalink / raw)
  To: Ian Rogers
  Cc: leo.yan, namhyung, adrian.hunter, james.clark, jolsa,
	linux-kernel, linux-perf-users, mingo, peterz

On Wed, Sep 30, 2026 at 10:41:16PM -0700, Ian Rogers wrote:
> This series includes a small Python test cleanup alongside build system
> improvements for linter parallelism and clean/install target
> dependencies:

Thanks, applied to perf-tools-next, for v7.4.

- Arnaldo

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-10-01 15:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01  2:34 [PATCH 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
2026-10-01  2:34 ` [PATCH 1/4] perf test: Update attr.py to use argparse Ian Rogers
2026-10-01  2:34 ` [PATCH 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel Ian Rogers
2026-10-01  2:34 ` [PATCH 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing Ian Rogers
2026-10-01  2:34 ` [PATCH 4/4] perf build: Fix clean and install target dependencies Ian Rogers
2026-10-01  5:41 ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Ian Rogers
2026-10-01  5:41   ` [PATCH v2 1/4] perf test: Update attr.py to use argparse Ian Rogers
2026-10-01  5:41   ` [PATCH v2 2/4] perf build: Run shellcheck, mypy, and remaining pylint checks in parallel Ian Rogers
2026-10-01  5:41   ` [PATCH v2 3/4] perf build: Clear GTK4 instead of setting unused NO_GTK4 when gtk4 is missing Ian Rogers
2026-10-01  5:41   ` [PATCH v2 4/4] perf build: Fix clean and install target dependencies Ian Rogers
2026-10-01 15:54   ` [PATCH v2 0/4] perf build: Linter parallelism and clean/install dependency fixes Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®