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
9 # The traditional model of directory traversal with make is as follows:
19 # Pseudo derecurse transforms the above into:
25 # MOZ_PSEUDO_DERECURSE can have values other than 1.
26 ifeq (1_.
,$(if
$(MOZ_PSEUDO_DERECURSE
),1)_
$(DEPTH
))
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.
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
))
41 $(call BUILDSTATUS
,TIER_FINISH
$@
)
43 # Carefully avoid $(eval) type of rule generation, which makes pymake slower
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
)
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.
61 export NO_RECURSE_MAKELEVEL
=1
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)
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
)))
74 STAMP_TOUCH
= $(TOUCH
) $(@D
)/binaries
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_
$*)))
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
) $*)
86 $(addprefix subtiers
/,$(addsuffix /$(CURRENT_TIER
),$(CURRENT_SUBTIERS
))): %/$(CURRENT_TIER
): $(if
$(WANT_STAMPS
),$(call mkdir_deps
,%))
89 GARBAGE_DIRS
+= subtiers
91 # Recursion rule for all directories traversed for all subtiers in the
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 /,_
,$*)) $*)
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 /,_
,$*)) $*)
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
)
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 ',$^
)))
135 ifeq (recurse_binaries
,$(MAKECMDGOALS
))
136 $(call include_deps
,binaries-deps.mk
)
141 DIST_GARBAGE
+= binaries-deps.mk binaries-deps
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
::
154 #########################
155 # Tier traversal handling
156 #########################
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
$@
)
171 define CREATE_SUBTIER_TRAVERSAL_RULE
172 PARALLEL_DIRS_
$(1) = $$(addsuffix _
$(1),$$(PARALLEL_DIRS
))
174 .PHONY
: $(1) $$(PARALLEL_DIRS_
$(1))
177 $$(PARALLEL_DIRS_
$(1)): %_
$(1): %/Makefile
178 +@
$$(call SUBMAKE
,$(1),$$*)
181 $(1):: $$(SUBMAKEFILES
)
183 +@
$(MAKE
) $$(PARALLEL_DIRS_
$(1))
189 $(foreach subtier
,export compile binaries libs tools
,$(eval
$(call CREATE_SUBTIER_TRAVERSAL_RULE
,$(subtier
))))
191 tools
export:: $(SUBMAKEFILES
)
192 $(LOOP_OVER_TOOL_DIRS
)
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
))
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.
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
))
222 $(addsuffix .pp
,$(addprefix $(MDDEPDIR
)/,$(sort \
224 $(filter-out $(SOBJS
) $(ASOBJS
) $(EXCLUDED_OBJS
),$(OBJ_TARGETS
)) \
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
)))
237 endif # ifdef MOZ_PSEUDO_DERECURSE
241 $(LOOP_OVER_PARALLEL_DIRS
)
243 $(LOOP_OVER_TOOL_DIRS
)