Index: /trunk/kBuild/footer-pass2-compiling-targets.kmk
===================================================================
--- /trunk/kBuild/footer-pass2-compiling-targets.kmk	(revision 3277)
+++ /trunk/kBuild/footer-pass2-compiling-targets.kmk	(revision 3278)
@@ -37,5 +37,77 @@
 #
 
-## wrapper the compile command dependency check.
+ifndef NO_COMPILE_CMDS_DEPS
+ ## Generates the rules for building a specific object and the aliases.
+ # for building a source file.
+ # @param    $(obj)    The object file.
+ define def_target_source_rule_v3plus
+$$(obj): .MUST_MAKE = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_CMDS_PREV_),$$(commands $$@),FORCE)
+$$(obj) + $$(kbsrc_output) +| $$(kbsrc_output_maybe) : $$(kbsrc_depend) | $$(kbsrc_depord) $(target_intermediate_vars)
+	%$$(call MSG_COMPILE,$(target),$(source),$$@,$(type))
+  ifndef TOOL_$(tool)_COMPILE_$(type)_DONT_PURGE_OUTPUT
+	$$(QUIET)$$(RM) -f -- $(dep) $(obj) $(kbsrc_output) $(kbsrc_output_maybe)
+  endif
+
+$(kbsrc_cmds)
+
+	%$$(QUIET2)$$(APPEND) -in '$(dep)' '' 'define $(target)_$(subst :,_,$(source))_CMDS_PREV_' '--insert-command=$(obj)' 'endef'
+$$(basename $$(notdir $$(obj))).o: $$(obj)
+ endef # def_target_source_rule_v3plus
+
+ ## Generates the rules for building a specific object and the aliases, kObjCache variant.
+ # for building a source file.
+ # @param    $(obj)    The object file.
+ define def_target_source_rule_v3plus_objcache
+$$(obj): .MUST_MAKE = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_CMDS_PREV_),$$(commands $$@),FORCE)
+_OUT_FILES += $(outbase).koc
+$$(outbase).koc +| $$(obj) $$(kbsrc_output) $$(kbsrc_output_maybe) : $$(kbsrc_depend) | $$(kbsrc_depord) $(target_intermediate_vars)
+	%$$(call MSG_COMPILE,$(target),$(source),$$@,$(type))
+
+$(kbsrc_cmds)
+
+	%$$(QUIET2)$$(APPEND) -in '$(dep)' '' 'define $(target)_$(subst :,_,$(source))_CMDS_PREV_' '--insert-command=$(obj)' 'endef'
+$$(basename $$(notdir $$(obj))).o: $$(obj)
+ endef # def_target_source_rule_v3plus_objcache
+
+else # NO_COMPILE_CMDS_DEPS
+
+ ## Generates the rules for building a specific object and the aliases.
+ # for building a source file.
+ # @param    $(obj)    The object file.
+ define def_target_source_rule_v3plus
+$$(obj) + $$(kbsrc_output) +| $$(kbsrc_output_maybe) : $$(kbsrc_depend) | $$(kbsrc_depord) $(target_intermediate_vars)
+	%$$(call MSG_COMPILE,$(target),$(source),$$@,$(type))
+  ifndef TOOL_$(tool)_COMPILE_$(type)_DONT_PURGE_OUTPUT
+	$$(QUIET)$$(RM) -f -- $(dep) $(obj) $(kbsrc_output) $(kbsrc_output_maybe)
+  endif
+
+$(kbsrc_cmds)
+
+$$(basename $$(notdir $$(obj))).o: $$(obj)
+ endef # def_target_source_rule_v3plus
+
+ ## Generates the rules for building a specific object and the aliases, kObjCache variant.
+ # for building a source file.
+ # @param    $(obj)    The object file.
+ define def_target_source_rule_v3plus_objcache
+_OUT_FILES += $(outbase).koc
+$(outbase).koc +| $(obj) $(kbsrc_output) $(kbsrc_output_maybe) : $(kbsrc_depend) | $(kbsrc_depord) $(target_intermediate_vars)
+	%$$(call MSG_COMPILE,$(target),$(source),$$@,$(type))
+
+$(kbsrc_cmds)
+
+$$(basename $$(notdir $$(obj))).o: $$(obj)
+ endef # def_target_source_rule_v3plus_objcache
+
+endif # NO_COMPILE_CMDS_DEPS
+$(eval-opt-var def_target_source_rule_v3plus)
+$(eval-opt-var def_target_source_rule_v3plus_objcache)
+
+
+##
+## Legacy legacy legacy - start
+##
+
+## Wrapper
 ifndef NO_COMPILE_CMDS_DEPS
  if1of ($(KMK_FEATURES),dot-must-make)
