DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (27a812186ff4)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

ifndef INCLUDED_RULES_MK
include $(topsrcdir)/config/rules.mk
endif

# The traditional model of directory traversal with make is as follows:
#   make -C foo
#     Entering foo
#     make -C bar
#       Entering foo/bar
#     make -C baz
#       Entering foo/baz
#   make -C qux
#     Entering qux
#
# Pseudo derecurse transforms the above into:
#   make -C foo
#   make -C foo/bar
#   make -C foo/baz
#   make -C qux

# MOZ_PSEUDO_DERECURSE can have values other than 1.
ifeq (1_.,$(if $(MOZ_PSEUDO_DERECURSE),1)_$(DEPTH))

include root.mk

# Disable build status for mach in top directories without TIERS.
# In practice this disables it when recursing under js/src, which confuses mach.
ifndef TIERS
BUILDSTATUS =
endif

# Main rules (export, compile, binaries, libs and tools) call recurse_* rules.
# This wrapping is only really useful for build status.
compile binaries libs export tools::
	$(call BUILDSTATUS,TIER_START $@ $($@_subtiers))
	+$(MAKE) recurse_$@
	$(call BUILDSTATUS,TIER_FINISH $@)

# Carefully avoid $(eval) type of rule generation, which makes pymake slower
# than necessary.
# Get current tier and corresponding subtiers from the data in root.mk.
CURRENT_TIER := $(filter $(foreach tier,compile binaries libs export tools,recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS))
ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER))))
$(error $(CURRENT_TIER) not supported on the same make command line)
endif
CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=))
CURRENT_SUBTIERS := $($(CURRENT_TIER)_subtiers)

# The rules here are doing directory traversal, so we don't want further
# recursion to happen when running make -C subdir $tier. But some make files
# further call make -C something else, and sometimes expect recursion to
# happen in that case (see browser/metro/locales/Makefile.in for example).
# Conveniently, every invocation of make increases MAKELEVEL, so only stop
# recursion from happening at current MAKELEVEL + 1.
ifdef CURRENT_TIER
ifeq (0,$(MAKELEVEL))
export NO_RECURSE_MAKELEVEL=1
else
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)
endif
endif

# Get all directories traversed for all subtiers in the current tier, or use
# directly the $(*_dirs) variables available in root.mk when there is no
# TIERS (like for js/src).
TIER_DIRS = $(or $($(1)_dirs),$(foreach subtier,$($(1)_subtiers),$($(1)_subtier_$(subtier))))
CURRENT_DIRS := $(call TIER_DIRS,$(CURRENT_TIER))

ifneq (,$(filter binaries libs,$(CURRENT_TIER)))
WANT_STAMPS = 1
STAMP_TOUCH = $(TOUCH) $(@D)/binaries
endif

# Subtier delimiter rules
$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start))
	$(call BUILDSTATUS,SUBTIER_START $(CURRENT_TIER) $* $(if $(BUG_915535_FIXED),$($(CURRENT_TIER)_subtier_$*)))
	@$(STAMP_TOUCH)

$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish))
	$(call BUILDSTATUS,SUBTIER_FINISH $(CURRENT_TIER) $*)
	@$(STAMP_TOUCH)

$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%))
	@$(STAMP_TOUCH)

GARBAGE_DIRS += subtiers

# Recursion rule for all directories traversed for all subtiers in the
# current tier.
# root.mk defines subtier_of_* variables, that map a normalized subdir path to
# a subtier name (e.g. subtier_of_memory_jemalloc = base)
$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
ifdef BUG_915535_FIXED
	$(call BUILDSTATUS,TIERDIR_START $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
endif
	+@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER))
# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one.
	$(if $(wildcard $@),@$(STAMP_TOUCH))
ifdef BUG_915535_FIXED
	$(call BUILDSTATUS,TIERDIR_FINISH $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
endif

# Dummy rules for possibly inexisting dependencies for the above tier targets
$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):

# The export tier requires nsinstall, which is built from config. So every
# subdirectory traversal needs to happen after traversing config.
ifeq ($(CURRENT_TIER),export)
$(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER)
endif

