Index: trunk/kBuild/footer.kmk
===================================================================
--- trunk/kBuild/footer.kmk	(revision 2515)
+++ trunk/kBuild/footer.kmk	(revision 2517)
@@ -1320,5 +1320,5 @@
 
 if1of ($(insttype), stage both)
- local stage := $(evalcall FIRST-DEFINED-VAR, \
+ local stage := $(strip $(firstdefined \
 	$(target)_STAGE.$(bld_trg).$(bld_trg_arch).$(bld_type) \
 	$(target)_INST.$(bld_trg).$(bld_trg_arch).$(bld_type) \
@@ -1335,5 +1335,6 @@
 	$(target)_STAGE \
 	$(target)_INST \
-	definst )
+	definst \
+	,value))
  $(target)_1_STAGE := $(stage)
  if "$(substr $(stage),-1,1)" == "/" # Multicast support requires addprefix/suffix.
@@ -1351,5 +1352,5 @@
 
 if1of ($(insttype), both)
- local inst := $(evalcall FIRST-DEFINED-VAR, \
+ local inst := $(strip $(firstdefined \
 	$(target)_INST.$(bld_trg).$(bld_trg_arch).$(bld_type) \
 	$(target)_INST.$(bld_trg).$(bld_trg_arch) \
@@ -1359,5 +1360,6 @@
 	$(target)_INST.$(bld_type) \
 	$(target)_INST \
-	definst )
+	definst \
+	,value))
  $(target)_1_INST := $(inst)
  if "$(substr $(inst),-1,1)" == "/" # Multicast support requires addprefix/suffix.
@@ -1526,5 +1528,5 @@
 # Determine the actual INST and STAGE sub-dirs to use for this target.
 if1of ($(insttype), stage both)
- local stage := $(evalcall FIRST-DEFINED-VAR, \
+ local stage := $(strip $(firstdefined \
 	$(target)_STAGE.$(bld_trg).$(bld_trg_arch).$(bld_type) \
 	$(target)_INST.$(bld_trg).$(bld_trg_arch).$(bld_type) \
@@ -1541,5 +1543,6 @@
 	$(target)_STAGE \
 	$(target)_INST \
-	definst )
+	definst \
+	,value))
  if $(words $(stage)) > 1
   $(warning kBuild: The STAGE/INST property of install '$(target)' specifies multiple location, that is not supported.)
@@ -1552,5 +1555,5 @@
 
 if1of ($(insttype), both)
- local inst := $(evalcall FIRST-DEFINED-VAR, \
+ local inst := $(strip $(firstdefined \
 	$(target)_INST.$(bld_trg).$(bld_trg_arch).$(bld_type) \
 	$(target)_INST.$(bld_trg).$(bld_trg_arch) \
@@ -1560,8 +1563,12 @@
 	$(target)_INST.$(bld_type) \
 	$(target)_INST \
-	definst )
+	definst \
+	,value))
  if $(words $(inst)) > 1
   $(warning kBuild: The INST property of install '$(target)' specifies multiple location, that is not supported.)
   local inst := $(word 1, $(inst))
+ endif
+ ifneq ($(root $(stage)),)
+  $(error kBuild: The INST property should not start with a root specification)
  endif
  $(target)_1_INST := $(inst)
@@ -3033,5 +3040,5 @@
 local srcdst    := $(word $(words $(srcdst)),$(srcdst))
 
-# Calc destinations.
+# instfun, mode, uid and gid
 ifdef $(srcsrc)_INSTFUN
  local instfun := $(srcsrc)_INSTFUN
@@ -3039,26 +3046,4 @@
  local instfun := $(top_instfun)
 endif
