Index: trunk/kBuild/footer.kmk
===================================================================
--- trunk/kBuild/footer.kmk	(revision 724)
+++ trunk/kBuild/footer.kmk	(revision 725)
@@ -185,4 +185,13 @@
 no-root-slash=$(patsubst /%,%,$(1))
 
+ifneq ($(filter abspathex,$(KMK_FEATURES)),abspathex) ## @todo Retire this to gnumake-header.kmk when it has been implemented.
+## Converts an relative path to an absolute path using the given CWD.
+# @returns absolute path.
+# @param    $1      The path to fixup.
+# @param    $2      The CWD to use.
+abspathex = $(foreach _fix_path,$1\
+,$(if $(subst :$(call no-root-slash,$(call no-drive,$(_fix_path))):,,:$(_fix_path):),$(_fix_path),$(abspath $2/$(_fix_path))))
+endif
+
 ## Figure out where to put object files.
 # @param    $1      source file
@@ -1127,5 +1136,30 @@
 ## Generic macro for processing all target sources.
 # @param    $(target)   Normalized target name.
+# @param    $(defpath)
+# @param    much-more...
 define def_target_sources
+
+# Apply any default path on the sources first.
+ifneq ($(defpath),)
+ ifdef $(target)_SOURCES
+  $(target)_SOURCES := $(call abspathex,$($(target)_SOURCES),$(defpath))
+ endif
+ ifdef $(target)_SOURCES.$(bld_trg)
+  $(target)_SOURCES.$(bld_trg) := $(call abspathex,$($(target)_SOURCES.$(bld_trg)),$(defpath))
+ endif
+ ifdef $(target)_SOURCES.$(bld_trg).$(bld_trg_arch)
+  $(target)_SOURCES.$(bld_trg).$(bld_trg_arch) := $(call abspathex,$($(target)_SOURCES.$(bld_trg).$(bld_trg_arch)),$(defpath))
+ endif
+ ifdef $(target)_SOURCES.$(bld_trg_arch)
+  $(target)_SOURCES.$(bld_trg_arch) := $(call abspathex,$($(target)_SOURCES.$(bld_trg_arch)),$(defpath))
+ endif
+ ifdef $(target)_SOURCES.$(bld_trg_cpu)
+  $(target)_SOURCES.$(bld_trg_cpu) := $(call abspathex,$($(target)_SOURCES.$(bld_trg_cpu)),$(defpath))
+ endif
+ ifdef $(target)_SOURCES.$(bld_type)
+  $(target)_SOURCES.$(bld_type) := $(call abspathex,$($(target)_SOURCES.$(bld_type)),$(defpath))
+ endif
+endif
+
 #$ (warning def_target_sources)
 # C sources
@@ -1217,4 +1251,5 @@
 TARGET_$(target) := $(out)
 $(target)_OBJS_ :=
+defpath := $($(target)_PATH)
 
 # source -> object
@@ -1254,4 +1289,10 @@
 deps        := $($(target)_DEPS)
 
+# Adjust paths if we got a default path.
+ifneq ($(defpath),)
+ objs := $(call abspathex,$(objs),$(defpath))
+ deps := $(call abspathex,$(deps),$(defpath))
+endif
+
 # dependency file
 dep := $(out)$(SUFF_DEP)
@@ -1328,4 +1369,5 @@
 TARGET_$(target) := $(out)
 $(target)_OBJS_  :=
+defpath := $($(target)_PATH)
 
 # source -> object
@@ -1455,4 +1497,12 @@
 deps        := $($(target)_DEPS)
 
