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