diff --git a/xen/include/Makefile b/xen/include/Makefile
index c3e0283d347f..56eb9b7f4540 100644
--- a/xen/include/Makefile
+++ b/xen/include/Makefile
@@ -1,5 +1,3 @@
-include $(XEN_ROOT)/Config.mk
-
 ifneq ($(CONFIG_COMPAT),)
 
 compat-arch-$(CONFIG_X86) := x86_32
@@ -46,67 +44,96 @@ endif
 
 endif
 
-public-$(CONFIG_X86) := $(wildcard public/arch-x86/*.h public/arch-x86/*/*.h)
-public-$(CONFIG_ARM) := $(wildcard public/arch-arm/*.h public/arch-arm/*/*.h)
+public-$(CONFIG_X86) := $(wildcard $(srctree)/$(src)/public/arch-x86/*.h $(srctree)/$(src)/public/arch-x86/*/*.h)
+public-$(CONFIG_ARM) := $(wildcard $(srctree)/$(src)/public/arch-arm/*.h $(srctree)/$(src)/public/arch-arm/*/*.h)
+
+all: $(addprefix $(obj)/,$(headers-y))
 
-.PHONY: all
-all: $(headers-y)
+$(obj)/compat/%.h: $(obj)/compat/%.i $(srctree)/tools/compat-build-header.py FORCE
+	$(call if_changed,compat_header)
 
-compat/%.h: compat/%.i Makefile $(BASEDIR)/tools/compat-build-header.py
-	set -e; id=_$$(echo $@ | tr '[:lower:]-/.' '[:upper:]___'); \
+quiet_cmd_compat_header = COMPAT-H $@
+define cmd_compat_header
+	set -e; id=_$$(echo $(patsubst $(obj)/%,%,$(@)) | tr '[:lower:]-/.' '[:upper:]___'); \
 	echo "#ifndef $$id" >$@.new; \
 	echo "#define $$id" >>$@.new; \
 	echo "#include <xen/compat.h>" >>$@.new; \
