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