recurse.mk (8330B)
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/. 4 5 ifndef INCLUDED_RULES_MK 6 include $(topsrcdir)/config/rules.mk 7 endif 8 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 18 # 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 24 25 ifeq (.,$(DEPTH)) 26 27 include root.mk 28 29 # Main rules (export, compile, libs and tools) call recurse_* rules. 30 # This wrapping is only really useful for build status. 31 $(RUNNABLE_TIERS):: 32 $(if $(filter $@,$(MAKECMDGOALS)),$(call BUILDSTATUS,TIERS $@),) 33 $(call BUILDSTATUS,TIER_START $@) 34 +$(MAKE) recurse_$@ 35 $(call BUILDSTATUS,TIER_FINISH $@) 36 37 # Special rule that does install-manifests (cf. Makefile.in) + compile 38 binaries:: 39 +$(MAKE) recurse_compile 40 41 # Get current tier and corresponding subtiers from the data in root.mk. 42 CURRENT_TIER := $(filter $(foreach tier,$(RUNNABLE_TIERS) $(non_default_tiers),recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS)) 43 ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER)))) 44 $(error $(CURRENT_TIER) not supported on the same make command line) 45 endif 46 CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=)) 47 48 # The rules here are doing directory traversal, so we don't want further 49 # recursion to happen when running make -C subdir $tier. But some make files 50 # further call make -C something else, and sometimes expect recursion to 51 # happen in that case. 52 # Conveniently, every invocation of make increases MAKELEVEL, so only stop 53 # recursion from happening at current MAKELEVEL + 1. 54 ifdef CURRENT_TIER 55 ifeq (0,$(MAKELEVEL)) 56 export NO_RECURSE_MAKELEVEL=1 57 else 58 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) 59 endif 60 endif 61 62 RECURSE = $(if $(RECURSE_TRACE_ONLY),@echo $2/$1,$(call SUBMAKE,$1,$2)) 63 64 # Use the $(*_dirs) variables available in root.mk 65 CURRENT_DIRS := $($(CURRENT_TIER)_dirs) 66 67 # Need a list of compile targets because we can't use pattern rules: 68 # https://savannah.gnu.org/bugs/index.php?42833 69 # Only recurse the paths starting with RECURSE_BASE_DIR when provided. 70 .PHONY: $(pre_compile_targets) $(compile_targets) $(syms_targets) 71 $(pre_compile_targets) $(compile_targets) $(syms_targets): 72 $(if $(filter $(RECURSE_BASE_DIR)%,$@),$(call RECURSE,$(@F),$(@D))) 73 74 $(syms_targets): %/syms: %/target 75 76 # Only hook symbols targets into the main compile graph in automation. 77 ifdef MOZ_AUTOMATION 78 ifeq (1,$(MOZ_AUTOMATION_BUILD_SYMBOLS)) 79 recurse_compile: $(syms_targets) 80 endif 81 endif 82 83 # Create a separate rule that depends on every 'syms' target so that 84 # symbols can be dumped on demand locally. 85 .PHONY: recurse_syms 86 recurse_syms: $(syms_targets) 87 88 # The compile tier has different rules from other tiers. 89 ifneq ($(CURRENT_TIER),compile) 90 91 # Recursion rule for all directories traversed for all subtiers in the 92 # current tier. 93 $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER): 94 $(call RECURSE,$(CURRENT_TIER),$*) 95 96 .PHONY: $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)) 97 98 # Dummy rules for possibly inexisting dependencies for the above tier targets 99 $(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)): 100 101 ifeq ($(CURRENT_TIER),export) 102 # At least build/export requires config/export for buildid, but who knows what 103 # else, so keep this global dependency to make config/export first for now. 104 $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER) 105 106 # The export tier requires nsinstall, which is built from config. So every 107 # subdirectory traversal needs to happen after building nsinstall in config, which 108 # is done with the config/host target. Note the config/host target only exists if 109 # nsinstall is actually built, which it is not on Windows, because we use 110 # nsinstall.py there. 111 ifdef COMPILE_ENVIRONMENT 112 ifneq (,$(filter config/host, $(compile_targets))) 113 $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): config/host 114 endif 115 endif 116 endif 117 118 endif # ifeq ($(CURRENT_TIER),compile) 119 120 else 121 122 # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above 123 ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL)) 124 125 $(RUNNABLE_TIERS):: 126 127 else 128 ######################### 129 # Tier traversal handling 130 ######################### 131 132 define CREATE_SUBTIER_TRAVERSAL_RULE 133 .PHONY: $(1) 134 135 $(1):: $$(SUBMAKEFILES) 136 $$(LOOP_OVER_DIRS) 137 138 endef 139 140 $(foreach subtier,$(filter-out compile,$(RUNNABLE_TIERS)),$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier)))) 141 142 ifndef TOPLEVEL_BUILD 143 ifdef COMPILE_ENVIRONMENT 144 compile:: 145 @$(MAKE) -C $(DEPTH) compile RECURSE_BASE_DIR=$(relativesrcdir)/ 146 endif # COMPILE_ENVIRONMENT 147 endif 148 149 endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL)) 150 151 endif # ifeq (.,$(DEPTH)) 152 153 recurse: 154 @$(RECURSED_COMMAND) 155 $(LOOP_OVER_DIRS) 156 157 ifeq (.,$(DEPTH)) 158 159 # This is required so that the pre-export tier sees the rules in 160 # mobile/android 161 ifeq ($(MOZ_WIDGET_TOOLKIT),android) 162 recurse_pre-export: mobile/android/pre-export 163 endif 164 165 # CSS2Properties.webidl needs ServoCSSPropList.py from layout/style 166 dom/bindings/export: layout/style/ServoCSSPropList.py 167 168 # Various telemetry histogram files need ServoCSSPropList.py from layout/style 169 toolkit/components/telemetry/export: layout/style/ServoCSSPropList.py 170 171 ifeq ($(TARGET_ENDIANNESS),big) 172 config/external/icu/data/target-objects: config/external/icu/data/$(MDDEPDIR)/icudt$(MOZ_ICU_VERSION)b.dat.stub 173 config/external/icu/data/$(MDDEPDIR)/icudt$(MOZ_ICU_VERSION)b.dat.stub: config/external/icu/icupkg/host 174 endif 175 176 ifdef ENABLE_CLANG_PLUGIN 177 # Only target rules use the clang plugin. 178 $(filter %/target %/target-objects,$(filter-out config/export config/host build/unix/stdc++compat/% build/clang-plugin/%,$(compile_targets))) security/rlbox/pre-compile media/libsoundtouch/src/pre-compile: build/clang-plugin/host build/clang-plugin/tests/target-objects 179 build/clang-plugin/tests/target-objects: build/clang-plugin/host 180 # clang-plugin tests require js-confdefs.h on js standalone builds and mozilla-config.h on 181 # other builds, because they are -include'd. 182 ifdef JS_STANDALONE 183 # The js/src/export target only exists when CURRENT_TIER is export. If we're in a later tier, 184 # we can assume js/src/export has happened anyways. 185 ifeq ($(CURRENT_TIER),export) 186 build/clang-plugin/tests/target-objects: js/src/export 187 endif 188 else 189 build/clang-plugin/tests/target-objects: mozilla-config.h 190 endif 191 endif 192 193 # Interdependencies that moz.build world don't know about yet for compilation. 194 # Note some others are hardcoded or "guessed" in recursivemake.py and emitter.py 195 ifdef MOZ_USING_WASM_SANDBOXING 196 dom/media/ogg/target-objects extensions/spellcheck/hunspell/glue/target-objects gfx/thebes/target-objects parser/expat/target-objects parser/htmlparser/target-objects gfx/ots/src/target-objects: security/rlbox/pre-compile 197 dom/media/target-objects dom/media/mediasink/target-objects: media/libsoundtouch/src/pre-compile 198 endif 199 200 # Most things are built during compile (target/host), but some things happen during export 201 # Those need to depend on config/export for system wrappers. 202 $(addprefix build/unix/stdc++compat/,target host) build/clang-plugin/host: config/export 203 204 # Rust targets, and export targets that run cbindgen need 205 # $topobjdir/.cargo/config.toml to be preprocessed first. Ideally, we'd only set it 206 # as a dependency of the rust targets, but unfortunately, that pushes Make to 207 # execute them much later than we'd like them to be when the file doesn't exist 208 # prior to Make running. So we also set it as a dependency of pre-export, which 209 # ensures it exists before recursing the rust targets and the export targets 210 # that run cbindgen, tricking Make into keeping them early. 211 # When $topobjdir/.cargo/config exists from an old build, we also remove it because 212 # cargo will prefer to use it rather than config.toml. 213 CARGO_CONFIG_DEPS = $(DEPTH)/.cargo/config.toml 214 ifneq (,$(wildcard $(DEPTH)/.cargo/config)) 215 CARGO_CONFIG_DEPS += $(MDDEPDIR)/cargo-config-cleanup.stub 216 endif 217 $(rust_targets): $(CARGO_CONFIG_DEPS) 218 ifndef TEST_MOZBUILD 219 recurse_pre-export: $(CARGO_CONFIG_DEPS) 220 endif 221 222 $(MDDEPDIR)/cargo-config-cleanup.stub: 223 rm $(DEPTH)/.cargo/config 224 touch $@ 225 endif