+# Adjust paths if we got a default path.
+ifneq ($(defpath),)
+ libpath := $(call abspathex,$(libpath)def $(target)_PATH)
+ objs := $(call abspathex,$(objs),$(defpath))
+ deps := $(call abspathex,$(deps),$(defpath))
+ # libs are not subject to this because of the the -l<lib> stuff. Use $(<target>_PATH)/lib if relative to current dir!
+endif
+
 ## @todo this stuff can't be working.
 custom_pre  := $(strip $(firstword \
@@ -1662,22 +1712,22 @@
 # _INSTFUN
 ifdef $(srcsrc)_INSTFUN
-instfun := $(srcsrc)_INSTFUN
+ instfun := $(srcsrc)_INSTFUN
 else
-ifdef $(target)_INSTFUN
-instfun := $(target)_INSTFUN
-else
-instfun := _INSTALL_FILE
-endif
+ ifdef $(target)_INSTFUN
+  instfun := $(target)_INSTFUN
+ else
+  instfun := _INSTALL_FILE
+ endif
 endif
 
 # _INST
 ifdef $(srcsrc)_INST
-inst := $(patsubst %/,%,$($(srcsrc)_INST))/$(dir $(srcdstdir))
+ inst := $(patsubst %/,%,$($(srcsrc)_INST))/$(dir $(srcdstdir))
 else
-ifdef $(target)_INST
-inst := $(patsubst %/,%,$($(target)_INST))/$(dir $(srcdstdir))
-else
-inst := $(dir $(srcdstdir))
-endif
+ ifdef $(target)_INST
+  inst := $(patsubst %/,%,$($(target)_INST))/$(dir $(srcdstdir))
+ else
+  inst := $(dir $(srcdstdir))
+ endif
 endif
 
@@ -1736,17 +1786,23 @@
 	$($(target)_GID))
 
+
+# Adjust the source if we got a default PATH. (This must be done this late!)
+ifdef $(target)_PATH
+ srcsrc := $(call abspathex,$(srcsrc),$($(target)_PATH))
+endif
+
 # create the command
 ifdef $(srcsrc)_INSTALLER
-inscmd := $(call $(srcsrc)_INSTALLER,$(srcsrc),$(insdst),$(target))
+ inscmd := $(call $(srcsrc)_INSTALLER,$(srcsrc),$(insdst),$(target))
 else
-ifdef $(target)_INSTALLER
-inscmd := $(call $(target)_INSTALLER,$(srcsrc),$(insdst),$(target))
-else
-inscmd := $$(INSTALL)\
+ ifdef $(target)_INSTALLER
+  inscmd := $(call $(target)_INSTALLER,$(srcsrc),$(insdst),$(target))
+ else
+  inscmd := $$(INSTALL)\
 		$(if $(uid),-o $(uid))\
 		$(if $(gid),-g $(gid))\
 		$(if $(mode),-m $(mode))\
 		$(srcsrc) $(insdst)
-endif
+ endif
 endif
 
@@ -1788,11 +1844,11 @@
 # _INST
 ifdef $(symlnk)_INST
-inst := $(patsubst %/,%,$($(symlnk)_INST))/$(dir $(symlnk))
+ inst := $(patsubst %/,%,$($(symlnk)_INST))/$(dir $(symlnk))
 else
-ifdef $(target)_INST
-inst := $(patsubst %/,%,$($(target)_INST))/$(dir $(symlnk))
-else
-inst := $(dir $(symlnk))
-endif
+ ifdef $(target)_INST
+  inst := $(patsubst %/,%,$($(target)_INST))/$(dir $(symlnk))
+ else
+  inst := $(dir $(symlnk))
+ endif
 endif
 
@@ -1828,11 +1884,11 @@
 # _INST
 ifdef $(directory)_INST
-inst := $(PATH_INS)/$(patsubst %/,%,$($(directory)_INST))
+ inst := $(PATH_INS)/$(patsubst %/,%,$($(directory)_INST))
 else
-ifdef $(target)_INST
-inst := $(PATH_INS)/$(patsubst %/,%,$($(target)_INST))
-else
-inst := $(PATH_INS)
-endif
+ ifdef $(target)_INST
+  inst := $(PATH_INS)/$(patsubst %/,%,$($(target)_INST))
+ else
+  inst := $(PATH_INS)
+ endif
 endif
 
@@ -2142,2 +2198,3 @@
 endif # __footer_kmk__
 
+
Index: trunk/kBuild/header.kmk
===================================================================
--- trunk/kBuild/header.kmk	(revision 724)
+++ trunk/kBuild/header.kmk	(revision 725)
@@ -156,15 +156,22 @@
 # Common definitions.
 #
+## PATH_CURRENT is the current directory (getcwd).
 PATH_CURRENT        := $(abspath $(CURDIR))
+## PATH_SUB_CURRENT points to current directory of the current makefile.
+# Meaning that it will change value as we enter and exit sub-makefiles.
+PATH_SUB_CURRENT    := $(PATH_CURRENT)
+## PATH_ROOT points to the project root directory.
+PATH_ROOT           := $(abspath $(PATH_CURRENT)/$(DEPTH))
+## PATH_SUB_ROOT points to the directory of the top-level makefile.
 ifneq ($(strip $(SUB_DEPTH)),)
-PATH_SUB_CURRENT    := $(abspath $(PATH_CURRENT)/$(SUB_DEPTH))
-else
-PATH_SUB_CURRENT    := $(PATH_CURRENT)
-endif
-PATH_ROOT           := $(abspath $(PATH_CURRENT)/$(DEPTH))
-
-# Subdirectory relative to the root.
+ PATH_SUB_ROOT      := $(abspath $(PATH_CURRENT)/$(SUB_DEPTH))
+else
+ PATH_SUB_ROOT      := $(PATH_CURRENT)
+endif
+
+## CURSUBDIR is PATH_SUB_ROOT described relative to PATH_ROOT. 
+# This variable is used to determin where the object files and other output goes.
 ifneq ($(PATH_ROOT),$(PATH_CURRENT))
-CURSUBDIR           := $(patsubst $(PATH_ROOT)/%,%,$(PATH_SUB_CURRENT))
+CURSUBDIR           := $(patsubst $(PATH_ROOT)/%,%,$(PATH_SUB_ROOT))
 else
 CURSUBDIR           := .
@@ -173,12 +180,12 @@
 # Output directories.
 ifndef PATH_OUT_BASE
-PATH_OUT_BASE       := $(PATH_ROOT)/out
+ PATH_OUT_BASE      := $(PATH_ROOT)/out
 endif
 ifndef PATH_OUT
-ifdef BUILD_TARGET_SUB # (BUILD_TARGET_SUB is not currently recognized by kBuild in any other places.)
-PATH_OUT            := $(PATH_OUT_BASE)/$(BUILD_TARGET).$(BUILD_TARGET_ARCH).$(BUILD_TARGET_SUB)/$(BUILD_TYPE)
-else
-PATH_OUT            := $(PATH_OUT_BASE)/$(BUILD_TARGET).$(BUILD_TARGET_ARCH)/$(BUILD_TYPE)
-endif
+ ifdef BUILD_TARGET_SUB # (BUILD_TARGET_SUB is not currently recognized by kBuild in any other places.)
+  PATH_OUT          := $(PATH_OUT_BASE)/$(BUILD_TARGET).$(BUILD_TARGET_ARCH).$(BUILD_TARGET_SUB)/$(BUILD_TYPE)
+ else
+  PATH_OUT          := $(PATH_OUT_BASE)/$(BUILD_TARGET).$(BUILD_TARGET_ARCH)/$(BUILD_TYPE)
+ endif
 endif # !define PATH_OUT
 PATH_OBJ             = $(PATH_OUT)/obj
@@ -193,14 +200,18 @@
 # Usually kBuild is external to the source tree.
 ifndef PATH_KBUILD
-PATH_KBUILD         := $(PATH_ROOT)/kBuild
+ PATH_KBUILD        := $(PATH_ROOT)/kBuild
 endif
 PATH_KBUILD         := $(abspath $(PATH_KBUILD))
 # kBuild files which might be of interest.
 FILE_KBUILD_HEADER  := $(PATH_KBUILD)/header.kmk
-FILE_KBUILD_CONFIG  := $(PATH_KBUILD)/config.kmk
+#FILE_KBUILD_CONFIG  := $(PATH_KBUILD)/config.kmk
 FILE_KBUILD_FOOTER  := $(PATH_KBUILD)/footer.kmk
 
 SUFF_DEP            := .dep
+## MAKEFILE is the name of the main makefile.
 MAKEFILE            := $(firstword $(MAKEFILE_LIST))
+## MAKEFILE_CURRENT is the name of the current makefile. 
+# This is updated everything a sub-makefile is included.
+MAKEFILE_CURRENT    := $(MAKEFILE)
 
 
Index: trunk/kBuild/subfooter.kmk
===================================================================
--- trunk/kBuild/subfooter.kmk	(revision 724)
+++ trunk/kBuild/subfooter.kmk	(revision 725)
@@ -25,7 +25,43 @@
 #
 
-_SUB_MAKEFILE_STACK := $(filter-out $(words $(_SUB_MAKEFILE_STACK)), $(_SUB_MAKEFILE_STACK))
-ifeq ($(words $(_SUB_MAKEFILE_STACK)),0)
-include $(PATH_KBUILD)/footer.kmk
+
+#
+# Set the default path for all new targets.
+#
+define def_subheader
+ifndef $(target)_PATH
+$(target)_PATH := $(PATH_SUB_CURRENT)
+endif
+ifndef $(target)_MAKEFILE
+$(target)_MAKEFILE := $(MAKEFILE_CURRENT)
+endif
+endef
+
+$(foreach target,\
+	$(ALL_TARGETS) \
+	$(FETCHES)     $(FETCHES.$(BUILD_TARGET))       $(FETCHES.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(PATCHES)     $(PATCHES.$(BUILD_TARGET))       $(PATCHES.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(BLDPROGS)    $(BLDPROGS.$(BUILD_PLATFORM))    $(BLDPROGS.$(BUILD_PLATFORM).$(BUILD_PLATFORM_ARCH)) \
+	$(LIBRARIES)   $(LIBRARIES.$(BUILD_TARGET))     $(LIBRARIES.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(IMPORT_LIBS) $(IMPORT_LIBS.$(BUILD_TARGET))   $(IMPORT_LIBS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(DLLS)        $(DLLS.$(BUILD_TARGET))          $(DLLS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(PROGRAMS)    $(PROGRAMS.$(BUILD_TARGET))      $(PROGRAMS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(SYSMODS)     $(SYSMODS.$(BUILD_TARGET))       $(SYSMODS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(INSTALLS)    $(INSTALLS.$(BUILD_TARGET))      $(INSTALLS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(OTHERS)      $(OTHERS.$(BUILD_TARGET))        $(OTHERS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+,$(eval $(def_subheader)))
+
+
+#
+# Switch back to the context of previous makefile on the stack.
+#
+MAKEFILE_CURRENT := $(call stack-pop,_SUB_MAKEFILE_STACK)
+PATH_SUB_CURRENT := $(abspath $(patsubst %/,%,$(dir $(MAKEFILE_CURRENT))))
+
+#
+# When we reach the last makefile we include the footer.
+#
+ifeq ($(_SUB_MAKEFILE_STACK),)
+ include $(PATH_KBUILD)/footer.kmk
 endif
 
Index: trunk/kBuild/subheader.kmk
===================================================================
--- trunk/kBuild/subheader.kmk	(revision 724)
+++ trunk/kBuild/subheader.kmk	(revision 725)
@@ -26,8 +26,47 @@
 
 ifndef _SUB_MAKEFILE_STACK
-_SUB_MAKEFILE_STACK := 1
-include $(PATH_KBUILD)/header.kmk
+ #
+ # The first time we just take the makefile context set by header.kmk.
+ #
+ include $(PATH_KBUILD)/header.kmk
+
 else
-_SUB_MAKEFILE_STACK := $(_SUB_MAKEFILE_STACK) $(words $(_SUB_MAKEFILE_STACK) 1)
+
+ #
+ # Set the default path and makefile for all new targets.
+ #
+ define def_subfooter
+ ifndef $(target)_PATH
+ $(target)_PATH := $(PATH_SUB_CURRENT)
+ endif
+ ifndef $(target)_MAKEFILE
+ $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
+ endif
+ endef
+
+ $(foreach target,\
+	$(ALL_TARGETS) \
+	$(FETCHES)     $(FETCHES.$(BUILD_TARGET))       $(FETCHES.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(PATCHES)     $(PATCHES.$(BUILD_TARGET))       $(PATCHES.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(BLDPROGS)    $(BLDPROGS.$(BUILD_PLATFORM))    $(BLDPROGS.$(BUILD_PLATFORM).$(BUILD_PLATFORM_ARCH)) \
+	$(LIBRARIES)   $(LIBRARIES.$(BUILD_TARGET))     $(LIBRARIES.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(IMPORT_LIBS) $(IMPORT_LIBS.$(BUILD_TARGET))   $(IMPORT_LIBS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(DLLS)        $(DLLS.$(BUILD_TARGET))          $(DLLS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(PROGRAMS)    $(PROGRAMS.$(BUILD_TARGET))      $(PROGRAMS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(SYSMODS)     $(SYSMODS.$(BUILD_TARGET))       $(SYSMODS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(INSTALLS)    $(INSTALLS.$(BUILD_TARGET))      $(INSTALLS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+	$(OTHERS)      $(OTHERS.$(BUILD_TARGET))        $(OTHERS.$(BUILD_TARGET).$(BUILD_TARGET_ARCH)) \
+ ,$(eval $(def_subfooter)))
+
+
+ #
+ # Switch context.
+ #
+ __tmp := $(MAKEFILE_LIST)
+ $(call stack-popv,__tmp)
+ MAKEFILE_CURRENT := $(call stack-top,__tmp)
+ PATH_SUB_CURRENT := $(abspath $(patsubst %/,%,$(dir $(MAKEFILE_CURRENT))))
 endif
 
+$(call stack-push,_SUB_MAKEFILE_STACK,$(MAKEFILE_CURRENT))
+
