Index: /trunk/kBuild/footer.kmk
===================================================================
--- /trunk/kBuild/footer.kmk	(revision 1666)
+++ /trunk/kBuild/footer.kmk	(revision 1667)
@@ -3166,4 +3166,50 @@
 #
 
+#
+# First, check whether we need to order the passes explicitly or not.
+# This depends on whether we're a leaf makefile or not. A leaf will
+# know all its dependencies, while a recursive one relies on the
+# order sub-directories and other makefiles are executed it.
+#
+
+## Setup a pass and check for optimizations.
+# @param	$(PASS)		Uppercase pass name.
+define def_pass_setup_and_optimize
+
+# The setup. ## @todo This is looks a bit weird...
+ifndef SUBDIRS_$(PASS)
+ SUBDIRS_$(PASS)          := $(SUBDIRS)          $(SUBDIRS.$(KBUILD_TARGET))          $(SUBDIRS.$(KBUILD_TARGET.$(KBUILD_TARGET_ARCH)))
+endif
+ifndef SUBDIRS_AFTER_$(PASS)
+ SUBDIRS_AFTER_$(PASS)    := $(SUBDIRS_AFTER)    $(SUBDIRS_AFTER.$(KBUILD_TARGET))    $(SUBDIRS_AFTER.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))
+endif
+ifndef MAKEFILES_BEFORE_$(PASS)
+ MAKEFILES_BEFORE_$(PASS) := $(MAKEFILES_BEFORE) $(MAKEFILES_BEFORE.$(KBUILD_TARGET)) $(MAKEFILES_BEFORE.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))
+endif
+ifndef MAKEFILES_AFTER_$(PASS)
+ MAKEFILES_AFTER_$(PASS)  := $(MAKEFILES_AFTER)  $(MAKEFILES_AFTER.$(KBUILD_TARGET))  $(MAKEFILES_AFTER.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))
+endif
+
+# The check.
+ifeq ($(_KBUILD_STRICT_PASS_ORDER),nonstrict)
+ ifneq ($(strip \
+          $(SUBDIRS_$(PASS))          $(SUBDIRS_$(PASS).$(KBUILD_TARGET))          $(SUBDIRS_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))           \
+          $(MAKEFILES_BEFORE_$(PASS)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))  \
+          $(SUBDIRS_AFTER_$(PASS))    $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET))    $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))     \
+          $(MAKEFILES_AFTER_$(PASS))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))   \
+         ),)
+  _KBUILD_STRICT_PASS_ORDER := strict
+ endif
+endif # _KBUILD_STRICT_PASS_ORDER == nonstrict
+endef # def_pass_setup_and_optimize
+
+## PASS: Setup & optimization.
+# Check if we can apply the non-strict pass order optimzation (no SUBDIRS_* and MAKEFILES_*),
+# and set up the pass specific variables as we go along.
+_KBUILD_STRICT_PASS_ORDER := nonstrict
+$(foreach PASS, $(PASSES), $(evalval def_pass_setup_and_optimize))
+#$ (error _KBUILD_STRICT_PASS_ORDER=$(_KBUILD_STRICT_PASS_ORDER))
+
+
 ## Subdir
 # @param	$(pass)		Lowercase pass name.
@@ -3179,5 +3225,5 @@
 # @param	$(pass)		Lowercase pass name.
 # @param	$(PASS)		Uppercase pass name.
-# @param	$(makefile) Makefile.
+# @param	$(makefile)	Makefile.
 # @param	$(tag)		tag to attach to the rule name.
 define def_pass_makefile
@@ -3186,60 +3232,29 @@
 endef
 
-## Execute a pass.
+## Execute a pass, strict order.
 # @param	$(pass)		Lowercase pass name.
 # @param	$(PASS)		Uppercase pass name.
-define def_pass_old
-$(eval SUBDIRS_$(PASS)          ?= $(SUBDIRS)          $(SUBDIRS.$(KBUILD_TARGET))           $(SUBDIRS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))          )
-$(eval SUBDIRS_AFTER_$(PASS)    ?= $(SUBDIRS_AFTER)    $(SUBDIRS_AFTER.$(KBUILD_TARGET))     $(SUBDIRS_AFTER.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))    )
-$(eval MAKEFILES_BEFORE_$(PASS) ?= $(MAKEFILES_BEFORE) $(MAKEFILES_BEFORE.$(KBUILD_TARGET))  $(MAKEFILES_BEFORE.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) )
-$(eval MAKEFILES_AFTER_$(PASS)  ?= $(MAKEFILES_AFTER)  $(MAKEFILES_AFTER.$(KBUILD_TARGET))   $(MAKEFILES_AFTER.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))  )
-
+define def_pass_strict
 $(eval tag:=_before)
 $(eval dep:=)
