recurse.mk 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. ifndef INCLUDED_RULES_MK
  5. include $(topsrcdir)/config/rules.mk
  6. endif
  7. # The traditional model of directory traversal with make is as follows:
  8. # make -C foo
  9. # Entering foo
  10. # make -C bar
  11. # Entering foo/bar
  12. # make -C baz
  13. # Entering foo/baz
  14. # make -C qux
  15. # Entering qux
  16. #
  17. # Pseudo derecurse transforms the above into:
  18. # make -C foo
  19. # make -C foo/bar
  20. # make -C foo/baz
  21. # make -C qux
  22. ifeq (.,$(DEPTH))
  23. include root.mk
  24. # Main rules (export, compile, libs and tools) call recurse_* rules.
  25. # This wrapping is only really useful for build status.
  26. $(TIERS)::
  27. $(call BUILDSTATUS,TIER_START $@)
  28. +$(MAKE) recurse_$@
  29. $(call BUILDSTATUS,TIER_FINISH $@)
  30. # Special rule that does install-manifests (cf. Makefile.in) + compile
  31. binaries::
  32. +$(MAKE) recurse_compile
  33. # Carefully avoid $(eval) type of rule generation, which makes pymake slower
  34. # than necessary.
  35. # Get current tier and corresponding subtiers from the data in root.mk.
  36. CURRENT_TIER := $(filter $(foreach tier,$(TIERS),recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS))
  37. ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER))))
  38. $(error $(CURRENT_TIER) not supported on the same make command line)
  39. endif
  40. CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=))
  41. # The rules here are doing directory traversal, so we don't want further
  42. # recursion to happen when running make -C subdir $tier. But some make files
  43. # further call make -C something else, and sometimes expect recursion to
  44. # happen in that case.
  45. # Conveniently, every invocation of make increases MAKELEVEL, so only stop
  46. # recursion from happening at current MAKELEVEL + 1.
  47. ifdef CURRENT_TIER
  48. ifeq (0,$(MAKELEVEL))
  49. export NO_RECURSE_MAKELEVEL=1
  50. else
  51. 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)
  52. endif
  53. endif
  54. # Use the $(*_dirs) variables available in root.mk
  55. CURRENT_DIRS := $($(CURRENT_TIER)_dirs)
  56. # Need a list of compile targets because we can't use pattern rules:
  57. # https://savannah.gnu.org/bugs/index.php?42833
  58. # Only recurse the paths starting with RECURSE_BASE_DIR when provided.
  59. .PHONY: $(compile_targets)
  60. $(compile_targets):
  61. $(if $(filter $(RECURSE_BASE_DIR)%,$@),$(call SUBMAKE,$(@F),$(@D)))
  62. # The compile tier has different rules from other tiers.
  63. ifneq ($(CURRENT_TIER),compile)
  64. # Recursion rule for all directories traversed for all subtiers in the
  65. # current tier.
  66. $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
  67. $(call SUBMAKE,$(CURRENT_TIER),$*)
  68. .PHONY: $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS))
  69. # Dummy rules for possibly inexisting dependencies for the above tier targets
  70. $(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
  71. ifeq ($(CURRENT_TIER),export)
  72. # At least build/export requires config/export for buildid, but who knows what
  73. # else, so keep this global dependency to make config/export first for now.
  74. $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER)
  75. # The export tier requires nsinstall, which is built from config. So every
  76. # subdirectory traversal needs to happen after building nsinstall in config, which
  77. # is done with the config/host target. Note the config/host target only exists if
  78. # nsinstall is actually built, which it is not on Windows, because we use
  79. # nsinstall.py there.
  80. ifdef COMPILE_ENVIRONMENT
  81. ifneq (,$(filter config/host, $(compile_targets)))
  82. $(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): config/host
  83. endif
  84. endif
  85. endif
  86. endif # ifeq ($(CURRENT_TIER),compile)
  87. else
  88. # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above
  89. ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
  90. $(TIERS)::
  91. else
  92. #########################
  93. # Tier traversal handling
  94. #########################
  95. define CREATE_SUBTIER_TRAVERSAL_RULE
  96. .PHONY: $(1)
  97. $(1):: $$(SUBMAKEFILES)
  98. $$(LOOP_OVER_DIRS)
  99. endef
  100. $(foreach subtier,$(filter-out compile,$(TIERS)),$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
  101. ifndef TOPLEVEL_BUILD
  102. ifdef COMPILE_ENVIRONMENT
  103. compile::
  104. @$(MAKE) -C $(DEPTH) compile RECURSE_BASE_DIR=$(relativesrcdir)/
  105. endif # COMPILE_ENVIRONMENT
  106. endif
  107. endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
  108. endif # ifeq (.,$(DEPTH))
  109. recurse:
  110. @$(RECURSED_COMMAND)
  111. $(LOOP_OVER_DIRS)
  112. ifeq (.,$(DEPTH))
  113. # Interdependencies for parallel export.
  114. js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
  115. accessible/xpcom/export: xpcom/xpidl/export
  116. # The widget binding generator code is part of the annotationProcessors.
  117. widget/android/bindings/export: build/annotationProcessors/export
  118. # .xpt generation needs the xpidl lex/yacc files
  119. xpcom/xpidl/export: xpcom/idl-parser/xpidl/export
  120. # The roboextender addon includes a classes.dex containing a test Java addon.
  121. # The test addon must be built first.
  122. mobile/android/tests/browser/robocop/roboextender/tools: mobile/android/tests/javaaddons/tools
  123. ifdef ENABLE_CLANG_PLUGIN
  124. $(filter-out config/host build/unix/stdc++compat/% build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target
  125. build/clang-plugin/tests/target: build/clang-plugin/target
  126. endif
  127. # Interdependencies that moz.build world don't know about yet for compilation.
  128. # Note some others are hardcoded or "guessed" in recursivemake.py and emitter.py
  129. ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3)
  130. toolkit/library/target: widget/gtk/mozgtk/gtk3/target
  131. endif
  132. ifdef MOZ_LDAP_XPCOM
  133. ldap/target: config/external/nss/target mozglue/build/target
  134. toolkit/library/target: ldap/target
  135. endif
  136. ifeq ($(MOZ_REPLACE_MALLOC_LINKAGE),dummy library)
  137. mozglue/build/target memory/replace/logalloc/replay/target: memory/replace/dummy/target
  138. endif
  139. endif
  140. ifeq (,$(MOZ_FOLD_LIBS))
  141. config/external/nss/target: config/external/nspr/pr/target config/external/nspr/ds/target config/external/nspr/libc/target
  142. endif
  143. # Most things are built during compile (target/host), but some things happen during export
  144. # Those need to depend on config/export for system wrappers.
  145. $(addprefix build/unix/stdc++compat/,target host) build/clang-plugin/target: config/export