Build 8.1 KB

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