-$(foreach subdir,$(SUBDIRS_$(PASS))            $(SUBDIRS_$(PASS).$(KBUILD_TARGET))           $(SUBDIRS_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))         ,$(eval $(def_pass_subdir)))
-$(foreach makefile,$(MAKEFILES_BEFORE_$(PASS)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET))  $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)),$(eval $(def_pass_makefile)))
+$(foreach subdir,  $(SUBDIRS_$(PASS))          $(SUBDIRS_$(PASS).$(KBUILD_TARGET))          $(SUBDIRS_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))         ,$(eval $(def_pass_subdir)))
+$(foreach makefile,$(MAKEFILES_BEFORE_$(PASS)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)),$(eval $(def_pass_makefile)))
 
 $(eval tag:=_after)
 $(eval dep:=pass_$(pass)_doit)
-$(foreach subdir,$(SUBDIRS_AFTER_$(PASS))      $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET))     $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))   ,$(eval $(def_pass_subdir)))
-$(foreach makefile,$(MAKEFILES_AFTER_$(PASS))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET))   $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) ,$(eval $(def_pass_makefile)))
-
-.NOTPARALLEL: pass_$(pass)_before pass_$(pass)_after
-.PHONY: pass_$(pass) pass_$(pass)_before pass_$(pass)_doit pass_$(pass)_after
-pass_$(pass)_doit: 	$(PASS_$(PASS)_trgs) $(foreach var,$(PASS_$(PASS)_vars),$(var))
+$(foreach subdir,  $(SUBDIRS_AFTER_$(PASS))    $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET))    $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))   ,$(eval $(def_pass_subdir)))
+$(foreach makefile,$(MAKEFILES_AFTER_$(PASS))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) ,$(eval $(def_pass_makefile)))
+
+ifdef KBUILD_SAFE_PARALLEL
+.NOTPARALLEL: pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_this
+.PHONY:       pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_this pass_$(pass)_doit
+pass_$(pass)_doit:      $(PASS_$(PASS)_trgs) $(foreach var,$(PASS_$(PASS)_vars),$(var))
 pass_$(pass)_this:      pass_$(pass)_before
 	+ $$(QUIET)$$(MAKE) -f $$(MAKEFILE) pass_$(pass)_doit
 pass_$(pass)_after::    pass_$(pass)_this
 pass_$(pass):           pass_$(pass)_after
-
-endef
-
-define def_pass
-$(eval SUBDIRS_$(PASS)          ?= $(SUBDIRS)          $(SUBDIRS.$(KBUILD_TARGET))          $(SUBDIRS.$(KBUILD_TARGET.$(KBUILD_TARGET_ARCH)))          )
-$(eval SUBDIRS_AFTER_$(PASS)    ?= $(SUBDIRS_AFTER)    $(SUBDIRS_AFTER.$(KBUILD_TARGET))    $(SUBDIRS_AFTER.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))    )
-$(eval MAKEFILES_BEFORE_$(PASS) ?= $(MAKEFILES_BEFORE) $(MAKEFILES_BEFORE.$(KBUILD_TARGET)) $(MAKEFILES_BEFORE.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) )
-$(eval MAKEFILES_AFTER_$(PASS)  ?= $(MAKEFILES_AFTER)  $(MAKEFILES_AFTER.$(KBUILD_TARGET))  $(MAKEFILES_AFTER.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))  )
-
-$(eval tag:=_before)
-$(eval dep:=)
-$(foreach subdir,$(SUBDIRS_$(PASS))            $(SUBDIRS_$(PASS).$(KBUILD_TARGET))          $(SUBDIRS_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))         ,$(eval $(def_pass_subdir)))
-$(foreach makefile,$(MAKEFILES_BEFORE_$(PASS)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET)) $(MAKEFILES_BEFORE_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)),$(eval $(def_pass_makefile)))
-
-$(eval tag:=_after)
-$(eval dep:=pass_$(pass)_doit)
-$(foreach subdir,$(SUBDIRS_AFTER_$(PASS))      $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET))    $(SUBDIRS_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))   ,$(eval $(def_pass_subdir)))
-$(foreach makefile,$(MAKEFILES_AFTER_$(PASS))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET))  $(MAKEFILES_AFTER_$(PASS).$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) ,$(eval $(def_pass_makefile)))
-
-ifdef KBUILD_SAFE_PARALLEL
-.NOTPARALLEL: pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_this
-.PHONY:       pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_this pass_$(pass)_doit
-pass_$(pass)_doit: 	    $(PASS_$(PASS)_trgs) $(foreach var,$(PASS_$(PASS)_vars),$(var))
-pass_$(pass)_this:      pass_$(pass)_before
-	+ $$(QUIET)$$(MAKE) -f $$(MAKEFILE) pass_$(pass)_doit
-pass_$(pass)_after::    pass_$(pass)_this
-pass_$(pass):           pass_$(pass)_after
-else
+else  # !KBUILD_SAFE_PARALLEL
+.PHONY:       pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_doit
 .NOTPARALLEL: pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_doit
