Index: trunk/kBuild/tools/VCC100.kmk
===================================================================
--- trunk/kBuild/tools/VCC100.kmk	(revision 2953)
+++ trunk/kBuild/tools/VCC100.kmk	(revision 2954)
@@ -108,4 +108,6 @@
 TOOL_VCC100_PDB = $(dir $(1))$(tolower $(notdir $(1))).$(2)
 
+
+# General Properties used by kBuild
 TOOL_VCC100_COBJSUFF         ?= .obj
 TOOL_VCC100_CFLAGS           ?= -TC -nologo -Zi
@@ -188,16 +190,60 @@
 # @param    $(outbase)  Output basename (full). Use this for list files and such.
 # @param    $(objsuff)  Object suffix.
-TOOL_VCC100_COMPILE_CXX_DEPEND =
+TOOL_VCC100_COMPILE_CXX_DEPEND = $($(target)_1_VCC_PCH_FILE)
 TOOL_VCC100_COMPILE_CXX_DEPORD =
 TOOL_VCC100_COMPILE_CXX_OUTPUT =
-TOOL_VCC100_COMPILE_CXX_OUTPUT_MAYBE = $(call TOOL_VCC100_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC100_PDB, $(outbase)-obj,idb)
+TOOL_VCC100_COMPILE_CXX_OUTPUT_MAYBE = $(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB)\
+	,,$(call TOOL_VCC100_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC100_PDB, $(outbase)-obj,idb))
 define TOOL_VCC100_COMPILE_CXX_CMDS
 	$(QUIET)$(TOOL_VCC100_CXX) -c\
 		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-		-Fd$(outbase)-obj.pdb \
