summaryrefslogtreecommitdiff
path: root/mk/cores.mk
blob: 7ce2e47e741190d489f9421dfdacf9d717febae4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
here = $(if $(mod_path),$(mod_path)/)
mod_path :=
subdir_stack :=

unknown_core = $(error unknown core '$(1)')

all_cores :=
all_stamps :=

top_stamp = $(call core_stamp,$(rule_top))
core_stamp = $(obj)/deps/$(core_info/$(1)/path)/stamp

core_paths = \
  $(patsubst /%,%, \
    $(patsubst /,., \
      $(abspath \
        $(let prefix,$(core_info/$(1)/workdir), \
          $(addprefix /$(if $(prefix),$(prefix)/),$(core_info/$(1)/$(2)))))))

define add_core
  this := core_info/$(1)

  ifneq (,$$($$(this)/path))
    $$(error multiple definitions of core '$(1)': '$$($$(this)/path)' and '$(2)')
  else ifneq (,$$(core_path/$(2)))
    $$(error multiple cores under path '$(2)')
  endif

  $$(this)/path := $(2)
  $$(this)/mod_file := $$(mod_file)
  $$(this)/workdir := $$(mod_path)

  $$(eval $$(call $(3)))

  this :=
  all_cores += $(1)
  core_path/$(2) := $(1)
endef

define add_core_subdir
  core :=
  cores :=
  subdirs :=

  subdir_stack += $$(mod_path)
  mod_path := $$(here)$(1)
  mod_file := $$(here)mod.mk

  include $$(mod_file)

  $$(if $$(core), \
    $$(eval $$(call add_core,$(notdir $(1)),$$(mod_path),core)))

  $$(foreach core,$$(cores), \
    $$(eval $$(call add_core,$$(core),$$(here)$$(core),core/$$(core))))

  $$(foreach subdir,$$(subdirs), \
    $$(eval $$(call add_core_subdir,$$(subdir))))

  mod_path := $$(lastword $$(subdir_stack))
  subdir_stack := $$(filter-out $$(mod_path),$$(subdir_stack))
endef

define setup_dep_tree
  $$(foreach core,$$(all_cores), \
    $$(eval $$(call defer,dep_tree/$$(core),$$$$(call get_core_deps,$$(core)))))
endef

define setup_stamp_rules
  $$(foreach core,$$(all_cores), \
    $$(let stamp,$$(call core_stamp,$$(core)), \
      $$(stamp) \
      $$(eval $$(call add_core_stamp,$$(core),$$(stamp))))): $$(build_makefiles) | $$(obj)
endef

define add_core_stamp
  $(2): $$(core_info/$(1)/mod_file) \
        $$(foreach dep,$$(core_info/$(1)/deps),$$(call core_stamp,$$(dep)))

  all_stamps += $(2)
endef

define get_core_deps
  dep_tree/$(1) :=

  $$(foreach dep,$$(core_info/$(1)/deps), \
    $$(if $$(core_info/$$(dep)/path),,$$(call unknown_core,$$(dep))) \
    $$(eval dep_tree/$(1) := \
      $$(dep_tree/$$(dep)) $$(filter-out $$(dep_tree/$$(dep)),$$(dep_tree/$(1)))))

  dep_tree/$(1) := $$(strip $$(dep_tree/$(1)))
  dep_tree/$(1) += $(1)
endef

map_core_deps = \
  $(if $(findstring undefined,$(origin $(1)_deps/$(2))), \
    $(eval $(call merge_mapped_deps,$(1),$(2)))) \
  $($(1)_deps/$(2))

define merge_mapped_deps
  $(1)_deps/$(2) := $$(core_info/$(2)/$(1))

  $$(foreach dep,$$(core_info/$(2)/deps), \
    $$(eval $(1)_deps/$(2) := \
      $$(let mapped_dep,$$(call map_core_deps,$(1),$$(dep)), \
        $$(mapped_dep) $$(filter-out $$(mapped_dep),$$($(1)_deps/$(2))))))
endef

define finish_stamp_rules
  $$(all_stamps):
	@mkdir -p $$$$(dirname $$@) && touch $$@
endef