@@ -49,6 +121,5 @@
 endif
 
-
-## Generates the rules for building a specific object, and the aliases
+## Generates the rules for building a specific object, and the aliases - legacy version.
 # for building a source file.
 # @param    $(obj)    The object file.
@@ -60,27 +131,11 @@
 _OUT_FILES += $(outbase).koc
 $(outbase).koc +| $(obj) $($(target)_$(source)_OUTPUT_) $($(target)_$(source)_OUTPUT_MAYBE_) : \
-		$($(target)_$(source)_DEPEND_) \
-		$(value _DEP_COMPILE_CMDS) \
-		| \
-		$($(target)_$(source)_DEPORD_) \
-		$$$$($(target)_INTERMEDIATES) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg).$(bld_trg_arch)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg_arch)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg_cpu)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_type))
+		$($(target)_$(source)_DEPEND_) $(value _DEP_COMPILE_CMDS) \
+		| $($(target)_$(source)_DEPORD_) $(target_intermediate_vars)
 	%$$(call MSG_COMPILE,$(target),$(source),$$@,$(type))
 else
 $(obj) + $($(target)_$(source)_OUTPUT_) +| $($(target)_$(source)_OUTPUT_MAYBE_) : \
-		$($(target)_$(source)_DEPEND_) \
-		$(value _DEP_COMPILE_CMDS) \
-		| \
-		$($(target)_$(source)_DEPORD_) \
-		$$$$($(target)_INTERMEDIATES) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg).$(bld_trg_arch)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg_arch)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_trg_cpu)) \
-		$$$$($(target)_INTERMEDIATES.$(bld_type))
+		$($(target)_$(source)_DEPEND_) $(value _DEP_COMPILE_CMDS)
+		| $($(target)_$(source)_DEPORD_) $(target_intermediate_vars)
 	%$$(call MSG_COMPILE,$(target),$(source),$$@,$(type))
 ifndef TOOL_$(tool)_COMPILE_$(type)_DONT_PURGE_OUTPUT
@@ -106,5 +161,4 @@
 
 $(basename $(notdir $(obj))).o: $(obj)
-$(basename $(notdir $(obj))).obj: $(obj)
 
 ## @todo make this 'local cmds,output,output_maybe,depend and depord' in 0.2.x or when a new kb-src-one is added.
@@ -116,4 +170,7 @@
 endef # def_target_source_rule
 $(eval-opt-var def_target_source_rule)
+##
+## Legacy legacy legacy - end
+
 
 
@@ -213,30 +270,30 @@
 define def_src_handler_c
 local type := C
- $(kb-src-one 2)
+ $(kb-src-one 3)
 endef
 
 define def_src_handler_cxx
 local type := CXX
- $(kb-src-one 2)
+ $(kb-src-one 3)
 endef
 
 define def_src_handler_objc
 local type := OBJC
- $(kb-src-one 2)
+ $(kb-src-one 3)
 endef
 
 define def_src_handler_objcxx
 local type := OBJCXX
- $(kb-src-one 2)
+ $(kb-src-one 3)
 endef
 
 define def_src_handler_asm
 local type := AS
- $(kb-src-one 2)
+ $(kb-src-one 3)
 endef
 
 define def_src_handler_rc
 local type := RC
- $(kb-src-one 2)
+ $(kb-src-one 3)
 endef
 
@@ -490,4 +547,25 @@
 $(target)_2_OBJS  :=
 
+# kObjCache.
+ifdef KBUILD_USE_KOBJCACHE
+ ifneq ($($(target)_KOBJCACHE),)
+local use_objcache := 1
+ else
+local use_objcache :=
+ endif
+local use_objcache :=
+endif
+
+# target level intermediates
+local target_intermediate_vars := $(foreach var, \
+	$(target)_INTERMEDIATES \
+	$(target)_INTERMEDIATES.$(bld_trg) \
+	$(target)_INTERMEDIATES.$(bld_trg).$(bld_trg_arch) \
+	$(target)_INTERMEDIATES.$(bld_trg_arch) \
+	$(target)_INTERMEDIATES.$(bld_trg_cpu) \
+	$(target)_INTERMEDIATES.$(bld_type) \
+	,$(if-expr defined($(var)),$$$$($(var)),))
+#$(info target_intermediate_vars=$(target_intermediate_vars))
+
 # Do units pre source callouts.
 local units       := \
@@ -499,14 +577,4 @@
 $(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre))
 $(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre_2))
