| EMPTY_PMU_EVENTS_C = pmu-events/empty-pmu-events.c | |
| # pmu-events.c will be generated by jevents.py or copied from EMPTY_PMU_EVENTS_C | |
| PMU_EVENTS_C = $(OUTPUT)pmu-events/pmu-events.c | |
| PMU_EVENTS_STRING_C = $(OUTPUT)pmu-events/pmu-events-string.c | |
| pmu-events-y += pmu-events.o | |
| ifneq ($(NO_JEVENTS),1) | |
| pmu-events-y += pmu-events-string.o | |
| endif | |
| # pmu-events.c file is generated in the OUTPUT directory so it needs a | |
| # separate rule to depend on it properly | |
| $(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C) | |
| $(call rule_mkdir) | |
| $(call if_changed_dep,cc_o_c) | |
| $(OUTPUT)pmu-events/pmu-events-string.o: $(PMU_EVENTS_STRING_C) | |
| $(call rule_mkdir) | |
| $(call if_changed_dep,cc_o_c) | |
| # Message for $(call echo-cmd,cp), possibly remove the src file from | |
| # the destination to save space in the build log. | |
| quiet_cmd_cp = COPY $(patsubst %$<,%,$@) <- $< | |
| # --- NO_JEVENTS=1 build --- | |
| ifeq ($(NO_JEVENTS),1) | |
| $(PMU_EVENTS_C): $(EMPTY_PMU_EVENTS_C) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,cp)cp $< $@ | |
| else | |
| # --- Regular build --- | |
| # Setup the JEVENTS_ARCH and JEVENTS_MODEL | |
| ifeq ($(JEVENTS_ARCH),) | |
| JEVENTS_ARCH=$(SRCARCH) | |
| endif | |
| JEVENTS_MODEL ?= all | |
| # The input json/csv files | |
| SRC_DIR := pmu-events/arch | |
| ifeq ($(JEVENTS_ARCH),all) | |
| SRC_JSON := $(shell find $(SRC_DIR) -name '*.json' -o -name '*.csv') | |
| else | |
| SRC_JSON := $(shell find $(SRC_DIR)/common $(SRC_DIR)/test $(SRC_DIR)/$(JEVENTS_ARCH) -name '*.json' -o -name '*.csv') | |
| endif | |
| # Python to build the generic legacy cache events | |
| LEGACY_CACHE_PY = pmu-events/make_legacy_cache.py | |
| LEGACY_CACHE_JSON = $(OUTPUT)pmu-events/arch/common/common/legacy-cache.json | |
| GEN_JSON = $(LEGACY_CACHE_JSON) | |
| $(LEGACY_CACHE_JSON): $(LEGACY_CACHE_PY) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $(LEGACY_CACHE_PY) > $@ | |
| # Python to generate architectural metrics | |
| GEN_METRIC_DEPS := pmu-events/metric.py pmu-events/common_metrics.py | |
| # Functions to extract the model from an extra-metrics.json or extra-metricgroups.json path. | |
| model_name = $(notdir $(patsubst %/,%,$(dir $(1)))) | |
| vendor_name = $(notdir $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $(1)))))) | |
| ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all)) | |
| # Generate AMD Json | |
| ZENS := $(shell ls -d pmu-events/arch/x86/amdzen*) | |
| ZEN_METRICS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metrics.json) | |
| ZEN_METRICGROUPS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metricgroups.json) | |
| GEN_JSON += $(ZEN_METRICS) $(ZEN_METRICGROUPS) | |
| $(ZEN_METRICS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@ | |
| $(ZEN_METRICGROUPS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@ | |
| endif | |
| ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),arm64 all)) | |
| # Generate ARM Json | |
| ARMS := $(shell ls -d pmu-events/arch/arm64/arm/*|grep -v cmn) | |
| ARM_METRICS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metrics.json) | |
| ARM_METRICGROUPS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metricgroups.json) | |
| GEN_JSON += $(ARM_METRICS) $(ARM_METRICGROUPS) | |
| $(ARM_METRICS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@ | |
| $(ARM_METRICGROUPS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@ | |
| endif | |
| ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all)) | |
| # Generate Intel Json | |
| INTELS := $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv) | |
| INTEL_METRICS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metrics.json) | |
| INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json) | |
| GEN_JSON += $(INTEL_METRICS) $(INTEL_METRICGROUPS) | |
| $(INTEL_METRICS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@ | |
| $(INTEL_METRICGROUPS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@ | |
| endif | |
| OUT_DIR := $(OUTPUT)pmu-events/arch | |
| ifeq ($(OUTPUT),) | |
| OUT_JSON := $(SRC_JSON) | |
| ORPHAN_FILES := | |
| else | |
| # Things that need to be built in the OUTPUT directory. Note, ensure | |
| # there is a slash after the directory name so that it matches what | |
| # $(dir) gives in COPY_RULE. | |
| OUT_JSON := $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%,$(SRC_JSON)) | |
| OUT_DIRS := $(sort $(patsubst %/,%,$(dir $(OUT_JSON)))) | |
| # Things already in the OUTPUT directory | |
| CUR_OUT_JSON := $(shell [ -d $(OUT_DIR) ] && find $(OUT_DIR) -type f) | |
| # Things in the OUTPUT directory but shouldn't be there as computed by | |
| # OUT_JSON and GEN_JSON. | |
| ORPHAN_FILES := $(filter-out $(OUT_JSON) $(GEN_JSON),$(CUR_OUT_JSON)) | |
| # Message for $(call echo-cmd,mkd). There is already a mkdir message | |
| # but it assumes $@ is a file to mkdir the directory for. | |
| quiet_cmd_mkd = MKDIR $@ | |
| $(OUT_DIRS): | |
| $(Q)$(call echo-cmd,mkd)mkdir -p $@ | |
| # Explicitly generate rules to copy SRC_JSON files as $(dir) cannot | |
| # apply to $@ in a dependency. Exclude from the copy rules any that | |
| # look like they are copying generated json. This happens as a perf | |
| # build within the tools/perf directory will leave generated json | |
| # files within the tree, these then get picked up by SRC_JSON find. | |
| define COPY_RULE | |
| $(2): $(1) | $(3) | |
| $$(Q)$$(call echo-cmd,cp)cp $(1) $(2) | |
| endef | |
| $(foreach src,$(SRC_JSON), \ | |
| $(eval dest := $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%,$(src))) \ | |
| $(eval ddir := $(patsubst %/,%,$(dir $(dest)))) \ | |
| $(if $(filter $(dest),$(GEN_JSON)),, \ | |
| $(eval $(call COPY_RULE,$(src),$(dest),$(ddir))) \ | |
| ) \ | |
| ) | |
| endif # ifneq ($(OUTPUT),) | |
| JEVENTS_PY = pmu-events/jevents.py | |
| METRIC_PY = pmu-events/metric.py | |
| # Rule to run the metric test. | |
| METRIC_TEST_PY = pmu-events/metric_test.py | |
| METRIC_TEST_LOG = $(OUTPUT)pmu-events/metric_test.log | |
| $(METRIC_TEST_LOG): $(METRIC_TEST_PY) $(METRIC_PY) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,test)$(PYTHON) $< 2> $@ || (cat $@ && false) | |
| # Rule to create then ensure the empty-pmu-events.c is in sync. | |
| TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c | |
| EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log | |
| $(TEST_EMPTY_PMU_EVENTS_C): $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none $(OUTPUT)pmu-events/arch $@ | |
| $(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,test)diff -u $^ 2> $@ || (cat $@ && false) | |
| # 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 | |
| # Message for $(call echo-cmd,rm). Generally cleaning files isn't part | |
| # of a build step. | |
| quiet_cmd_rm = RM ...$(words $^) orphan file(s)... | |
| # The list of files can be long. Use xargs to prevent issues. | |
| prune_orphans: $(ORPHAN_FILES) | |
| $(Q)$(call echo-cmd,rm)echo "$^" | xargs rm -f | |
| JEVENTS_DEPS += prune_orphans | |
| endif | |
| # Finally, the rule to build pmu-events.c using jevents.py. All test | |
| # and inputs are dependencies. | |
| $(PMU_EVENTS_C): $(JEVENTS_DEPS) | |
| $(call rule_mkdir) | |
| $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) \ | |
| $(OUT_DIR) $(PMU_EVENTS_C) $(PMU_EVENTS_STRING_C) | |
| $(PMU_EVENTS_STRING_C): $(PMU_EVENTS_C) | |
| @: | |
| endif # ifeq ($(NO_JEVENTS),1) |