-.PHONY:       pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_doit
 pass_$(pass)_doit: pass_$(pass)_before \
 		$(PASS_$(PASS)_trgs) $(foreach var,$(PASS_$(PASS)_vars),$($(var)))
@@ -3247,26 +3262,37 @@
 		pass_$(pass)_before \
 		pass_$(pass)_doit \
-        pass_$(pass)_after
-endif
+		pass_$(pass)_after
+endif # !KBUILD_SAFE_PARALLEL
 
 #$ (warning pass=$(pass) PASS=$(PASS): $(PASS_$(PASS)_trgs) $(PASS_$(PASS)_trgs) $(foreach var,$(PASS_$(PASS)_vars),$($(var))))
-endef
-
-# Generate the defined passes.
+endef # def_pass_strict
+
+## Execute a pass, non-strict pass ordering.
+# @param	$(pass)		Lowercase pass name.
+# @param	$(PASS)		Uppercase pass name.
+define def_pass_nonstrict
+.PHONY:       pass_$(pass) pass_$(pass)_before pass_$(pass)_after pass_$(pass)_doit
+pass_$(pass)_doit: $(PASS_$(PASS)_trgs) $(foreach var,$(PASS_$(PASS)_vars),$($(var)))
+pass_$(pass):	pass_$(pass)_doit
+endef # def_pass_nonstrict
+
+## PASS: rules
+# Generate the rules for the defined passes.
 $(foreach PASS, $(PASSES), \
 	$(eval pass := $(PASS_$(PASS)_pass)) \
-	$(eval $(def_pass)))
-
-## Pass order
+	$(eval $(def_pass_$(_KBUILD_STRICT_PASS_ORDER))))
+
+
+## Pass order, strict.
 # @param	$(pass)		Current pass name.
 # @param	$(prev_pass)	The previous pass name.
-define def_pass_order
+define def_pass_order_strict
 ifdef KBUILD_SAFE_PARALLEL
+.PHONY:       pass_$(pass)_order
 .NOTPARALLEL: pass_$(pass)_order
-.PHONY: pass_$(pass)_order
 pass_$(pass)_order: $(pass_prev)
 	%$$(call MSG_PASS,$$(if $$(PASS_$(PASS)),$$(PASS_$(PASS)),$(pass)))
 	+ $$(QUIET)$$(MAKE) -f $$(MAKEFILE) pass_$(pass)
-else
+else  # !KBUILD_SAFE_PARALLEL
 .NOTPARALLEL: pass_$(pass)_order pass_$(pass)_banner
 .PHONY:       pass_$(pass)_order pass_$(pass)_banner
@@ -3277,7 +3303,21 @@
 		pass_$(pass)_banner \
 		pass_$(pass)
-endif
+endif # !KBUILD_SAFE_PARALLEL
 $(eval pass_prev := pass_$(pass)_order)
-endef
+endef # def_pass_order_strict
+
+## Pass order, non-strict.
+# @param	$(pass)		Current pass name.
+# @param	$(prev_pass)	The previous pass name.
+define def_pass_order_nonstrict
+.PHONY:       pass_$(pass)_order pass_$(pass)_banner
+pass_$(pass)_banner:
+	%$$(call MSG_PASS,$$(if $$(PASS_$(PASS)),$$(PASS_$(PASS)),$(pass)))
+pass_$(pass)_order: \
+		$(pass_prev) \
+		pass_$(pass)_banner \
+		pass_$(pass)
+$(eval pass_prev := pass_$(pass)_order)
+endef # def_pass_order_nonstrict
 
 ## PASS: order
@@ -3286,5 +3326,5 @@
 $(foreach PASS,$(DEFAULT_PASSES),\
 	$(eval pass := $(PASS_$(PASS)_pass)) \
-	$(eval $(def_pass_order)))
+	$(eval $(def_pass_order_$(_KBUILD_STRICT_PASS_ORDER))))
 
 ifdef KBUILD_PROFILE_SELF
@@ -3326,4 +3366,5 @@
 # kBuild debugging stuff.
 #
+## @todo this doesn't work. Move to a debug unit and expand it.
 show_targets:
 	@$(foreach target, $(_ALL_TARGETS),\
