config/recurse.mk

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/config/recurse.mk	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,219 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 +# You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +ifndef INCLUDED_RULES_MK
     1.9 +include $(topsrcdir)/config/rules.mk
    1.10 +endif
    1.11 +
    1.12 +# The traditional model of directory traversal with make is as follows:
    1.13 +#   make -C foo
    1.14 +#     Entering foo
    1.15 +#     make -C bar
    1.16 +#       Entering foo/bar
    1.17 +#     make -C baz
    1.18 +#       Entering foo/baz
    1.19 +#   make -C qux
    1.20 +#     Entering qux
    1.21 +#
    1.22 +# Pseudo derecurse transforms the above into:
    1.23 +#   make -C foo
    1.24 +#   make -C foo/bar
    1.25 +#   make -C foo/baz
    1.26 +#   make -C qux
    1.27 +
    1.28 +# MOZ_PSEUDO_DERECURSE can have values other than 1.
    1.29 +ifeq (1_.,$(if $(MOZ_PSEUDO_DERECURSE),1)_$(DEPTH))
    1.30 +
    1.31 +include root.mk
    1.32 +
    1.33 +# Disable build status for mach in top directories without TIERS.
    1.34 +# In practice this disables it when recursing under js/src, which confuses mach.
    1.35 +ifndef TIERS
    1.36 +BUILDSTATUS =
    1.37 +endif
    1.38 +
    1.39 +# Main rules (export, compile, binaries, libs and tools) call recurse_* rules.
    1.40 +# This wrapping is only really useful for build status.
    1.41 +compile binaries libs export tools::
    1.42 +	$(call BUILDSTATUS,TIER_START $@)
    1.43 +	+$(MAKE) recurse_$@
    1.44 +	$(call BUILDSTATUS,TIER_FINISH $@)
    1.45 +
    1.46 +# Carefully avoid $(eval) type of rule generation, which makes pymake slower
    1.47 +# than necessary.
    1.48 +# Get current tier and corresponding subtiers from the data in root.mk.
    1.49 +CURRENT_TIER := $(filter $(foreach tier,compile binaries libs export tools,recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS))
    1.50 +ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER))))
    1.51 +$(error $(CURRENT_TIER) not supported on the same make command line)
    1.52 +endif
    1.53 +CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=))
    1.54 +CURRENT_SUBTIERS := $($(CURRENT_TIER)_subtiers)
    1.55 +
    1.56 +# The rules here are doing directory traversal, so we don't want further
    1.57 +# recursion to happen when running make -C subdir $tier. But some make files
    1.58 +# further call make -C something else, and sometimes expect recursion to
    1.59 +# happen in that case (see browser/metro/locales/Makefile.in for example).
    1.60 +# Conveniently, every invocation of make increases MAKELEVEL, so only stop
    1.61 +# recursion from happening at current MAKELEVEL + 1.
    1.62 +ifdef CURRENT_TIER
    1.63 +ifeq (0,$(MAKELEVEL))
    1.64 +export NO_RECURSE_MAKELEVEL=1
    1.65 +else
    1.66 +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)
    1.67 +endif
    1.68 +endif
    1.69 +
    1.70 +# Get all directories traversed for all subtiers in the current tier, or use
    1.71 +# directly the $(*_dirs) variables available in root.mk when there is no
    1.72 +# TIERS (like for js/src).
    1.73 +TIER_DIRS = $(or $($(1)_dirs),$(foreach subtier,$($(1)_subtiers),$($(1)_subtier_$(subtier))))
    1.74 +CURRENT_DIRS := $(call TIER_DIRS,$(CURRENT_TIER))
    1.75 +
    1.76 +ifneq (,$(filter binaries libs,$(CURRENT_TIER)))
    1.77 +WANT_STAMPS = 1
    1.78 +STAMP_TOUCH = $(TOUCH) $(@D)/binaries
    1.79 +endif
    1.80 +
    1.81 +# Subtier delimiter rules
    1.82 +$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start))
    1.83 +	@$(STAMP_TOUCH)
    1.84 +
    1.85 +$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish))
    1.86 +	@$(STAMP_TOUCH)
    1.87 +
    1.88 +$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%))
    1.89 +	@$(STAMP_TOUCH)
    1.90 +
    1.91 +GARBAGE_DIRS += subtiers
    1.92 +
    1.93 +# Recursion rule for all directories traversed for all subtiers in the
    1.94 +# current tier.
    1.95 +# root.mk defines subtier_of_* variables, that map a normalized subdir path to
    1.96 +# a subtier name (e.g. subtier_of_memory_jemalloc = base)
    1.97 +$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
    1.98 +	+@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER))
    1.99 +# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one.
   1.100 +	$(if $(wildcard $@),@$(STAMP_TOUCH))
   1.101 +
   1.102 +# Dummy rules for possibly inexisting dependencies for the above tier targets
   1.103 +$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
   1.104 +
   1.105 +# The export tier requires nsinstall, which is built from config. So every
   1.106 +# subdirectory traversal needs to happen after traversing config.
   1.107 +ifeq ($(CURRENT_TIER),export)
   1.108 +$(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER)
   1.109 +endif
   1.110 +
   1.111 +ifdef COMPILE_ENVIRONMENT
   1.112 +ifneq (,$(filter libs binaries,$(CURRENT_TIER)))
   1.113 +# When doing a "libs" build, target_libs.mk ensures the interesting dependency data
   1.114 +# is available in the "binaries" stamp. Once recursion is done, aggregate all that
   1.115 +# dependency info so that stamps depend on relevant files and relevant other stamps.
   1.116 +# When doing a "binaries" build, the aggregate dependency file and those stamps are
   1.117 +# used and allow to skip recursing directories where changes are not going to require
   1.118 +# rebuild. A few directories, however, are still traversed all the time, mostly, the
   1.119 +# gyp managed ones and js/src.
   1.120 +# A few things that are not traversed by a "binaries" build, but should, in an ideal
   1.121 +# world, are nspr, nss, icu and ffi.
   1.122 +recurse_$(CURRENT_TIER):
   1.123 +	@$(MAKE) binaries-deps
   1.124 +
   1.125 +# Creating binaries-deps.mk directly would make us build it twice: once when beginning
   1.126 +# the build because of the include, and once at the end because of the stamps.
   1.127 +binaries-deps: $(addsuffix /binaries,$(CURRENT_DIRS))
   1.128 +	@$(call py_action,link_deps,-o $@.mk --group-by-depfile --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) --guard $(addprefix ',$(addsuffix ',$^)))
   1.129 +	@$(TOUCH) $@
   1.130 +
   1.131 +ifeq (recurse_binaries,$(MAKECMDGOALS))
   1.132 +$(call include_deps,binaries-deps.mk)
   1.133 +endif
   1.134 +
   1.135 +endif
   1.136 +
   1.137 +DIST_GARBAGE += binaries-deps.mk binaries-deps
   1.138 +
   1.139 +endif
   1.140 +
   1.141 +else
   1.142 +
   1.143 +# Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above
   1.144 +ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
   1.145 +
   1.146 +compile binaries libs export tools::
   1.147 +
   1.148 +else
   1.149 +#########################
   1.150 +# Tier traversal handling
   1.151 +#########################
   1.152 +
   1.153 +ifdef TIERS
   1.154 +
   1.155 +libs export tools::
   1.156 +	$(call BUILDSTATUS,TIER_START $@)
   1.157 +	$(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
   1.158 +		$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
   1.159 +		$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@))))
   1.160 +	$(call BUILDSTATUS,TIER_FINISH $@)
   1.161 +
   1.162 +else
   1.163 +
   1.164 +define CREATE_SUBTIER_TRAVERSAL_RULE
   1.165 +PARALLEL_DIRS_$(1) = $$(addsuffix _$(1),$$(PARALLEL_DIRS))
   1.166 +
   1.167 +.PHONY: $(1) $$(PARALLEL_DIRS_$(1))
   1.168 +
   1.169 +ifdef PARALLEL_DIRS
   1.170 +$$(PARALLEL_DIRS_$(1)): %_$(1): %/Makefile
   1.171 +	+@$$(call SUBMAKE,$(1),$$*)
   1.172 +endif
   1.173 +
   1.174 +$(1):: $$(SUBMAKEFILES)
   1.175 +ifdef PARALLEL_DIRS
   1.176 +	+@$(MAKE) $$(PARALLEL_DIRS_$(1))
   1.177 +endif
   1.178 +	$$(LOOP_OVER_DIRS)
   1.179 +
   1.180 +endef
   1.181 +
   1.182 +$(foreach subtier,export compile binaries libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
   1.183 +
   1.184 +tools export:: $(SUBMAKEFILES)
   1.185 +	$(LOOP_OVER_TOOL_DIRS)
   1.186 +
   1.187 +endif # ifdef TIERS
   1.188 +
   1.189 +endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
   1.190 +
   1.191 +endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))
   1.192 +
   1.193 +ifdef MOZ_PSEUDO_DERECURSE
   1.194 +
   1.195 +ifdef COMPILE_ENVIRONMENT
   1.196 +
   1.197 +# Aggregate all dependency files relevant to a binaries build except in
   1.198 +# the mozilla top-level directory.
   1.199 +ifneq (.,$(DEPTH))
   1.200 +ALL_DEP_FILES := \
   1.201 +  $(BINARIES_PP) \
   1.202 +  $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
   1.203 +    $(TARGETS) \
   1.204 +    $(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
   1.205 +  ))) \
   1.206 +  $(NULL)
   1.207 +endif
   1.208 +
   1.209 +binaries libs:: $(TARGETS) $(BINARIES_PP)
   1.210 +ifneq (.,$(DEPTH))
   1.211 +	@$(if $^,$(call py_action,link_deps,-o binaries --group-all --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
   1.212 +endif
   1.213 +
   1.214 +endif
   1.215 +
   1.216 +endif # ifdef MOZ_PSEUDO_DERECURSE
   1.217 +
   1.218 +recurse:
   1.219 +	@$(RECURSED_COMMAND)
   1.220 +	$(LOOP_OVER_PARALLEL_DIRS)
   1.221 +	$(LOOP_OVER_DIRS)
   1.222 +	$(LOOP_OVER_TOOL_DIRS)

mercurial