+		$(if-expr defined($(target)_VCC_PCH_HDR)\
+		,-FI$($(target)_VCC_PCH_HDR) -Yu$($(target)_VCC_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE),)\
+		-Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
 		-Fo$(obj)\
 		$(subst /,\\,$(abspath $(source)))
 	$(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
 endef
+
+
+#
+# Helper tool for creating the precompiled C++ header.
+#
+# It only have the C++ compile bits and it's purpose is to skip bits
+# related _1_VCC_PCH_FILE and add -Yc.
+#
+TOOL_VCC100-PCH                         := Helper for creating precompiled header using CXX handling.
+TOOL_VCC100-PCH_EXTENDS                 := VCC100
+TOOL_VCC100-PCH_CXXOBJSUFF              := .obj
+TOOL_VCC100-PCH_CXXINCS                  = $(TOOL_VCC100_CXXINCS)
+TOOL_VCC100-PCH_COMPILE_CXX_DEPEND       = $(NO_SUCH_VARIABLE)
+TOOL_VCC100-PCH_COMPILE_CXX_DEPORD       = $(NO_SUCH_VARIABLE)
+TOOL_VCC100-PCH_COMPILE_CXX_OUTPUT       = $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+TOOL_VCC100-PCH_COMPILE_CXX_OUTPUT_MAYBE = $(NO_SUCH_VARIABLE)
+ifdef TOOL_VCC100_KSUBMIT
+ define TOOL_VCC100-PCH_COMPILE_CXX_CMDS
+	$(QUIET)$(TOOL_VCC100_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)\
+		-- $(TOOL_VCC100_CXX) -c -Yc\
+		$(filter-out $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+               -Fp$($(target)_1_VCC_PCH_FILE) \
+		-Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+		-Fo$(obj)\
+               -TP \
+		$(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC100-PCH_COMPILE_CXX_CMDS
+	$(QUIET)$(TOOL_VCC100_CXX) -c -Yc\
+		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+               -Fp$($(target)_1_VCC_PCH_FILE) \
+		-Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+		-Fo$(obj)\
+               -TP \
+		$(subst /,\\,$(abspath $(source)))
+	$(QUIET)$(DEP_OBJ) -f -s -q  -e .pch -o $(dep) -t $(obj) $(obj)
+
+ endef
+endif # !TOOL_VCC100_KSUBMIT
+
 
 ## @todo configure the assembler template.
@@ -250,6 +296,4 @@
 	$(QUIET)$(TOOL_VCC100_AR) $(flags) /OUT:$(out) @$(outbase).rsp
 endef
-
-
 
 
Index: trunk/kBuild/tools/VCC100AMD64.kmk
===================================================================
--- trunk/kBuild/tools/VCC100AMD64.kmk	(revision 2953)
+++ trunk/kBuild/tools/VCC100AMD64.kmk	(revision 2954)
@@ -106,4 +106,6 @@
 TOOL_VCC100AMD64_PDB = $(dir $(1))$(tolower $(notdir $(1))).$(2)
 
+
+# General Properties used by kBuild
 TOOL_VCC100AMD64_COBJSUFF         ?= .obj
 TOOL_VCC100AMD64_CFLAGS           ?= -TC -nologo -Zi
@@ -192,8 +194,9 @@
 # @param    $(outbase)  Output basename (full). Use this for list files and such.
 # @param    $(objsuff)  Object suffix.
-TOOL_VCC100AMD64_COMPILE_CXX_DEPEND =
+TOOL_VCC100AMD64_COMPILE_CXX_DEPEND = $($(target)_1_VCC_PCH_FILE)
 TOOL_VCC100AMD64_COMPILE_CXX_DEPORD =
 TOOL_VCC100AMD64_COMPILE_CXX_OUTPUT =
-TOOL_VCC100AMD64_COMPILE_CXX_OUTPUT_MAYBE = $(call TOOL_VCC100AMD64_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC100AMD64_PDB, $(outbase)-obj,idb)
+TOOL_VCC100AMD64_COMPILE_CXX_OUTPUT_MAYBE = $(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB)\
+	,,$(call TOOL_VCC100AMD64_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC100AMD64_PDB, $(outbase)-obj,idb))
 ifdef TOOL_VCC100AMD64_KSUBMIT
  TOOL_VCC100AMD64_COMPILE_CXX_DONT_PURGE_OUTPUT := 1 # speed
@@ -202,5 +205,7 @@
 		-- $(TOOL_VCC100AMD64_CXX) -c\
 		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-		-Fd$(outbase)-obj.pdb \
+		$(if-expr defined($(target)_VCC_PCH_HDR)\
+		,-FI$($(target)_VCC_PCH_HDR) -Yu$($(target)_VCC_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE),)\
+		-Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
 		-Fo$(obj)\
 		$(subst /,\\,$(abspath $(source)))
@@ -210,5 +215,7 @@
 	$(QUIET)$(TOOL_VCC100AMD64_CXX) -c\
 		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-		-Fd$(outbase)-obj.pdb \
+		$(if-expr defined($(target)_VCC_PCH_HDR)\
+		,-FI$($(target)_VCC_PCH_HDR) -Yu$($(target)_VCC_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE),)\
+		-Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
 		-Fo$(obj)\
 		$(subst /,\\,$(abspath $(source)))
@@ -216,4 +223,45 @@
  endef
 endif # !TOOL_VCC100AMD64_KSUBMIT
+
+
+#
+# Helper tool for creating the precompiled C++ header.
+#
+# It only have the C++ compile bits and it's purpose is to skip bits
+# related _1_VCC_PCH_FILE and add -Yc.
+#
+TOOL_VCC100AMD64-PCH                         := Helper for creating precompiled header using CXX handling.
+TOOL_VCC100AMD64-PCH_EXTENDS                 := VCC100AMD64
+TOOL_VCC100AMD64-PCH_CXXOBJSUFF              := .obj
+TOOL_VCC100AMD64-PCH_CXXINCS                  = $(TOOL_VCC100AMD64_CXXINCS)
+TOOL_VCC100AMD64-PCH_COMPILE_CXX_DEPEND       = $(NO_SUCH_VARIABLE)
+TOOL_VCC100AMD64-PCH_COMPILE_CXX_DEPORD       = $(NO_SUCH_VARIABLE)
+TOOL_VCC100AMD64-PCH_COMPILE_CXX_OUTPUT       = $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+TOOL_VCC100AMD64-PCH_COMPILE_CXX_OUTPUT_MAYBE = $(NO_SUCH_VARIABLE)
+ifdef TOOL_VCC100AMD64_KSUBMIT
+ define TOOL_VCC100AMD64-PCH_COMPILE_CXX_CMDS
+	$(QUIET)$(TOOL_VCC100AMD64_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)\
+		-- $(TOOL_VCC100AMD64_CXX) -c -Yc\
+		$(filter-out $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+               -Fp$($(target)_1_VCC_PCH_FILE) \
+		-Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+		-Fo$(obj)\
+               -TP \
+		$(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC100AMD64-PCH_COMPILE_CXX_CMDS
+	$(QUIET)$(TOOL_VCC100AMD64_CXX) -c -Yc\
+		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+               -Fp$($(target)_1_VCC_PCH_FILE) \
+		-Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+		-Fo$(obj)\
+               -TP \
+		$(subst /,\\,$(abspath $(source)))
+	$(QUIET)$(DEP_OBJ) -f -s -q  -e .pch -o $(dep) -t $(obj) $(obj)
+
+ endef
+endif # !TOOL_VCC100AMD64_KSUBMIT
+
 
 ## @todo configure the assembler template.
Index: trunk/kBuild/tools/VCC100X86.kmk
===================================================================
--- trunk/kBuild/tools/VCC100X86.kmk	(revision 2953)
+++ trunk/kBuild/tools/VCC100X86.kmk	(revision 2954)
@@ -187,8 +187,9 @@
 # @param    $(outbase)  Output basename (full). Use this for list files and such.
 # @param    $(objsuff)  Object suffix.
-TOOL_VCC100X86_COMPILE_CXX_DEPEND =
+TOOL_VCC100X86_COMPILE_CXX_DEPEND = $($(target)_1_VCC_PCH_FILE)
 TOOL_VCC100X86_COMPILE_CXX_DEPORD =
 TOOL_VCC100X86_COMPILE_CXX_OUTPUT =
-TOOL_VCC100X86_COMPILE_CXX_OUTPUT_MAYBE = $(call TOOL_VCC100X86_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC100X86_PDB, $(outbase)-obj,idb)
+TOOL_VCC100X86_COMPILE_CXX_OUTPUT_MAYBE = $(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB)\
+	,,$(call TOOL_VCC100X86_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC100X86_PDB, $(outbase)-obj,idb))
 ifdef TOOL_VCC100X86_KSUBMIT
  TOOL_VCC100X86_COMPILE_CXX_DONT_PURGE_OUTPUT = 1 # speed
@@ -197,5 +198,7 @@
 		-- $(TOOL_VCC100X86_CXX) -c\
 		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-		-Fd$(outbase)-obj.pdb \
+		$(if-expr defined($(target)_VCC_PCH_HDR)\
+		,-FI$($(target)_VCC_PCH_HDR) -Yu$($(target)_VCC_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE),)\
+		-Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
 		-Fo$(obj)\
 		$(subst /,\\,$(abspath $(source)))
@@ -205,5 +208,7 @@
 	$(QUIET)$(TOOL_VCC100X86_CXX) -c\
 		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-		-Fd$(outbase)-obj.pdb \
+		$(if-expr defined($(target)_VCC_PCH_HDR)\
+		,-FI$($(target)_VCC_PCH_HDR) -Yu$($(target)_VCC_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE),)\
+		-Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
 		-Fo$(obj)\
 		$(subst /,\\,$(abspath $(source)))
@@ -211,4 +216,45 @@
  endef
 endif # !TOOL_VCC100X86_KSUBMIT
+
+
+#
+# Helper tool for creating the precompiled C++ header.
+#
+# It only have the C++ compile bits and it's purpose is to skip bits
+# related _1_VCC_PCH_FILE and add -Yc.
+#
+TOOL_VCC100X86-PCH                         := Helper for creating precompiled header using CXX handling.
+TOOL_VCC100X86-PCH_EXTENDS                 := VCC100X86
+TOOL_VCC100X86-PCH_CXXOBJSUFF              := .obj
+TOOL_VCC100X86-PCH_CXXINCS                  = $(TOOL_VCC100X86_CXXINCS)
+TOOL_VCC100X86-PCH_COMPILE_CXX_DEPEND       = $(NO_SUCH_VARIABLE)
+TOOL_VCC100X86-PCH_COMPILE_CXX_DEPORD       = $(NO_SUCH_VARIABLE)
+TOOL_VCC100X86-PCH_COMPILE_CXX_OUTPUT       = $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+TOOL_VCC100X86-PCH_COMPILE_CXX_OUTPUT_MAYBE = $(NO_SUCH_VARIABLE)
+ifdef TOOL_VCC100X86_KSUBMIT
+ define TOOL_VCC100X86-PCH_COMPILE_CXX_CMDS
+	$(QUIET)$(TOOL_VCC100X86_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)\
+		-- $(TOOL_VCC100X86_CXX) -c -Yc\
+		$(filter-out $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+               -Fp$($(target)_1_VCC_PCH_FILE) \
+		-Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+		-Fo$(obj)\
+               -TP \
+		$(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC100X86-PCH_COMPILE_CXX_CMDS
+	$(QUIET)$(TOOL_VCC100X86_CXX) -c -Yc\
+		$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+               -Fp$($(target)_1_VCC_PCH_FILE) \
+		-Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+		-Fo$(obj)\
+               -TP \
+		$(subst /,\\,$(abspath $(source)))
+	$(QUIET)$(DEP_OBJ) -f -s -q  -e .pch -o $(dep) -t $(obj) $(obj)
+
+ endef
+endif # !TOOL_VCC100X86_KSUBMIT
+
 
 ## @todo configure the assembler template.
Index: trunk/kBuild/units/vccprecomp.kmk
===================================================================
--- trunk/kBuild/units/vccprecomp.kmk	(revision 2954)
+++ trunk/kBuild/units/vccprecomp.kmk	(revision 2954)
@@ -0,0 +1,66 @@
+# $Id$
+## @file
+# kBuild Unit - Target Level Precompiled Headers for Visual C++.
+#
+
+#
+# Copyright (c) 2016 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
+#
+# This file is part of kBuild.
+#
+# kBuild is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# kBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with kBuild; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#
+# As a special exception you are granted permission to include this file, via
+# the kmk include directive, as you wish without this in itself causing the
+# resulting makefile, program or whatever to be covered by the GPL license.
+# This exception does not however invalidate any other reasons why the makefile,
+# program, whatever should not be covered the GPL.
+#
+#
+
+
+UNIT_vccprecomp = Target level precompiled Headers for Visual C++
+
+#
+# Early target processing pass #1.
+#
+# This set the internal _VCC_PCH_FILE and VCC_COMMON_OBJ_PDB properties,
+# which will be picked up by the VCCxxx tool.
+#
+define def_unit_vccprecomp_target_pre
+ $(target)_1_VCC_PCH_FILE       := $(outbase)-pch.pch
+ $(target)_1_VCC_COMMON_OBJ_PDB := $(outbase)-common-obj.pdb
+endef
+
+#
+# Early target processing pass #2.
+#
+# This sets up a rule for creating the .pch file after qt5 and similar units
+# are done modifying INCS, DEFS and company.  The 'tool' variable is defined by
+# footer-pass2-compiling-targets.kmk and is really the LD tool, but that'll
+# have to do for now.  The '-PCH' variant of the VCC tool, is defined together
+# with $(tool) and allow us to bypass the options and dependencies triggered
+# by _1_VCC_PCH_FILE and _1_VCC_COMMON_OBJ_PDB, and also make sure we don't get
+# circular dependencies by way of kDepObj and the debug info.
+#
+define def_unit_vccprecomp_target_pre_2
+ local source := $($(target)_PCH_HDR)
+ $(source)_TOOL := $(tool)-PCH
+ local suff   := $(suffix $(source))
+ local type   := CXX
+ $(kb-src-one 2)
+endef
+
