1# This file is intended to be included from each subdirectory makefile.
2#
3# Subdirectory makefiles must define:
4#   SubDirs - The subdirectories to traverse.
5#   ObjNames - The objects available in that directory.
6#   Implementation - The library configuration the objects should go in (Generic or
7#                    Optimized)
8#   Dependencies - Any dependences for the object files.
9#
10# Subdirectory makefiles may define:
11#   OnlyArchs - Only build the objects for the listed archs.
12#   OnlyConfigs - Only build the objects for the listed configurations.
13
14ifeq ($(Dir),)
15  $(error "No Dir variable defined.")
16endif
17
18###
19# Include child makefile fragments
20
21# The list of variables which are intended to be overridden in a subdirectory
22# makefile.
23RequiredSubdirVariables := SubDirs ObjNames Implementation Dependencies
24OptionalSubdirVariables := OnlyArchs OnlyConfigs
25
26# Template: subdir_traverse_template subdir
27define subdir_traverse_template
28$(call Set,Dir,$(1))
29ifneq ($(DEBUGMAKE),)
30  $$(info MAKE: $(Dir): Processing subdirectory)
31endif
32
33# Construct the variable key for this directory.
34$(call Set,DirKey,SubDir.$(subst .,,$(subst /,__,$(1))))
35$(call Append,SubDirKeys,$(DirKey))
36$(call Set,$(DirKey).Dir,$(Dir))
37
38# Reset subdirectory specific variables to sentinel value.
39$$(foreach var,$$(RequiredSubdirVariables) $$(OptionalSubdirVariables),\
40  $$(call Set,$$(var),UNDEFINED))
41
42# Get the subdirectory variables.
43include $(1)/Makefile.mk
44
45ifeq ($(DEBUGMAKE),2)
46$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\
47  $$(if $$(call strneq,UNDEFINED,$$($$(var))), \
48	$$(info MAKE: $(Dir): $$(var) is defined), \
49	$$(info MAKE: $(Dir): $$(var) is undefined)))
50endif
51
52# Check for undefined required variables, and unset sentinel value from optional
53# variables.
54$$(foreach var,$(RequiredSubdirVariables),\
55  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
56	$$(error $(Dir): variable '$$(var)' was not undefined)))
57$$(foreach var,$(OptionalSubdirVariables),\
58  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
59	$$(call Set,$$(var),)))
60
61# Collect all subdirectory variables for subsequent use.
62$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\
63  $$(call Set,$(DirKey).$$(var),$$($$(var))))
64
65# Recurse.
66include make/subdir.mk
67
68# Restore directory variable, for cleanliness.
69$$(call Set,Dir,$(1))
70
71ifneq ($(DEBUGMAKE),)
72  $$(info MAKE: $$(Dir): Done processing subdirectory)
73endif
74endef
75
76# Evaluate this now so we do not have to worry about order of evaluation.
77
78SubDirsList := $(strip \
79  $(if $(call streq,.,$(Dir)),\
80       $(SubDirs),\
81       $(SubDirs:%=$(Dir)/%)))
82ifeq ($(SubDirsList),)
83else
84  ifneq ($(DEBUGMAKE),)
85    $(info MAKE: Descending into subdirs: $(SubDirsList))
86  endif
87
88  $(foreach subdir,$(SubDirsList),\
89	$(eval $(call subdir_traverse_template,$(subdir))))
90endif
91