Backed out changeset 838f865fa1c7 (bug 933231) for bustage on some platforms.
[gecko.git] / config / recurse.mk
blob07dfa9d51e2874bc6988418c9fecb38af822e0f8
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 # You can obtain one at http://mozilla.org/MPL/2.0/.
5 ifndef INCLUDED_RULES_MK
6 include $(topsrcdir)/config/rules.mk
7 endif
9 # The traditional model of directory traversal with make is as follows:
10 # make -C foo
11 # Entering foo
12 # make -C bar
13 # Entering foo/bar
14 # make -C baz
15 # Entering foo/baz
16 # make -C qux
17 # Entering qux
19 # Pseudo derecurse transforms the above into:
20 # make -C foo
21 # make -C foo/bar
22 # make -C foo/baz
23 # make -C qux
25 # MOZ_PSEUDO_DERECURSE can have values other than 1.
26 ifeq (1_.,$(if $(MOZ_PSEUDO_DERECURSE),1)_$(DEPTH))
28 include root.mk
30 # Disable build status for mach in top directories without TIERS.
31 # In practice this disables it when recursing under js/src, which confuses mach.
32 ifndef TIERS
33 BUILDSTATUS =
34 endif
36 # Main rules (export, compile, binaries, libs and tools) call recurse_* rules.
37 # This wrapping is only really useful for build status.
38 compile binaries libs export tools::
39 $(call BUILDSTATUS,TIER_START $@ $($@_subtiers))
40 +$(MAKE) recurse_$@
41 $(call BUILDSTATUS,TIER_FINISH $@)
43 # Carefully avoid $(eval) type of rule generation, which makes pymake slower
44 # than necessary.
45 # Get current tier and corresponding subtiers from the data in root.mk.
46 CURRENT_TIER := $(filter $(foreach tier,compile binaries libs export tools,recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS))
47 ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER))))
48 $(error $(CURRENT_TIER) not supported on the same make command line)
49 endif
50 CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=))
51 CURRENT_SUBTIERS := $($(CURRENT_TIER)_subtiers)
53 # The rules here are doing directory traversal, so we don't want further
54 # recursion to happen when running make -C subdir $tier. But some make files
55 # further call make -C something else, and sometimes expect recursion to
56 # happen in that case (see browser/metro/locales/Makefile.in for example).
57 # Conveniently, every invocation of make increases MAKELEVEL, so only stop
58 # recursion from happening at current MAKELEVEL + 1.
59 ifdef CURRENT_TIER
60 ifeq (0,$(MAKELEVEL))
61 export NO_RECURSE_MAKELEVEL=1
62 else
63 export NO_RECURSE_MAKELEVEL=$(word $(MAKELEVEL),2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
64 endif
65 endif
67 # Get all directories traversed for all subtiers in the current tier, or use
68 # directly the $(*_dirs) variables available in root.mk when there is no
69 # TIERS (like for js/src).
70 CURRENT_DIRS := $(or $($(CURRENT_TIER)_dirs),$(foreach subtier,$(CURRENT_SUBTIERS),$($(CURRENT_TIER)_subtier_$(subtier))))
72 ifneq (,$(filter binaries libs,$(CURRENT_TIER)))
73 WANT_STAMPS = 1
74 STAMP_TOUCH = $(TOUCH) $(@D)/binaries
75 endif
77 # Subtier delimiter rules
78 $(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start))
79 $(call BUILDSTATUS,SUBTIER_START $(CURRENT_TIER) $* $(if $(BUG_915535_FIXED),$($(CURRENT_TIER)_subtier_$*)))
80 @$(STAMP_TOUCH)
82 $(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish))
83 $(call BUILDSTATUS,SUBTIER_FINISH $(CURRENT_TIER) $*)
84 @$(STAMP_TOUCH)
86 $(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%))
87 @$(STAMP_TOUCH)
89 GARBAGE_DIRS += subtiers
91 # Recursion rule for all directories traversed for all subtiers in the
92 # current tier.
93 # root.mk defines subtier_of_* variables, that map a normalized subdir path to
94 # a subtier name (e.g. subtier_of_memory_jemalloc = base)
95 $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
96 ifdef BUG_915535_FIXED
97 $(call BUILDSTATUS,TIERDIR_START $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
98 endif
99 +@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER))
100 # Ensure existing stamps are up-to-date, but don't create one if submake didn't create one.
101 $(if $(wildcard $@),@$(STAMP_TOUCH))
102 ifdef BUG_915535_FIXED
103 $(call BUILDSTATUS,TIERDIR_FINISH $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
104 endif
106 # Dummy rules for possibly inexisting dependencies for the above tier targets
107 $(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
109 # The export tier requires nsinstall, which is built from config. So every
110 # subdirectory traversal needs to happen after traversing config.
111 ifeq ($(CURRENT_TIER),export)
112 $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER)
113 endif
115 ifdef COMPILE_ENVIRONMENT
116 ifneq (,$(filter libs binaries,$(CURRENT_TIER)))
117 # When doing a "libs" build, target_libs.mk ensures the interesting dependency data
118 # is available in the "binaries" stamp. Once recursion is done, aggregate all that
119 # dependency info so that stamps depend on relevant files and relevant other stamps.
120 # When doing a "binaries" build, the aggregate dependency file and those stamps are
121 # used and allow to skip recursing directories where changes are not going to require
122 # rebuild. A few directories, however, are still traversed all the time, mostly, the
123 # gyp managed ones and js/src.
124 # A few things that are not traversed by a "binaries" build, but should, in an ideal
125 # world, are nspr, nss, icu and ffi.
126 recurse_$(CURRENT_TIER):
127 @$(MAKE) binaries-deps
129 # Creating binaries-deps.mk directly would make us build it twice: once when beginning
130 # the build because of the include, and once at the end because of the stamps.
131 binaries-deps: $(addsuffix /binaries,$(CURRENT_DIRS))
132 @$(call py_action,link_deps,-o $@.mk --group-by-depfile --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) --guard $(addprefix ',$(addsuffix ',$^)))
133 @$(TOUCH) $@
135 ifeq (recurse_binaries,$(MAKECMDGOALS))
136 $(call include_deps,binaries-deps.mk)
137 endif
139 endif
141 DIST_GARBAGE += binaries-deps.mk binaries-deps
143 endif
145 else
147 # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above, but
148 # still recurse for externally managed make files (gyp-generated ones).
149 ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL))
151 compile binaries libs export tools::
153 else
154 #########################
155 # Tier traversal handling
156 #########################
158 ifdef TIERS
160 libs export tools::
161 $(call BUILDSTATUS,TIER_START $@ $(filter-out $(if $(filter export,$@),,precompile),$(TIERS)))
162 $(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
163 $(call BUILDSTATUS,SUBTIER_START $@ $(tier) $(if $(filter libs,$@),$(tier_$(tier)_staticdirs)) $(tier_$(tier)_dirs)) \
164 $(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
165 $(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@)) \
166 $(call BUILDSTATUS,SUBTIER_FINISH $@ $(tier))))
167 $(call BUILDSTATUS,TIER_FINISH $@)
169 else
171 define CREATE_SUBTIER_TRAVERSAL_RULE
172 PARALLEL_DIRS_$(1) = $$(addsuffix _$(1),$$(PARALLEL_DIRS))
174 .PHONY: $(1) $$(PARALLEL_DIRS_$(1))
176 ifdef PARALLEL_DIRS
177 $$(PARALLEL_DIRS_$(1)): %_$(1): %/Makefile
178 +@$$(call SUBMAKE,$(1),$$*)
179 endif
181 $(1):: $$(SUBMAKEFILES)
182 ifdef PARALLEL_DIRS
183 +@$(MAKE) $$(PARALLEL_DIRS_$(1))
184 endif
185 $$(LOOP_OVER_DIRS)
187 endef
189 $(foreach subtier,export compile binaries libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
191 tools export:: $(SUBMAKEFILES)
192 $(LOOP_OVER_TOOL_DIRS)
194 endif # ifdef TIERS
196 endif # ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL))
198 endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))
200 ifdef MOZ_PSEUDO_DERECURSE
201 ifdef EXTERNALLY_MANAGED_MAKE_FILE
202 # gyp-managed directories
203 recurse_targets := $(addsuffix /binaries,$(DIRS) $(PARALLEL_DIRS))
204 else
205 ifeq (.,$(DEPTH))
206 # top-level directories
207 recurse_targets := $(addsuffix /binaries,$(binaries_dirs))
208 ifdef recurse_targets
209 # only js/src has binaries_dirs, and we want to adjust paths for it.
210 want_abspaths = 1
211 endif
212 endif
213 endif
215 ifdef COMPILE_ENVIRONMENT
217 # Aggregate all dependency files relevant to a binaries build except in
218 # the mozilla top-level directory.
219 ifneq (_.,$(recurse_targets)_$(DEPTH))
220 ALL_DEP_FILES := \
221 $(BINARIES_PP) \
222 $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
223 $(TARGETS) \
224 $(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
225 ))) \
226 $(recurse_targets) \
227 $(NULL)
228 endif
230 binaries libs:: $(TARGETS) $(BINARIES_PP)
231 ifneq (_.,$(recurse_targets)_$(DEPTH))
232 @$(if $(or $(recurse_targets),$^),$(call py_action,link_deps,-o binaries --group-all $(if $(want_abspaths),--abspaths )--topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
233 endif
235 endif
237 endif # ifdef MOZ_PSEUDO_DERECURSE
239 recurse:
240 @$(RECURSED_COMMAND)
241 $(LOOP_OVER_PARALLEL_DIRS)
242 $(LOOP_OVER_DIRS)
243 $(LOOP_OVER_TOOL_DIRS)