perf build: Run shellcheck, mypy, and remaining pylint checks in parallel

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>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2026-09-30 22:41:18 -07:00 committed by Arnaldo Carvalho de Melo
parent cd116fcbc0
commit 857dad68dc
5 changed files with 99 additions and 47 deletions

View File

@ -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')

View File

@ -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
pylint-perf pylint-tests: | $(LANG_BINDINGS)
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
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

View File

@ -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))
@:

View File

@ -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')

View File

@ -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