-
-# kObjCache.
-ifdef KBUILD_USE_KOBJCACHE
- ifneq ($($(target)_KOBJCACHE),)
-local use_objcache := 1
- else
-local use_objcache :=
- endif
-local use_objcache :=
-endif
 
 # source -> object
@@ -705,4 +773,25 @@
 $(target)_2_OBJS  :=
 
+# kObjCache.
+ifdef KBUILD_USE_KOBJCACHE
+ ifneq ($($(target)_KOBJCACHE),)
+local use_objcache := 1
+ else
+local use_objcache :=
+ endif
+local use_objcache :=
+endif
+
+# target level intermediates
+local target_intermediate_vars := $(foreach var, \
+	$(target)_INTERMEDIATES \
+	$(target)_INTERMEDIATES.$(bld_trg) \
+	$(target)_INTERMEDIATES.$(bld_trg).$(bld_trg_arch) \
+	$(target)_INTERMEDIATES.$(bld_trg_arch) \
+	$(target)_INTERMEDIATES.$(bld_trg_cpu) \
+	$(target)_INTERMEDIATES.$(bld_type) \
+	,$(if-expr defined($(var)),$$$$($(var)),))
+#$(info target_intermediate_vars=$(target_intermediate_vars))
+
 # Do units pre source callouts.
 local units       := \
@@ -714,14 +803,4 @@
 $(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre))
 $(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre_2))
-
-# kObjCache.
-ifdef KBUILD_USE_KOBJCACHE
- ifneq ($($(target)_KOBJCACHE),)
-local use_objcache := 1
- else
-local use_objcache :=
- endif
-local use_objcache :=
-endif
 
 # source -> object
Index: /trunk/src/kmk/kbuild.c
===================================================================
--- /trunk/src/kmk/kbuild.c	(revision 3277)
+++ /trunk/src/kmk/kbuild.c	(revision 3278)
@@ -2007,5 +2007,5 @@
 #endif
     struct variable *pObj       = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
-    int fInstallOldVars = 0;
+    int fInstallOldObjsVar = 0;
     char *pszDstVar, *pszDst, *pszSrcVar, *pszSrc, *pszVal, *psz;
     char *pszSavedVarBuf;
@@ -2123,5 +2123,5 @@
     /** @todo Make all these local variables, if someone needs the info later it
      *        can be recalculated. (Ticket #80.) */
-    cch = sizeof("TOOL_") + pTool->value_length + sizeof("_COMPILE_") + pType->value_length + sizeof("_OUTPUT_MAYBE");
+    cch = sizeof("TOOL_") + pTool->value_length + sizeof("_COMPILE_") + pType->value_length + sizeof("_USES_KOBJCACHE");
     if (cch < pTarget->value_length + sizeof("$(_2_OBJS)"))
         cch = pTarget->value_length + sizeof("$(_2_OBJS)");
@@ -2143,6 +2143,7 @@
     memcpy(pszDst, "_CMDS_", sizeof("_CMDS_"));
     pVar = kbuild_get_recursive_variable(pszSrcVar);
