subdir.mk revision f06648acf50b17b4a90abb46eb4515947f96fecd
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 := \
24	ModuleName SubDirs ObjNames Implementation Dependencies
25OptionalSubdirVariables := OnlyArchs OnlyConfigs
26
27# Template: subdir_traverse_template subdir
28define subdir_traverse_template
29$(call Set,Dir,$(1))
30ifneq ($(DEBUGMAKE),)
31  $$(info MAKE: $(Dir): Processing subdirectory)
32endif
33
34# Construct the variable key for this directory.
35$(call Set,DirKey,SubDir.$(subst .,,$(subst /,__,$(1))))
36$(call Append,SubDirKeys,$(DirKey))
37$(call Set,$(DirKey).Dir,$(Dir))
38
39# Reset subdirectory specific variables to sentinel value.
40$$(foreach var,$$(RequiredSubdirVariables) $$(OptionalSubdirVariables),\
41  $$(call Set,$$(var),UNDEFINED))
42
43# Get the subdirectory variables.
44include $(1)/Makefile.mk
45
46ifeq ($(DEBUGMAKE),2)
47$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\
48  $$(if $$(call strneq,UNDEFINED,$$($$(var))), \
49	$$(info MAKE: $(Dir): $$(var) is defined), \
50	$$(info MAKE: $(Dir): $$(var) is undefined)))
51endif
52
53# Check for undefined required variables, and unset sentinel value from optional
54# variables.
55$$(foreach var,$(RequiredSubdirVariables),\
56  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
57	$$(error $(Dir): variable '$$(var)' was not undefined)))
58$$(foreach var,$(OptionalSubdirVariables),\
59  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
60	$$(call Set,$$(var),)))
61
62# Collect all subdirectory variables for subsequent use.
63$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\
64  $$(call Set,$(DirKey).$$(var),$$($$(var))))
65
66# Recurse.
67include make/subdir.mk
68
69# Restore directory variable, for cleanliness.
70$$(call Set,Dir,$(1))
71
72ifneq ($(DEBUGMAKE),)
73  $$(info MAKE: $$(Dir): Done processing subdirectory)
74endif
75endef
76
77# Evaluate this now so we do not have to worry about order of evaluation.
78
79SubDirsList := $(strip \
80  $(if $(call streq,.,$(Dir)),\
81       $(SubDirs),\
82       $(SubDirs:%=$(Dir)/%)))
83ifeq ($(SubDirsList),)
84else
85  ifneq ($(DEBUGMAKE),)
86    $(info MAKE: Descending into subdirs: $(SubDirsList))
87  endif
88
89  $(foreach subdir,$(SubDirsList),\
90	$(eval $(call subdir_traverse_template,$(subdir))))
91endif
92