1# Input
2#
3# subdirs	tells the subdirectories to descend
4#
5# Output
6#
7# set     srcs gen-srcs
8# set     cflags-$(oname) cflags-remove-$(oname)
9#         cxxflags-$(oname) cxxflags-remove-$(oname)
10#         aflags-$(oname) aflags-remove-$(oname)
11#         cppflags-$(oname) cppflags-remove-$(oname)
12#         incdirs-$(oname)
13#         incdirs-lib$(libname)-$(sm)  [if libname is defined]
14#         cppflags-lib$(libname)-$(sm) [if libname is defined]
15#         cflags-lib$(libname)-$(sm)   [if libname is defined]
16#         cxxflags-lib$(libname)-$(sm) [if libname is defined]
17# for each file found, oname is the name of the object file for corresponding
18# source file
19
20srcs :=
21gen-srcs :=
22asm-defines-files :=
23
24uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
25
26define process-subdir-srcs-y
27ifeq ($$(sub-dir),.)
28srcs 				+= $1
29oname				:= $(out-dir)/$(base-prefix)$(basename $1).o
30else
31ifneq ($(filter /%,$(1)),)
32# $1 is an absolute path - start with "/"
33srcs 				+= $1
34oname				:= $(out-dir)/$(base-prefix)$(basename $1).o
35else
36srcs				+= $(sub-dir)/$1
37oname				:= $(out-dir)/$(base-prefix)$(basename $$(sub-dir)/$1).o
38endif
39endif
40cflags-$$(oname) 		:= $$(cflags-y) $$(cflags-$(1)-y)
41cflags-remove-$$(oname) 	:= $$(cflags-remove-y) \
42					$$(cflags-remove-$(1)-y)
43cxxflags-$$(oname) 		:= $$(cxxflags-y) $$(cxxflags-$(1)-y)
44cxxflags-remove-$$(oname) 	:= $$(cxxflags-remove-y) \
45					$$(cxxflags-remove-$(1)-y)
46cppflags-$$(oname) 		:= $$(cppflags-y) $$(cppflags-$(1)-y)
47cppflags-remove-$$(oname) 	:= $$(cppflags-remove-y) \
48					$$(cppflags-remove-$(1)-y)
49aflags-$$(oname) 		:= $$(aflags-y) $$(aflags-$(1)-y)
50aflags-remove-$$(oname) 	:= $$(aflags-remove-y) \
51					$$(aflags-remove-$(1)-y)
52incdirs-$$(oname)		:= $$(thissubdir-incdirs) $$(addprefix $(sub-dir)/,$$(incdirs-$(1)-y))
53# Clear local filename specific variables to avoid accidental reuse
54# in another subdirectory
55cflags-$(1)-y 			:=
56cflags-remove-$(1)-y		:=
57cflags-lib-y			:=
58cxxflags-$(1)-y 		:=
59cxxflags-remove-$(1)-y		:=
60cxxflags-lib-y			:=
61cppflags-$(1)-y			:=
62cppflags-remove-$(1)-y		:=
63cppflags-lib-y			:=
64aflags-$(1)-y 			:=
65aflags-remove-$(1)-y		:=
66incdirs-$(1)-y			:=
67fname				:=
68oname				:=
69endef #process-subdir-srcs-y
70
71define process-subdir-gensrcs-helper
72# $1 gensrc-y element
73# $2 full path and name of generated source file
74# $3 full path and name of object file compiled from source file
75# $4 full path to out directory
76# $5 y if $2 must be generated before $(sm) starts building (e.g., .h file)
77
78gen-srcs			+= $2
79cleanfiles			+= $2
80oname				:= $3
81
82FORCE-GENSRC$(sm): $(if $(filter y,$5),$2,)
83
84$$(addprefix $4,$$(produce-additional-$1)): $2
85
86subdir-$2 := $$(sub-dir)
87recipe-$2 := $$(recipe-$1)
88$2: $$(depends-$1)
89	@$(cmd-echo-silent) '  GEN     $2'
90	$(q)mkdir -p $4
91	$(q)$$(recipe-$2)
92
93cflags-$$(oname) 		:= $$(cflags-y) $$(cflags-$(1)-y)
94cflags-remove-$$(oname) 	:= $$(cflags-remove-y) \
95					$$(cflags-remove-$(1)-y)
96cxxflags-$$(oname) 		:= $$(cxxflags-y) $$(cxxflags-$(1)-y)
97cxxflags-remove-$$(oname) 	:= $$(cxxflags-remove-y) \
98					$$(cxxflags-remove-$(1)-y)
99cppflags-$$(oname) 		:= $$(cppflags-y) $$(cppflags-$(1)-y)
100cppflags-remove-$$(oname) 	:= $$(cppflags-remove-y) \
101					$$(cppflags-remove-$(1)-y)
102aflags-$$(oname) 		:= $$(aflags-y) $$(aflags-$(1)-y)
103aflags-remove-$$(oname) 	:= $$(aflags-remove-y) \
104					$$(aflags-remove-$(1)-y)
105incdirs-$$(oname)		:= $$(thissubdir-incdirs) $$(addprefix $(sub-dir)/,$$(incdirs-$(1)-y))
106# Clear local filename specific variables to avoid accidental reuse
107# in another subdirectory
108cflags-$(1)-y 			:=
109cflags-remove-$(1)-y		:=
110cflags-lib-y			:=
111cxxflags-$(1)-y 			:=
112cxxflags-remove-$(1)-y		:=
113cxxflags-lib-y			:=
114cppflags-$(1)-y			:=
115cppflags-remove-$(1)-y		:=
116cppflags-lib-y			:=
117aflags-$(1)-y 			:=
118aflags-remove-$(1)-y		:=
119incdirs-$(1)-y			:=
120fname				:=
121oname				:=
122
123endef #process-subdir-gensrcs-helper
124
125define process-subdir-gensrcs-y
126$$(eval $$(call process-subdir-gensrcs-helper,$1,$(sub-dir-out)/$$(produce-$1),$(sub-dir-out)/$(basename $(produce-$1)).o,$(sub-dir-out),$(force-gensrc-$1)))
127endef #process-subdir-gensrcs-y
128
129define process-subdir-asm-defines-y
130asm-defines-files += $(sub-dir)/$1
131endef #process-subdir-asm-defines-y
132
133define process-subdir
134sub-dir := $1
135ifeq ($1,.)
136sub-dir-out := $(patsubst %/,%,$(out-dir)/$(base-prefix))
137else
138sub-dir-out := $(out-dir)/$(base-prefix)$1
139endif
140
141include $1/sub.mk
142sub-subdirs := $$(addprefix $1/,$$(subdirs-y)) $$(subdirs_ext-y)
143incdirs$(sm) := $(incdirs$(sm)) $$(addprefix $1/,$$(global-incdirs-y))
144thissubdir-incdirs := $(out-dir)/$(base-prefix)$1 $$(addprefix $1/,$$(incdirs-y)) $$(incdirs_ext-y)
145ifneq ($$(libname),)
146incdirs-lib$$(libname)-$$(sm) := $$(incdirs-lib$$(libname)-$$(sm)) $$(addprefix $1/,$$(incdirs-lib-y))
147cflags-lib$$(libname)-$$(sm) := $$(cflags-lib$$(libname)-$$(sm)) $$(cflags-lib-y)
148cxxflags-lib$$(libname)-$$(sm) := $$(cxxflags-lib$$(libname)-$$(sm)) $$(cxxflags-lib-y)
149cppflags-lib$$(libname)-$$(sm) := $$(cppflags-lib$$(libname)-$$(sm)) $$(cppflags-lib-y)
150endif
151
152# Process files in current directory
153$$(foreach g, $$(gensrcs-y), $$(eval $$(call process-subdir-gensrcs-y,$$(g))))
154$$(foreach s, $$(srcs-y), $$(eval $$(call process-subdir-srcs-y,$$(s))))
155$$(foreach a, $$(asm-defines-y), $$(eval $$(call process-subdir-asm-defines-y,$$(a))))
156# Clear flags used when processing current directory
157srcs-y :=
158cflags-y :=
159cflags-lib-y :=
160cxxflags-y :=
161cxxflags-lib-y :=
162cppflags-y :=
163cppflags-lib-y :=
164aflags-y :=
165cflags-remove-y :=
166cxxflags-remove-y :=
167aflags-remove-y :=
168subdirs-y :=
169subdirs_ext-y :=
170global-incdirs-y :=
171incdirs-lib-y :=
172incdirs-y :=
173incdirs_ext-y :=
174gensrcs-y :=
175this-out-dir :=
176asm-defines-y :=
177
178# Process subdirectories in current directory
179$$(foreach sd, $$(call uniq,$$(sub-subdirs)), $$(eval $$(call process-subdir,$$(sd))))
180endef #process-subdir
181
182# Top subdirectories
183$(foreach sd, $(call uniq,$(subdirs)), $(eval $(call process-subdir,$(sd))))
184