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)