-
-local stage    := $(firstword $($(srcsrc)_STAGE) $($(srcsrc)_INST) $($(target)_1_STAGE))
-ifneq ($(substr $(stage),-1),/)
- $(warning kBuild: File $(srcsrc) in install target $(target) has a STAGE property without a trailing slash.)
- local stage   := $(stage)/
-endif
-local stage    := $(stage)$(dir $(srcdstdir))
-local stagedst := $(call $(instfun),$(srcdst),$(target),$(stage),$(PATH_STAGE))
-
-ifeq ($(insttype),both)
- local inst     := $(firstword $($(srcsrc)_INST) $($(target)_1_INST))
- ifneq ($(substr $(inst),-1),/)
-  $(warning kBuild: File $(srcsrc) in install target $(target) has a INST property without a trailing slash.)
-  local inst    := $(inst)/
- endif
- local inst     := $(inst)$(dir $(srcdstdir))
- local instdst  := $(call $(instfun),$(srcdst),$(target),$(inst),$(PATH_INS))
-endif
-
-#$(warning instfun=$(instfun) srcdst=$(srcdst) target=$(target) inst=$(inst) => instdst=$(instdst); stage=$(stage) => stagedst=$(stagedst))
-
-# mode, uid and gid
 local mode := $(firstword \
 	$($(target)_$(srcsrc)$(source_type_prefix)_MODE.$(bld_trg).$(bld_trg_arch)) \
@@ -3145,4 +3130,21 @@
 
 # Generate the staging rule (requires double evaluation).
+local stage      := $(strip $(firstdefined $(srcsrc)_STAGE $(srcsrc)_INST $(target)_1_STAGE,value))
+if "$(substr $(stage),-1)" != "/" && "$(stage)" != ""
+ $(warning kBuild: File $(srcsrc) in install target $(target) has a STAGE/INST property without a trailing slash: '$(stage)')
+ local stage     := $(stage)/
+endif
+local stage      := $(stage)$(dir $(srcdstdir))
+ifeq ($(root $(stage)),)
+ local stagedst  := $(call $(instfun),$(srcdst),$(target),$(stage),$(PATH_STAGE))
+else
+ local stage     := $(abspath $(stage))
+ ifeq ($(pos $(PATH_OBJ),$(stage)),1)
+  local stage    := $(substr $(stage), 1, $(length-var PATH_OBJ))
+  local stagedst := $(call $(instfun),$(srcdst),$(target),$(stage),$(PATH_OBJ))
+ else
+  $(error kBuild: File $(srcsrc) in install target $(target) has a STAGE/INST property with an absolute path outside PATH_OBJ: '$(stage)')
+ endif
+endif
 ifdef $(srcsrc)_INSTALLER
  local stagecmd := $(call $(srcsrc)_INSTALLER,$(srcsrc),$(stagedst),$(target),$(flags),stage)
@@ -3162,8 +3164,19 @@
 # Generate the install rule
 ifeq ($(insttype),both)
+ local inst     := $(strip $(firstdefined $(srcsrc)_INST $(target)_1_INST,value))
+ if "$(substr $(inst),-1)" != "/" && "$(inst)" != ""
+  $(warning kBuild: File $(srcsrc) in install target $(target) has a INST property without a trailing slash: '$(inst)')
+  local inst    := $(inst)/
+ endif
+ local inst     := $(inst)$(dir $(srcdstdir))
+ ifneq ($(root $(inst)),)
+  $(error kBuild: File $(srcsrc) in install target $(target) has a INST property with an absolute path: '$(inst)')
+ endif
+ local instdst  := $(call $(instfun),$(srcdst),$(target),$(inst),$(PATH_INS))
+
  ifdef $(srcsrc)_INSTALLER
-  local instcmd  := $(call $(srcsrc)_INSTALLER,$(srcsrc),$(instdst),$(target),$(flags),install)
+  local instcmd := $(call $(srcsrc)_INSTALLER,$(srcsrc),$(instdst),$(target),$(flags),install)
  else ifdef $(target)_INSTALLER
-  local instcmd  := $(call $(target)_INSTALLER,$(srcsrc),$(instdst),$(target),$(flags),install)
+  local instcmd := $(call $(target)_INSTALLER,$(srcsrc),$(instdst),$(target),$(flags),install)
  else
   local instcmd := $$(INSTALL)\
@@ -3178,4 +3191,5 @@
 endif
 
+#$(warning instfun=$(instfun) srcdst=$(srcdst) target=$(target) inst=$(inst) => instdst=$(instdst); stage=$(stage) => stagedst=$(stagedst))
 endef # def_install_src
 $(eval-opt-var def_install_src)
@@ -3212,5 +3226,5 @@
 local symdst := $(word $(words $(symdst)),$(symdst))
 
-# Calc destinations
+# Figure which install function to use below.
 ifdef $(symlnk)_INSTFUN
  local instfun := $(symlnk)_INSTFUN
@@ -3219,31 +3233,43 @@
 endif
 
-local stage    := $(firstword $($(symlnk)_STAGE) $($(symlnk)_INST) $($(target)_1_STAGE))
-ifneq ($(substr $(stage),-1),/)
- $(warning kBuild: Symlink $(symlnk) in install target $(target) has a STAGE property without a trailing slash: '$(stage)')
- local stage   := $(stage)/
-endif
-local stage    := $(stage)$(dir $(srcdstdir))
-local stagedst := $(call $(instfun),$(symlnk),$(target),$(stage),$(PATH_STAGE))
-
-local inst     := $(firstword $($(symlnk)_INST) $($(target)_1_INST))
-ifneq ($(substr $(inst),-1),/)
- $(warning kBuild: Symlnk $(symlnk) in install target $(target) has a INST property without a trailing slash: '$(inst)')
- local inst    := $(inst)/
-endif
-local inst     := $(inst)$(dir $(srcdstdir))
-local instdst  := $(call $(instfun),$(symlnk),$(target),$(inst),$(PATH_INS))
-#$(warning symlnk=$(symlnk) symdst=$(symdst) instdst=$(instdst) stagedst=$(stagedst) instfun=$(instfun) inst=$(inst) stage='$(stage)')
-
-# Generate the staging rule (requires double evaluation).
+# Calc stage destination and generate the rule (requires double evaluation).
+local stage      := $(strip $(firstdefined $(symlnk)_STAGE $(symlnk)_INST $(target)_1_STAGE,value))
+if "$(substr $(stage),-1)" != "/" && "$(stage)" != ""
+ $(warning kBuild: Symlink $(symlnk) in install target $(target) has a STAGE/INST property without a trailing slash: '$(stage)')
+ local stage     := $(stage)/
+endif
+local stage      := $(stage)$(dir $(srcdstdir))
+ifeq ($(root $(stage)),)
+ local stagedst  := $(call $(instfun),$(symlnk),$(target),$(stage),$(PATH_STAGE))
+else
+ local stage     := $(abspath $(stage))
+ ifeq ($(pos $(PATH_OBJ),$(stage)),1)
+  local stage    := $(substr $(stage), 1, $(length-var PATH_OBJ))
+  local stagedst := $(call $(instfun),$(symlnk),$(target),$(stage),$(PATH_OBJ))
+ else
+  $(error kBuild: Symlink $(symlnk) in install target $(target) has a STAGE/INST property with an absolute path outside PATH_OBJ: '$(stage)')
+ endif
+endif
+
 $(eval $(def_install_symlink_rule_staging))
 $(target)_2_STAGE_TARGETS += $(stagedst)
 
-# Generate the install rule.
+# Calcuate the install destiation and generate the rule (if necessary).
 ifeq ($(instmode),both)
+ local inst    := $(strip $(firstdefined $(symlnk)_INST $(target)_1_INST,value))
+ if "$(substr $(inst),-1)" != "/" && "$(inst)" != ""
+  $(warning kBuild: Symlink $(symlnk) in install target $(target) has a INST property without a trailing slash: '$(inst)')
+  local inst   := $(inst)/
+ endif
+ ifneq ($(root $(inst)),)
+  $(error kBuild: Symlink $(symlnk) in install target $(target) has a INST property with an absolute path: '$(inst)')
+ endif
+ local inst    := $(inst)$(dir $(srcdstdir))
+ local instdst := $(call $(instfun),$(symlnk),$(target),$(inst),$(PATH_INS))
  $(eval $(def_install_symlink_rule_installing))
  $(target)_2_INST_TARGETS += $(instdst)
 endif
 
+#$(warning symlnk=$(symlnk) symdst=$(symdst) instdst=$(instdst) stagedst=$(stagedst) instfun=$(instfun) inst=$(inst) stage='$(stage)')
 endef # def_install_symlink
 $(optmize def_install_symlink)
@@ -3275,25 +3301,4 @@
 
 # gather common properties.
-ifdef $(directory)_INST
- local inst := $($(directory)_INST)
-else
- local inst := $($(target)_1_INST)
-endif
-ifneq ($(substr $(inst),-1),/)
- $(warning kBuild: Directory $(directory) in install target $(target) has a INST property without a trailing slash.)
- local inst := $(inst)/
-endif
-ifdef $(directory)_STAGE
- local stage := $($(directory)_STAGE)
-else ifdef $(directory)_INST
- local stage := $($(directory)_INST)
-else
- local stage := $($(target)_1_STAGE)
-endif
-ifneq ($(substr $(stage),-1),/)
- $(warning kBuild: Directory $(directory) in install target $(target) has a INST property without a trailing slash.)
- local stage := $(stage)/
-endif
-
 local mode := $(firstword \
 	$($(target)_$(directory)_MODE.$(bld_trg).$(bld_trg_arch)) \
@@ -3328,8 +3333,22 @@
 	$($(target)_$(directory)_IDFLAGS.$(bld_trg)) \
 	$($(target)_$(directory)_IDFLAGS.$(bld_trg).$(bld_trg_arch)) \
- #$(warning directory=$(directory) inst=$(inst) stage=$(stage) mode=$(mode) gid=$(gid) uid=$(uid))
 
 # The staging rule (requires double evaluation).
-local insdst := $(PATH_STAGE)/$(stage)$(directory)/
+local stage    := $(strip $(firstdefined $(directory)_STAGE $(directory)_INST $(target)_1_STAGE,value))
+if "$(substr $(stage),-1)" != "/" && "$(stage)" != ""
+ $(warning kBuild: Directory $(directory) in install target $(target) has a STAGE/INST property without a trailing slash: '$(stage)')
+ local stage   := $(stage)/
+endif
+ifeq ($(root $(stage)),)
+ local insdst  := $(PATH_STAGE)/$(stage)$(directory)/
+else
+ local stage   := $(abspath $(stage))
+ ifeq ($(pos $(PATH_OBJ),$(stage)),1)
+  local insdst := $(stage)$(directory)/
+ else
+  $(error kBuild: Directory $(directory) in install target $(target) has a STAGE/INST property with an absolute path outside PATH_OBJ: '$(stage)')
+ endif
+endif
+
 $(target)_2_STAGE_DIR_TARGETS += $(insdst)
 $(eval $(def_install_directory_rule))
@@ -3337,4 +3356,12 @@
 # The install rule.
 ifeq ($(insttype),both)
+ local inst   := $(strip $(firstdefined $(directory)_INST $(target)_1_INST,value))
+ ifneq ($(substr $(inst),-1),/)
+  $(warning kBuild: Directory $(directory) in install target $(target) has a INST property without a trailing slash: '$(inst)')
+  local inst  := $(inst)/
+ endif
+ ifeq ($(root $(stage)),)
+  $(error kBuild: Directory $(directory) in install target $(target) has a INST property with an absoluate path: '$(inst)')
+ endif
  local insdst := $(PATH_INS)/$(inst)$(directory)/
  $(target)_2_INST_DIR_TARGETS += $(insdst)
@@ -3342,4 +3369,5 @@
 endif
 
+#$(warning directory=$(directory) inst=$(inst) stage=$(stage) mode=$(mode) gid=$(gid) uid=$(uid))
 endef # def_install_directory
 $(eval-opt-var def_install_directory)