-	$(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \
+	$(if $(filter-out $(obj)/compat/arch-%.h,$@),echo "#include <$(patsubst $(obj)/compat/%,public/%,$@)>" >>$@.new;) \
 	$(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \
 	grep -v '^# [0-9]' $< | \
-	$(PYTHON) $(BASEDIR)/tools/compat-build-header.py | uniq >>$@.new; \
+	(cd $(srctree)/$(src); $(PYTHON) $(abs_srctree)/tools/compat-build-header.py) | uniq >>$@.new; \
 	$(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \
-	echo "#endif /* $$id */" >>$@.new
+	echo "#endif /* $$id */" >>$@.new; \
 	mv -f $@.new $@
+endef
+
+$(obj)/compat/%.i: $(obj)/compat/%.c FORCE
+	$(call if_changed,compat_i_c)
+
+quiet_cmd_compat_i_c = CPP     $@
+      cmd_compat_i_c = $(CPP) $(filter-out -Wa$(comma)% -include %/include/xen/config.h,$(KBUILD_CFLAGS)) $(cppflags-y) -o $@ $<
 
-compat/%.i: compat/%.c Makefile
-	$(CPP) $(filter-out -Wa$(comma)% -M% %.d -include %/include/xen/config.h,$(CFLAGS)) $(cppflags-y) -o $@ $<
+$(obj)/compat/%.c: $(src)/public/%.h $(src)/xlat.lst $(srctree)/tools/compat-build-source.py FORCE
+	$(call if_changed,compat_source)
 
-compat/%.c: public/%.h xlat.lst Makefile $(BASEDIR)/tools/compat-build-source.py
-	mkdir -p $(@D)
+quiet_cmd_compat_source = COMPAT-C $@
+define cmd_compat_source
+	set -e; \
+	mkdir -p $(@D); \
 	grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \
-	$(PYTHON) $(BASEDIR)/tools/compat-build-source.py >$@.new
+	(cd $(srctree)/$(src); $(PYTHON) $(abs_srctree)/tools/compat-build-source.py) >$@.new; \
 	mv -f $@.new $@
+endef
 
-compat/.xlat/%.h: compat/%.h compat/.xlat/%.lst $(BASEDIR)/tools/get-fields.sh Makefile
-	export PYTHON=$(PYTHON); \
+$(obj)/compat/.xlat/%.h: $(obj)/compat/%.h $(obj)/compat/.xlat/%.lst $(srctree)/tools/get-fields.sh FORCE
+	$(call if_changed,sub_xlat_h)
+
+quiet_cmd_sub_xlat_h = SUBXLAT $@
+define cmd_sub_xlat_h
+	set -e; \
 	while read what name; do \
-		$(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $< || exit $$?; \
-	done <$(patsubst compat/%,compat/.xlat/%,$(basename $<)).lst >$@.new
+		$(SHELL) $(srctree)/tools/get-fields.sh "$$what" compat_$$name $< || exit $$?; \
+	done <$(patsubst $(obj)/compat/%,$(obj)/compat/.xlat/%,$(basename $<)).lst >$@.new; \
 	mv -f $@.new $@
+endef
+
+$(obj)/compat/.xlat/%.lst: $(src)/xlat.lst $(src)/Makefile
+	$(call filechk,xlat_lst)
 
-.PRECIOUS: compat/.xlat/%.lst
-compat/.xlat/%.lst: xlat.lst Makefile
-	mkdir -p $(@D)
-	grep -v '^[[:blank:]]*#' $< | sed -ne 's,@arch@,$(compat-arch-y),g' -re 's,[[:blank:]]+$*\.h[[:blank:]]*$$,,p' >$@.new
-	$(call move-if-changed,$@.new,$@)
+define filechk_xlat_lst
+	grep -v '^[[:blank:]]*#' $< | sed -ne 's,@arch@,$(compat-arch-y),g' -re 's,[[:blank:]]+$*\.h[[:blank:]]*$$,,p'
+endef
 
-xlat-y := $(shell sed -ne 's,@arch@,$(compat-arch-y),g' -re 's,^[?!][[:blank:]]+[^[:blank:]]+[[:blank:]]+,,p' xlat.lst | uniq)
+xlat-y := $(shell sed -ne 's,@arch@,$(compat-arch-y),g' -re 's,^[?!][[:blank:]]+[^[:blank:]]+[[:blank:]]+,,p' $(srctree)/$(src)/xlat.lst | uniq)
 xlat-y := $(filter $(patsubst compat/%,%,$(headers-y)),$(xlat-y))
 
-compat/xlat.h: $(addprefix compat/.xlat/,$(xlat-y)) Makefile
-	cat $(filter %.h,$^) >$@.new
+$(obj)/compat/xlat.h: $(addprefix $(obj)/compat/.xlat/,$(xlat-y))
+	$(call if_changed,xlat_h)
+
+quiet_cmd_xlat_h = UPD $@
+define cmd_xlat_h
+	set -e; \
+	cat $(filter %.h,$^) >$@.new; \
 	mv -f $@.new $@
+endef
 
 ifeq ($(XEN_TARGET_ARCH),$(XEN_COMPILE_ARCH))
 
-all: headers.chk headers99.chk headers++.chk
+all: $(obj)/headers.chk $(obj)/headers99.chk $(obj)/headers++.chk
 
-PUBLIC_HEADERS := $(filter-out public/arch-% public/dom0_ops.h, $(wildcard public/*.h public/*/*.h) $(public-y))
+PUBLIC_HEADERS := $(filter-out $(srctree)/$(src)/public/arch-% $(srctree)/$(src)/public/dom0_ops.h, $(wildcard $(srctree)/$(src)/public/*.h $(srctree)/$(src)/public/*/*.h) $(public-y))
 
-PUBLIC_C99_HEADERS := public/io/9pfs.h public/io/pvcalls.h
-PUBLIC_ANSI_HEADERS := $(filter-out public/%ctl.h public/xsm/% public/%hvm/save.h $(PUBLIC_C99_HEADERS), $(PUBLIC_HEADERS))
+PUBLIC_C99_HEADERS := $(srctree)/$(src)/public/io/9pfs.h $(srctree)/$(src)/public/io/pvcalls.h
+PUBLIC_ANSI_HEADERS := $(filter-out $(srctree)/$(src)/public/%ctl.h $(srctree)/$(src)/public/xsm/% $(srctree)/$(src)/public/%hvm/save.h $(PUBLIC_C99_HEADERS), $(PUBLIC_HEADERS))
 
-public/io/9pfs.h-prereq := string
-public/io/pvcalls.h-prereq := string
+# XXX for in tree build
+$(src)/public/io/9pfs.h-prereq := string
+$(src)/public/io/pvcalls.h-prereq := string
+# XXX for out of tree build
+$(srctree)/$(src)/public/io/9pfs.h-prereq := string
+$(srctree)/$(src)/public/io/pvcalls.h-prereq := string
 
-headers.chk: $(PUBLIC_ANSI_HEADERS) Makefile
+$(obj)/headers.chk: $(PUBLIC_ANSI_HEADERS) $(src)/Makefile
 	for i in $(filter %.h,$^); do \
 	    $(CC) -x c -ansi -Wall -Werror -include stdint.h \
 	          -S -o /dev/null $$i || exit 1; \
@@ -114,7 +141,7 @@ headers.chk: $(PUBLIC_ANSI_HEADERS) Makefile
 	done >$@.new
 	mv $@.new $@
 
-headers99.chk: $(PUBLIC_C99_HEADERS) Makefile
+$(obj)/headers99.chk: $(PUBLIC_C99_HEADERS) $(src)/Makefile
 	rm -f $@.new
 	$(foreach i, $(filter %.h,$^),                                        \
 	    echo "#include "\"$(i)\"                                          \
@@ -124,7 +151,7 @@ headers99.chk: $(PUBLIC_C99_HEADERS) Makefile
 	    || exit $$?; echo $(i) >> $@.new;)
 	mv $@.new $@
 
-headers++.chk: $(PUBLIC_HEADERS) Makefile
+$(obj)/headers++.chk: $(PUBLIC_HEADERS) $(src)/Makefile
 	rm -f $@.new
 	if ! $(CXX) -v >/dev/null 2>&1; then                                  \
 	    touch $@.new;                                                     \
@@ -133,21 +160,33 @@ headers++.chk: $(PUBLIC_HEADERS) Makefile
 	$(foreach i, $(filter %.h,$^),                                        \
 	    echo "#include "\"$(i)\"                                          \
 	    | $(CXX) -x c++ -std=gnu++98 -Wall -Werror -D__XEN_TOOLS__        \
-	      -include stdint.h -include public/xen.h                         \
+	      -include stdint.h -include $(srctree)/$(src)/public/xen.h       \
 	      $(foreach j, $($(i)-prereq), -include c$(j)) -S -o /dev/null -  \
 	    || exit $$?; echo $(i) >> $@.new;)
 	mv $@.new $@
 
 endif
 
-ifeq ($(XEN_TARGET_ARCH),x86_64)
+ifeq ($(ARCH),x86_64)
 .PHONY: lib-x86-all
 lib-x86-all:
-	$(MAKE) -C xen/lib/x86 all
+	$(Q)$(MAKE) XEN_ROOT=$(abs_srctree)/.. -C $(srctree)/$(src)/xen/lib/x86 all
 
 all: lib-x86-all
 endif
 
-clean::
-	rm -rf compat config generated headers*.chk
-	rm -f $(BASEDIR)/include/xen/lib/x86/cpuid-autogen.h
+# Update targets to help Kbuild finding which dependency file to load.
+targets += $(headers-y)
+# Adding intermediate targets
+targets += $(foreach h, $(headers-y), \
+		$(h:.h=.i) $(h:.h=.c))
+# Adding intermediate targets of xlat.h
+targets += $(addprefix compat/.xlat/,$(xlat-y))
+
+clean-dirs += compat config generated
+clean-files += headers*.chk
+clean-files += xen/lib/x86/cpuid-autogen.h
+
+PHONY += all
+all:
+	@:
