xref: /linux/tools/perf/pmu-events/Build (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1EMPTY_PMU_EVENTS_C = pmu-events/empty-pmu-events.c
2# pmu-events.c will be generated by jevents.py or copied from EMPTY_PMU_EVENTS_C
3PMU_EVENTS_C	=  $(OUTPUT)pmu-events/pmu-events.c
4pmu-events-y	+= pmu-events.o
5
6# pmu-events.c file is generated in the OUTPUT directory so it needs a
7# separate rule to depend on it properly
8$(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C)
9	$(call rule_mkdir)
10	$(call if_changed_dep,cc_o_c)
11
12# Message for $(call echo-cmd,cp), possibly remove the src file from
13# the destination to save space in the build log.
14quiet_cmd_cp   = COPY    $(patsubst %$<,%,$@) <- $<
15
16# --- NO_JEVENTS=1 build ---
17ifeq ($(NO_JEVENTS),1)
18$(PMU_EVENTS_C): $(EMPTY_PMU_EVENTS_C)
19	$(call rule_mkdir)
20	$(Q)$(call echo-cmd,cp)cp $< $@
21else
22# --- Regular build ---
23
24# Setup the JEVENTS_ARCH and JEVENTS_MODEL
25ifeq ($(JEVENTS_ARCH),)
26JEVENTS_ARCH=$(SRCARCH)
27endif
28JEVENTS_MODEL ?= all
29
30# The input json/csv files
31SRC_DIR		:= pmu-events/arch
32ifeq ($(JEVENTS_ARCH),all)
33SRC_JSON	:= $(shell find $(SRC_DIR) -name '*.json' -o -name '*.csv')
34else
35SRC_JSON	:= $(shell find $(SRC_DIR)/common $(SRC_DIR)/test $(SRC_DIR)/$(JEVENTS_ARCH) -name '*.json' -o -name '*.csv')
36endif
37
38# Python to build the generic legacy cache events
39LEGACY_CACHE_PY	=  pmu-events/make_legacy_cache.py
40LEGACY_CACHE_JSON = $(OUTPUT)pmu-events/arch/common/common/legacy-cache.json
41GEN_JSON = $(LEGACY_CACHE_JSON)
42
43$(LEGACY_CACHE_JSON): $(LEGACY_CACHE_PY)
44	$(call rule_mkdir)
45	$(Q)$(call echo-cmd,gen)$(PYTHON) $(LEGACY_CACHE_PY) > $@
46
47# Python to generate architectural metrics
48GEN_METRIC_DEPS := pmu-events/metric.py pmu-events/common_metrics.py
49# Functions to extract the model from an extra-metrics.json or extra-metricgroups.json path.
50model_name = $(shell echo $(1)|sed -e 's@.\+/\(.*\)/extra-metric.*\.json@\1@')
51vendor_name = $(shell echo $(1)|sed -e 's@.\+/\(.*\)/[^/]*/extra-metric.*\.json@\1@')
52
53ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all))
54# Generate AMD Json
55ZENS = $(shell ls -d pmu-events/arch/x86/amdzen*)
56ZEN_METRICS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metrics.json)
57ZEN_METRICGROUPS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metricgroups.json)
58GEN_JSON += $(ZEN_METRICS) $(ZEN_METRICGROUPS)
59
60$(ZEN_METRICS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS)
61	$(call rule_mkdir)
62	$(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@
63
64$(ZEN_METRICGROUPS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS)
65	$(call rule_mkdir)
66	$(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@
67
68endif
69
70ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),arm64 all))
71# Generate ARM Json
72ARMS = $(shell ls -d pmu-events/arch/arm64/arm/*|grep -v cmn)
73ARM_METRICS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metrics.json)
74ARM_METRICGROUPS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metricgroups.json)
75GEN_JSON += $(ARM_METRICS) $(ARM_METRICGROUPS)
76
77$(ARM_METRICS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS)
78	$(call rule_mkdir)
79	$(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@
80
81$(ARM_METRICGROUPS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS)
82	$(call rule_mkdir)
83	$(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@
84
85endif
86
87ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all))
88# Generate Intel Json
89INTELS = $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv)
90INTEL_METRICS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metrics.json)
91INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json)
92GEN_JSON += $(INTEL_METRICS) $(INTEL_METRICGROUPS)
93
94$(INTEL_METRICS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS)
95	$(call rule_mkdir)
96	$(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@
97
98$(INTEL_METRICGROUPS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS)
99	$(call rule_mkdir)
100	$(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@
101
102endif
103
104OUT_DIR		:= $(OUTPUT)pmu-events/arch
105
106ifeq ($(OUTPUT),)
107OUT_JSON	:= $(SRC_JSON)
108ORPHAN_FILES	:=
109else
110# Things that need to be built in the OUTPUT directory. Note, ensure
111# there is a slash after the directory name so that it matches what
112# $(dir) gives in COPY_RULE.
113OUT_JSON	:= $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%,$(SRC_JSON))
114OUT_DIRS	:= $(sort $(patsubst %/,%,$(dir $(OUT_JSON))))
115
116# Things already in the OUTPUT directory
117CUR_OUT_JSON	:= $(shell [ -d $(OUT_DIR) ] && find $(OUT_DIR) -type f)
118
119# Things in the OUTPUT directory but shouldn't be there as computed by
120# OUT_JSON and GEN_JSON.
121ORPHAN_FILES	:= $(filter-out $(OUT_JSON) $(GEN_JSON),$(CUR_OUT_JSON))
122
123# Message for $(call echo-cmd,mkd). There is already a mkdir message
124# but it assumes $@ is a file to mkdir the directory for.
125quiet_cmd_mkd  = MKDIR   $@
126
127$(OUT_DIRS):
128	$(Q)$(call echo-cmd,mkd)mkdir -p $@
129
130# Explicitly generate rules to copy SRC_JSON files as $(dir) cannot
131# apply to $@ in a dependency. Exclude from the copy rules any that
132# look like they are copying generated json. This happens as a perf
133# build within the tools/perf directory will leave generated json
134# files within the tree, these then get picked up by SRC_JSON find.
135define COPY_RULE
136$(2): $(1) | $(3)
137	$$(Q)$$(call echo-cmd,cp)cp $(1) $(2)
138endef
139$(foreach src,$(SRC_JSON), \
140    $(eval dest := $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%,$(src))) \
141    $(eval ddir := $(patsubst %/,%,$(dir $(dest)))) \
142    $(if $(filter $(dest),$(GEN_JSON)),, \
143        $(eval $(call COPY_RULE,$(src),$(dest),$(ddir))) \
144    ) \
145)
146
147endif # ifneq ($(OUTPUT),)
148
149JEVENTS_PY	=  pmu-events/jevents.py
150METRIC_PY	=  pmu-events/metric.py
151
152# Rule to run the metric test.
153METRIC_TEST_PY	=  pmu-events/metric_test.py
154METRIC_TEST_LOG	=  $(OUTPUT)pmu-events/metric_test.log
155
156$(METRIC_TEST_LOG): $(METRIC_TEST_PY) $(METRIC_PY)
157	$(call rule_mkdir)
158	$(Q)$(call echo-cmd,test)$(PYTHON) $< 2> $@ || (cat $@ && false)
159
160# Rule to create then ensure the empty-pmu-events.c is in sync.
161TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c
162EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log
163
164$(TEST_EMPTY_PMU_EVENTS_C): $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY)
165	$(call rule_mkdir)
166	$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none $(OUTPUT)pmu-events/arch $@
167
168$(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C)
169	$(call rule_mkdir)
170	$(Q)$(call echo-cmd,test)diff -u $^ 2> $@ || (cat $@ && false)
171
172
173# Dependencies for jevents.py
174JEVENTS_DEPS := $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY) $(EMPTY_PMU_EVENTS_TEST_LOG) $(METRIC_TEST_LOG)
175
176# Rules to run mypy if enabled.
177ifdef MYPY
178define MYPY_RULE
179$(2): $(1)
180	$$(Q)$$(call echo-cmd,test)mypy $(1) > $(2) || (cat $(2) && rm $(2) && false)
181endef
182$(foreach src,$(wildcard pmu-events/*.py), \
183    $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(src))) \
184    $(eval $(call MYPY_RULE,$(src),$(dest))) \
185)
186
187MYPY_INPUTS := $(wildcard pmu-events/*.py)
188MYPY_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(MYPY_INPUTS))
189JEVENTS_DEPS += $(MYPY_OUTPUTS)
190endif
191
192# Rules to run pylint if enabled.
193ifdef PYLINT
194define PYLINT_RULE
195$(2): $(1)
196	$$(Q)$$(call echo-cmd,test)pylint $(1) > $(2) || (cat $(2) && rm $(2) && false)
197endef
198$(foreach src,$(wildcard pmu-events/*.py), \
199    $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(src))) \
200    $(eval $(call PYLINT_RULE,$(src),$(dest))) \
201)
202
203PYLINT_INPUTS := $(wildcard pmu-events/*.py)
204PYLINT_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(PYLINT_INPUTS))
205JEVENTS_DEPS += $(PYLINT_OUTPUTS)
206endif
207
208# If there are orphaned files remove them.
209ifneq ($(strip $(ORPHAN_FILES)),)
210.PHONY: prune_orphans
211
212# Message for $(call echo-cmd,rm). Generally cleaning files isn't part
213# of a build step.
214quiet_cmd_rm  = RM      $^
215
216prune_orphans: $(ORPHAN_FILES)
217	$(Q)$(call echo-cmd,rm)rm -f $^
218
219JEVENTS_DEPS += prune_orphans
220endif
221
222# Finally, the rule to build pmu-events.c using jevents.py. All test
223# and inputs are dependencies.
224$(PMU_EVENTS_C): $(JEVENTS_DEPS)
225	$(call rule_mkdir)
226	$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) $(OUT_DIR) $@
227
228endif # ifeq ($(NO_JEVENTS),1)
229