ifdef COMPILE_ENVIRONMENT
ifneq (,$(filter libs binaries,$(CURRENT_TIER)))
# When doing a "libs" build, target_libs.mk ensures the interesting dependency data
# is available in the "binaries" stamp. Once recursion is done, aggregate all that
# dependency info so that stamps depend on relevant files and relevant other stamps.
# When doing a "binaries" build, the aggregate dependency file and those stamps are
# used and allow to skip recursing directories where changes are not going to require
# rebuild. A few directories, however, are still traversed all the time, mostly, the
# gyp managed ones and js/src.
# A few things that are not traversed by a "binaries" build, but should, in an ideal
# world, are nspr, nss, icu and ffi.
recurse_$(CURRENT_TIER):
	@$(MAKE) binaries-deps

# Creating binaries-deps.mk directly would make us build it twice: once when beginning
# the build because of the include, and once at the end because of the stamps.
binaries-deps: $(addsuffix /binaries,$(CURRENT_DIRS))
	@$(call py_action,link_deps,-o $@.mk --group-by-depfile --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) --guard $(addprefix ',$(addsuffix ',$^)))
	@$(TOUCH) $@

ifeq (recurse_binaries,$(MAKECMDGOALS))
$(call include_deps,binaries-deps.mk)
endif

endif

DIST_GARBAGE += binaries-deps.mk binaries-deps

endif

else

# Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above
ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))

compile binaries libs export tools::

else
#########################
# Tier traversal handling
#########################

ifdef TIERS

libs export tools::
	$(call BUILDSTATUS,TIER_START $@ $(filter-out $(if $(filter export,$@),,precompile),$(TIERS)))
	$(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
		$(call BUILDSTATUS,SUBTIER_START $@ $(tier) $(if $(filter libs,$@),$(tier_$(tier)_staticdirs)) $(tier_$(tier)_dirs)) \
		$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
		$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@)) \
		$(call BUILDSTATUS,SUBTIER_FINISH $@ $(tier))))
	$(call BUILDSTATUS,TIER_FINISH $@)

else

define CREATE_SUBTIER_TRAVERSAL_RULE
PARALLEL_DIRS_$(1) = $$(addsuffix _$(1),$$(PARALLEL_DIRS))

.PHONY: $(1) $$(PARALLEL_DIRS_$(1))

ifdef PARALLEL_DIRS
$$(PARALLEL_DIRS_$(1)): %_$(1): %/Makefile
	+@$$(call SUBMAKE,$(1),$$*)
endif

$(1):: $$(SUBMAKEFILES)
ifdef PARALLEL_DIRS
	+@$(MAKE) $$(PARALLEL_DIRS_$(1))
endif
	$$(LOOP_OVER_DIRS)

endef

$(foreach subtier,export compile binaries libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))

tools export:: $(SUBMAKEFILES)
	$(LOOP_OVER_TOOL_DIRS)

endif # ifdef TIERS

endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))

endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))

ifdef MOZ_PSEUDO_DERECURSE
ifeq (.,$(DEPTH))
# top-level directories
ifndef JS_STANDALONE
# Only define recurse_targets for js, when it is built as part of gecko.
recurse_targets := $(addsuffix /binaries,$(call TIER_DIRS,binaries))
# we want to adjust paths for js/src.
want_abspaths = 1
endif
endif

ifdef COMPILE_ENVIRONMENT

# Aggregate all dependency files relevant to a binaries build except in
# the mozilla top-level directory.
ifneq (_.,$(recurse_targets)_$(DEPTH))
ALL_DEP_FILES := \
  $(BINARIES_PP) \
  $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
    $(TARGETS) \
    $(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
  ))) \
  $(recurse_targets) \
  $(NULL)
endif

binaries libs:: $(TARGETS) $(BINARIES_PP)
ifneq (_.,$(recurse_targets)_$(DEPTH))
	@$(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)))
endif

endif

endif # ifdef MOZ_PSEUDO_DERECURSE

recurse:
	@$(RECURSED_COMMAND)
	$(LOOP_OVER_PARALLEL_DIRS)
	$(LOOP_OVER_DIRS)
	$(LOOP_OVER_TOOL_DIRS)