-    do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
-                             !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
+    if (iVer <= 2)
+        do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
+                                 !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
     do_variable_definition_2(NILF, "kbsrc_cmds", pVar->value, pVar->value_length,
                              !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
@@ -2151,6 +2152,7 @@
     memcpy(pszDst, "_OUTPUT_", sizeof("_OUTPUT_"));
     pVar = kbuild_get_recursive_variable(pszSrcVar);
-    pOutput = do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
-                                       !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
+    if (iVer <= 2)
+        pOutput = do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
+                                           !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
     pOutput = do_variable_definition_2(NILF, "kbsrc_output", pVar->value, pVar->value_length,
                                        !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
@@ -2161,6 +2163,7 @@
     if (pVar)
     {
-        pOutputMaybe = do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
-                                                !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
+        if (iVer <= 2)
+            pOutputMaybe = do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
+                                                    !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
         pOutputMaybe = do_variable_definition_2(NILF, "kbsrc_output_maybe", pVar->value, pVar->value_length,
                                                 !pVar->recursive, 0, o_local, f_simple, 0 /* !target_var */);
@@ -2168,5 +2171,6 @@
     else
     {
-        pOutputMaybe = do_variable_definition_2(NILF, pszDstVar, "", 0, 1, 0, o_local, f_simple, 0 /* !target_var */);
+        if (iVer <= 2)
+            pOutputMaybe = do_variable_definition_2(NILF, pszDstVar, "", 0, 1, 0, o_local, f_simple, 0 /* !target_var */);
         pOutputMaybe = do_variable_definition_2(NILF, "kbsrc_output_maybe", "", 0, 1, 0, o_local, f_simple, 0 /* !target_var */);
     }
@@ -2181,7 +2185,8 @@
     *psz++ = ' ';
     memcpy(psz, pSource->value, pSource->value_length + 1);
-    do_variable_definition_2(NILF, pszDstVar, pszVal, pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length,
-                             !pVar->recursive && !pDeps->recursive && !pSource->recursive,
-                             NULL, o_local, f_simple, 0 /* !target_var */);
+    if (iVer <= 2)
+        do_variable_definition_2(NILF, pszDstVar, pszVal, pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length,
+                                 !pVar->recursive && !pDeps->recursive && !pSource->recursive,
+                                 NULL, o_local, f_simple, 0 /* !target_var */);
     do_variable_definition_2(NILF, "kbsrc_depend", pszVal, pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length,
                              !pVar->recursive && !pDeps->recursive && !pSource->recursive,
@@ -2197,8 +2202,9 @@
     *psz++ = ' ';
     memcpy(psz, pOrderDeps->value, pOrderDeps->value_length + 1);
-    do_variable_definition_2(NILF, pszDstVar, pszVal,
-                             pVar->value_length + 1 + pDirDep->value_length + 1 + pOrderDeps->value_length,
-                             !pVar->recursive && !pDirDep->recursive && !pOrderDeps->recursive,
-                             NULL, o_local, f_simple, 0 /* !target_var */);
+    if (iVer <= 2)
+        do_variable_definition_2(NILF, pszDstVar, pszVal,
+                                 pVar->value_length + 1 + pDirDep->value_length + 1 + pOrderDeps->value_length,
+                                 !pVar->recursive && !pDirDep->recursive && !pOrderDeps->recursive,
+                                 NULL, o_local, f_simple, 0 /* !target_var */);
     do_variable_definition_2(NILF, "kbsrc_depord", pszVal,
                              pVar->value_length + 1 + pDirDep->value_length + 1 + pOrderDeps->value_length,
@@ -2219,5 +2225,5 @@
     memcpy(pszDstVar + pTarget->value_length, "_2_OBJS", sizeof("_2_OBJS"));
     pVar = kbuild_query_recursive_variable_n(pszDstVar, pTarget->value_length + sizeof("_2_OBJS") - 1);
-    fInstallOldVars |= iVer <= 2 && (!pVar || !pVar->value_length);
+    fInstallOldObjsVar |= iVer <= 2 && (!pVar || !pVar->value_length);
     if (pVar)
     {
@@ -2235,7 +2241,7 @@
 
     /*
-     * Install legacy variables.
-     */
-    if (fInstallOldVars)
+     * Install legacy variable.
+     */
+    if (fInstallOldObjsVar)
     {
         /* $(target)_OBJS_ = $($(target)_2_OBJS)*/
@@ -2259,6 +2265,31 @@
     $(eval $(def_target_source_rule))
     */
-    pVar = kbuild_get_recursive_variable("def_target_source_rule");
-    pszVal = variable_expand_string_2 (o, pVar->value, pVar->value_length, &psz);
+    if (iVer > 2)
+    {
+        /*ifneq ($(TOOL_$(tool)_COMPILE_$(type)_USES_KOBJCACHE),)*/
+        int fUsesObjCache = 0;
+        memcpy(pszSrc, "_USES_KOBJCACHE", sizeof("_USES_KOBJCACHE"));
+        pVar = lookup_variable(pszSrcVar, pszSrc + sizeof("_USES_KOBJCACHE") - 1 - pszSrcVar);
+        if (pVar)
+        {
+            if (   !pVar->recursive
+                || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar))
+                fUsesObjCache = pVar->value_length > 0;
+            else
+            {
+                unsigned int cchTmp = 0;
+                char *pszTmp = allocated_variable_expand_2(pVar->value, pVar->value_length, &cchTmp);
+                free(pszTmp);
+                fUsesObjCache = cchTmp > 0;
+            }
+        }
+        if (!fUsesObjCache)
+            pVar = kbuild_get_recursive_variable("def_target_source_rule_v3plus");
+        else
+            pVar = kbuild_get_recursive_variable("def_target_source_rule_v3plus_objcache");
+    }
+    else
+        pVar = kbuild_get_recursive_variable("def_target_source_rule");
+    pszVal = variable_expand_string_2(o, pVar->value, pVar->value_length, &psz);
     assert(!((size_t)pszVal & 3));
 
