diff --git a/.gitignore b/.gitignore
index 89492fd97746204b7073dfdf2e9c0cb7e288ed1e..f5db603a6a5462b4bcd36f0872b76756145f16d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,7 @@ _darcs/
 /driver/ghc/dist/
 /driver/haddock/dist/
 /driver/ghci/dist/
+/includes/dist/
 /includes/dist-*/
 /libffi/dist-install/
 /libraries/*/dist-boot/
@@ -128,9 +129,6 @@ _darcs/
 /ghc.spec
 /ghc/ghc-bin.cabal
 /includes/dist/
-/includes/ghcautoconf.h
-/includes/ghcplatform.h
-/includes/ghcversion.h
 /index.html
 /inplace/
 /libffi/build/
diff --git a/compiler/HsVersions.h b/compiler/HsVersions.h
index 0b7665429da1dd0e6d5c1d91d5b53e5155bb1352..daeec9dd3da0cf80951aa2bfda8cd8cbb7209eb4 100644
--- a/compiler/HsVersions.h
+++ b/compiler/HsVersions.h
@@ -9,14 +9,10 @@ you will screw up the layout where they are used in case expressions!
 
 #endif
 
-/* Pull in all the platform defines for this build (foo_HOST_ARCH etc.) */
-#include "ghc_boot_platform.h"
-
-/* Pull in the autoconf defines (HAVE_FOO), but don't include
- * ghcconfig.h, because that will include ghcplatform.h which has the
- * wrong platform settings for the compiler (it has the platform
- * settings for the target plat instead). */
-#include "ghcautoconf.h"
+/* Pull in the autoconf defines (HAVE_FOO), and all the platform defines
+ * for this build (foo_HOST_ARCH etc.)
+ */
+#include "ghcconfig.h"
 
 #define GLOBAL_VAR(name,value,ty)  \
 {-# NOINLINE name #-};             \
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index ea12b5563defe2709ef06135bcc4fb885ca7ce59..7e21924c343eb57c76511727740fa03313646614 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -162,7 +162,7 @@ Library
             if flag(stage3)
                 Include-Dirs: stage2
 
-    Install-Includes: HsVersions.h, ghc_boot_platform.h
+    Install-Includes: HsVersions.h
 
     c-sources:
         parser/cutils.c
diff --git a/compiler/ghc.mk b/compiler/ghc.mk
index 441b6989727fdb0f58d94a3000a8c171c07100f1..3f94e879267c90fd5f542a0eb32399386886244c 100644
--- a/compiler/ghc.mk
+++ b/compiler/ghc.mk
@@ -29,20 +29,23 @@ compiler_stage1_C_FILES_NODEPS = compiler/parser/cutils.c
 # we just skip the check.
 compiler_NO_CHECK = YES
 
+dec1 = 0
+dec2 = 1
+dec3 = 2
+
 ifneq "$(BINDIST)" "YES"
-compiler/stage1/package-data.mk : compiler/stage1/build/Config.hs
-compiler/stage2/package-data.mk : compiler/stage2/build/Config.hs
-compiler/stage3/package-data.mk : compiler/stage3/build/Config.hs
-
-compiler/stage1/build/PlatformConstants.o: $(includes_GHCCONSTANTS_HASKELL_TYPE)
-compiler/stage2/build/PlatformConstants.o: $(includes_GHCCONSTANTS_HASKELL_TYPE)
-compiler/stage3/build/PlatformConstants.o: $(includes_GHCCONSTANTS_HASKELL_TYPE)
-compiler/stage1/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_EXPORTS)
-compiler/stage2/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_EXPORTS)
-compiler/stage3/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_EXPORTS)
-compiler/stage1/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_WRAPPERS)
-compiler/stage2/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_WRAPPERS)
-compiler/stage3/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_WRAPPERS)
+
+$(foreach n,1 2 3, \
+    $(eval compiler/stage$n/package-data.mk : $(includes_$(dec$n)_H_PLATFORM)) \
+    $(eval compiler/stage$n/package-data.mk : $(includes_$(dec$n)_H_CONFIG)) \
+  )
+
+$(foreach n,1 2 3, \
+    $(eval compiler/stage$n/package-data.mk : compiler/stage$n/build/Config.hs) \
+    $(eval compiler/stage$n/build/PlatformConstants.o : $(includes_GHCCONSTANTS_HASKELL_TYPE)) \
+    $(eval compiler/stage$n/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_EXPORTS)) \
+    $(eval compiler/stage$n/build/DynFlags.o: $(includes_GHCCONSTANTS_HASKELL_WRAPPERS)) \
+  )
 endif
 
 compiler/stage%/build/Config.hs : mk/config.mk mk/project.mk | $$(dir $$@)/.
@@ -62,7 +65,7 @@ compiler/stage%/build/Config.hs : mk/config.mk mk/project.mk | $$(dir $$@)/.
 	@echo                                                               >> $@
 	@echo 'import GHC.Version'                                          >> $@
 	@echo                                                               >> $@
-	@echo '#include "ghc_boot_platform.h"'                              >> $@
+	@echo '#include "ghcplatform.h"'                                    >> $@
 	@echo                                                               >> $@
 	@echo 'cBuildPlatformString :: String'                              >> $@
 	@echo 'cBuildPlatformString = BuildPlatform_NAME'                   >> $@
@@ -80,82 +83,6 @@ compiler/stage%/build/Config.hs : mk/config.mk mk/project.mk | $$(dir $$@)/.
 	@echo 'cStage                = show (STAGE :: Int)'                 >> $@
 	@echo done.
 
-# -----------------------------------------------------------------------------
-# Create platform includes
-
-# Here we generate a little header file containing CPP symbols that GHC
-# uses to determine which platform it is building on/for.  The platforms
-# can differ between stage1 and stage2 if we're cross-compiling, so we
-# need one of these header files per stage.
-
-PLATFORM_H = ghc_boot_platform.h
-
-compiler/stage1/$(PLATFORM_H) : mk/config.mk mk/project.mk | $$(dir $$@)/.
-	$(call removeFiles,$@)
-	@echo "Creating $@..."
-	@echo "#if !defined(__PLATFORM_H__)"                     >> $@
-	@echo "#define __PLATFORM_H__"                           >> $@
-	@echo                                                    >> $@
-	@echo "#define BuildPlatform_NAME  \"$(BUILDPLATFORM)\""  >> $@
-	@echo "#define HostPlatform_NAME   \"$(HOSTPLATFORM)\""   >> $@
-	@echo                                                     >> $@
-	@echo "#define $(BuildPlatform_CPP)_BUILD 1"              >> $@
-	@echo "#define $(HostPlatform_CPP)_HOST 1"                >> $@
-	@echo                                                     >> $@
-	@echo "#define $(BuildArch_CPP)_BUILD_ARCH 1"             >> $@
-	@echo "#define $(HostArch_CPP)_HOST_ARCH 1"               >> $@
-	@echo "#define BUILD_ARCH \"$(BuildArch_CPP)\""           >> $@
-	@echo "#define HOST_ARCH \"$(HostArch_CPP)\""             >> $@
-	@echo                                                     >> $@
-	@echo "#define $(BuildOS_CPP)_BUILD_OS 1"                 >> $@
-	@echo "#define $(HostOS_CPP)_HOST_OS 1"                   >> $@
-	@echo "#define BUILD_OS \"$(BuildOS_CPP)\""               >> $@
-	@echo "#define HOST_OS \"$(HostOS_CPP)\""                 >> $@
-	@echo                                                     >> $@
-	@echo "#define $(BuildVendor_CPP)_BUILD_VENDOR 1"         >> $@
-	@echo "#define $(HostVendor_CPP)_HOST_VENDOR 1"           >> $@
-	@echo "#define BUILD_VENDOR \"$(BuildVendor_CPP)\""       >> $@
-	@echo "#define HOST_VENDOR \"$(HostVendor_CPP)\""         >> $@
-	@echo                                                     >> $@
-	@echo "#endif /* __PLATFORM_H__ */"                       >> $@
-	@echo "Done."
-
-# For stage2 and above, the BUILD platform is the HOST of stage1, and
-# the HOST platform is the TARGET of stage1.  The TARGET remains the same
-# (stage1 is the cross-compiler, not stage2).
-compiler/stage2/$(PLATFORM_H) : mk/config.mk mk/project.mk | $$(dir $$@)/.
-	$(call removeFiles,$@)
-	@echo "Creating $@..."
-	@echo "#if !defined(__PLATFORM_H__)"                      >> $@
-	@echo "#define __PLATFORM_H__"                            >> $@
-	@echo                                                     >> $@
-	@echo "#define BuildPlatform_NAME  \"$(HOSTPLATFORM)\""   >> $@
-	@echo "#define HostPlatform_NAME   \"$(TARGETPLATFORM)\"" >> $@
-	@echo                                                     >> $@
-	@echo "#define $(HostPlatform_CPP)_BUILD 1"               >> $@
-	@echo "#define $(TargetPlatform_CPP)_HOST 1"              >> $@
-	@echo                                                     >> $@
-	@echo "#define $(HostArch_CPP)_BUILD_ARCH 1"              >> $@
-	@echo "#define $(TargetArch_CPP)_HOST_ARCH 1"             >> $@
-	@echo "#define BUILD_ARCH \"$(HostArch_CPP)\""            >> $@
-	@echo "#define HOST_ARCH \"$(TargetArch_CPP)\""           >> $@
-	@echo                                                     >> $@
-	@echo "#define $(HostOS_CPP)_BUILD_OS 1"                  >> $@
-	@echo "#define $(TargetOS_CPP)_HOST_OS 1"                 >> $@
-	@echo "#define BUILD_OS \"$(HostOS_CPP)\""                >> $@
-	@echo "#define HOST_OS \"$(TargetOS_CPP)\""               >> $@
-	@echo                                                     >> $@
-	@echo "#define $(HostVendor_CPP)_BUILD_VENDOR 1"          >> $@
-	@echo "#define $(TargetVendor_CPP)_HOST_VENDOR 1"         >> $@
-	@echo "#define BUILD_VENDOR \"$(HostVendor_CPP)\""        >> $@
-	@echo "#define HOST_VENDOR \"$(TargetVendor_CPP)\""       >> $@
-	@echo                                                     >> $@
-	@echo "#endif /* __PLATFORM_H__ */"                       >> $@
-	@echo "Done."
-
-compiler/stage3/$(PLATFORM_H) : compiler/stage2/$(PLATFORM_H)
-	"$(CP)" $< $@
-
 # ----------------------------------------------------------------------------
 #		Generate supporting stuff for prelude/PrimOp.hs
 #		from prelude/primops.txt
@@ -180,18 +107,16 @@ PRIMOP_BITS_STAGE1 = $(addprefix compiler/stage1/build/,$(PRIMOP_BITS_NAMES))
 PRIMOP_BITS_STAGE2 = $(addprefix compiler/stage2/build/,$(PRIMOP_BITS_NAMES))
 PRIMOP_BITS_STAGE3 = $(addprefix compiler/stage3/build/,$(PRIMOP_BITS_NAMES))
 
-compiler_CPP_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
-compiler_CPP_OPTS += ${GhcCppOpts}
-
-# We add these paths to the Haskell compiler's #include search path list since
-# we must avoid #including files by paths relative to the source file as Hadrian
-# moves the build artifacts out of the source tree. See #8040.
-compiler_HC_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
-
 define preprocessCompilerFiles
-# $0 = stage
-compiler/stage$1/build/primops.txt: compiler/prelude/primops.txt.pp
-	$$(HS_CPP) -P $$(compiler_CPP_OPTS) -Icompiler/stage$1 -x c $$< | grep -v '^#pragma GCC' > $$@
+# $1 = compiler stage (build system stage + 1)
+compiler/stage$1/build/primops.txt: \
+		compiler/prelude/primops.txt.pp \
+		$(includes_$(dec$1)_H_CONFIG) \
+		$(includes_$(dec$1)_H_PLATFORM)
+	$$(HS_CPP) -P $$(compiler_CPP_OPTS) \
+		-Icompiler/stage$1 \
+		-I$(BUILD_$(dec$1)_INCLUDE_DIR) \
+		-x c $$< | grep -v '^#pragma GCC' > $$@
 
 compiler/stage$1/build/primop-data-decl.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE)
 	"$$(genprimopcode_INPLACE)" --data-decl          < $$< > $$@
@@ -389,6 +314,17 @@ compiler_stage2_CONFIGURE_OPTS += --disable-library-for-ghci
 compiler_stage3_CONFIGURE_OPTS += --disable-library-for-ghci
 
 # after build-package, because that sets compiler_stage1_HC_OPTS:
+
+compiler_CPP_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
+$(foreach n,1 2 3,$(eval compiler_stage$n_CPP_OPTS += -I$(BUILD_$(dec$n)_INCLUDE_DIR)))
+compiler_CPP_OPTS += ${GhcCppOpts}
+
+# We add these paths to the Haskell compiler's #include search path list since
+# we must avoid #including files by paths relative to the source file as Hadrian
+# moves the build artifacts out of the source tree. See #8040.
+compiler_HC_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
+$(foreach n,1 2 3,$(eval compiler_stage$n_HC_OPTS += -I$(BUILD_$(dec$n)_INCLUDE_DIR)))
+
 ifeq "$(V)" "0"
 compiler_stage1_HC_OPTS += $(filter-out -Rghc-timing,$(GhcHcOpts)) $(GhcStage1HcOpts)
 compiler_stage2_HC_OPTS += $(filter-out -Rghc-timing,$(GhcHcOpts)) $(GhcStage2HcOpts)
@@ -401,12 +337,10 @@ endif
 
 ifneq "$(BINDIST)" "YES"
 
-$(compiler_stage1_depfile_haskell) : compiler/stage1/$(PLATFORM_H)
-$(compiler_stage2_depfile_haskell) : compiler/stage2/$(PLATFORM_H)
-$(compiler_stage3_depfile_haskell) : compiler/stage3/$(PLATFORM_H)
+$(compiler_stage1_depfile_haskell) : $(includes_0_H_CONFIG) $(includes_0_H_PLATFORM)
+$(compiler_stage2_depfile_haskell) : $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM)
+$(compiler_stage3_depfile_haskell) : $(includes_2_H_CONFIG) $(includes_2_H_PLATFORM)
 
-COMPILER_INCLUDES_DEPS += $(includes_H_CONFIG)
-COMPILER_INCLUDES_DEPS += $(includes_H_PLATFORM)
 COMPILER_INCLUDES_DEPS += $(includes_GHCCONSTANTS)
 COMPILER_INCLUDES_DEPS += $(includes_GHCCONSTANTS_HASKELL_TYPE)
 COMPILER_INCLUDES_DEPS += $(includes_GHCCONSTANTS_HASKELL_WRAPPERS)
diff --git a/ghc.mk b/ghc.mk
index 677508de8e6230f8d3ea2b8deed92da6c07dcd59..cb6bbb87a0f7ddb3c372fda2284161f545487fc5 100644
--- a/ghc.mk
+++ b/ghc.mk
@@ -1023,6 +1023,9 @@ $(eval $(call bindist-list,.,\
     $(BINDIST_EXTRAS) \
     includes/Makefile \
     $(includes_H_FILES) \
+    $(includes_1_H_CONFIG) \
+    $(includes_1_H_PLATFORM) \
+    $(includes_1_H_VERSION) \
     $(includes_DERIVEDCONSTANTS) \
     $(includes_GHCCONSTANTS) \
     $(libffi_HEADERS) \
@@ -1064,7 +1067,7 @@ BIN_DIST_MK = $(BIN_DIST_PREP_DIR)/bindist.mk
 #
 # See Note [No stage2 packages when CrossCompiling or Stage1Only].
 
-unix-binary-dist-prep:
+unix-binary-dist-prep: $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) $(includes_1_H_VERSION)
 	$(call removeTrees,bindistprep/)
 	"$(MKDIRHIER)" $(BIN_DIST_PREP_DIR)
 	set -e; for i in packages LICENSE compiler ghc rts libraries utils docs libffi includes driver mk rules Makefile aclocal.m4 config.sub config.guess install-sh llvm-targets llvm-passes ghc.mk inplace distrib/configure.ac distrib/README distrib/INSTALL; do ln -s ../../$$i $(BIN_DIST_PREP_DIR)/; done
@@ -1303,9 +1306,9 @@ CLEAN_FILES += compiler/ghc.cabal.old
 # as they may still be in old GHC trees:
 CLEAN_FILES += includes/GHCConstants.h
 CLEAN_FILES += includes/DerivedConstants.h
-CLEAN_FILES += includes/ghcautoconf.h
-CLEAN_FILES += includes/ghcplatform.h
-CLEAN_FILES += includes/ghcversion.h
+$(foreach n,0 1 2, \
+    $(foreach h,$(includes_$n_H_CONFIG) $(includes_$n_H_PLATFORM) $(includes_$n_H_VERSION), \
+        $(eval CLEAN_FILES += $h)))
 CLEAN_FILES += $(includes_SETTINGS)
 CLEAN_FILES += utils/ghc-pkg/Version.hs
 CLEAN_FILES += compiler/prelude/primops.txt
@@ -1441,7 +1444,6 @@ maintainer-clean : distclean
 
 .PHONY: bootstrapping-files
 # See https://gitlab.haskell.org/ghc/ghc/wikis/building/porting
-bootstrapping-files: $(includes_H_CONFIG)
 bootstrapping-files: $(includes_DERIVEDCONSTANTS)
 bootstrapping-files: $(includes_GHCCONSTANTS)
 bootstrapping-files: $(libffi_HEADERS)
diff --git a/ghc/ghc.mk b/ghc/ghc.mk
index b1f9f57d819269360af551825a04bec9f32dfdea..3bff2f58c936213b1c4a311a1c9525737ccd998b 100644
--- a/ghc/ghc.mk
+++ b/ghc/ghc.mk
@@ -120,11 +120,6 @@ ghc/stage2/build/tmp/$(ghc_stage2_PROG) : $(compiler_stage2_p_LIB)
 ghc/stage2/build/tmp/$(ghc_stage2_PROG) : $(foreach lib,$(PACKAGES_STAGE1),$(libraries/$(lib)_dist-install_p_LIB))
 endif
 
-# Modules here import HsVersions.h, so we need ghc_boot_platform.h
-$(ghc_stage1_depfile_haskell) : compiler/stage1/$(PLATFORM_H)
-$(ghc_stage2_depfile_haskell) : compiler/stage2/$(PLATFORM_H)
-$(ghc_stage3_depfile_haskell) : compiler/stage3/$(PLATFORM_H)
-
 all_ghc_stage1 : $(GHC_STAGE1)
 all_ghc_stage2 : $(GHC_STAGE2)
 all_ghc_stage3 : $(GHC_STAGE3)
diff --git a/hadrian/src/Base.hs b/hadrian/src/Base.hs
index bc4eab354e7fd1c1801a6a5cd35959fcf94a76c0..f7f1029d4ee974a25d2369013c3ba8dd86d99721 100644
--- a/hadrian/src/Base.hs
+++ b/hadrian/src/Base.hs
@@ -23,7 +23,7 @@ module Base (
 
     -- * Paths
     hadrianPath, configPath, configFile, sourcePath, shakeFilesDir,
-    generatedDir, generatedPath, stageBinPath, stageLibPath, templateHscPath,
+    stageBinPath, stageLibPath, templateHscPath,
     ghcBinDeps, ghcLibDeps, includesDependencies, haddockDeps,
     relativePackageDbPath, packageDbPath, packageDbStamp, mingwStamp,
     ) where
@@ -68,22 +68,14 @@ sourcePath = hadrianPath -/- "src"
 configH :: FilePath
 configH = "mk/config.h"
 
-ghcVersionH :: Action FilePath
-ghcVersionH = generatedPath <&> (-/- "ghcversion.h")
+ghcVersionH :: Stage -> Action FilePath
+ghcVersionH stage = stageLibPath stage <&> (-/- "ghcversion.h")
 
 -- | The directory in 'buildRoot' containing the Shake database and other
 -- auxiliary files generated by Hadrian.
 shakeFilesDir :: FilePath
 shakeFilesDir = "hadrian"
 
--- | The directory in 'buildRoot' containing generated source files that are not
--- package-specific, e.g. @ghcplatform.h@.
-generatedDir :: FilePath
-generatedDir = "generated"
-
-generatedPath :: Action FilePath
-generatedPath = buildRoot <&> (-/- generatedDir)
-
 -- | Path to the package database for a given build stage, relative to the build
 -- root.
 relativePackageDbPath :: Stage -> FilePath
@@ -122,10 +114,11 @@ ghcBinDeps stage = mapM (\f -> stageLibPath stage <&> (-/- f))
     , "ghci-usage.txt"
     ]
 
-includesDependencies :: Action [FilePath]
-includesDependencies = do
-    path <- generatedPath
-    return $ (path -/-) <$> [ "ghcautoconf.h", "ghcplatform.h", "ghcversion.h" ]
+includesDependencies :: Stage -> Action [FilePath]
+includesDependencies stage = do
+    p <- stageLibPath stage
+    pure $ (p -/-) <$>
+      [ "ghcautoconf.h", "ghcplatform.h", "ghcversion.h" ]
 
 -- | Files the `haddock` binary depends on
 haddockDeps :: Stage -> Action [FilePath]
diff --git a/hadrian/src/Builder.hs b/hadrian/src/Builder.hs
index 587c62fa160e5340d3f9923e8d5514e4e3a24001..34027d7bbb0ae9f10a8ef92542d2a5062f300562 100644
--- a/hadrian/src/Builder.hs
+++ b/hadrian/src/Builder.hs
@@ -176,12 +176,12 @@ instance H.Builder Builder where
         Autoreconf dir -> return [dir -/- "configure.ac"]
         Configure  dir -> return [dir -/- "configure"]
 
-        Ghc _ Stage0 -> generatedGhcDependencies Stage0
+        Ghc _ Stage0 -> includesDependencies Stage0
         Ghc _ stage -> do
             root <- buildRoot
             touchyPath <- programPath (vanillaContext Stage0 touchy)
             unlitPath  <- builderPath Unlit
-            ghcgens <- generatedGhcDependencies stage
+            ghcgens <- includesDependencies stage
 
             -- GHC from the previous stage is used to build artifacts in the
             -- current stage. Need the previous stage's GHC deps.
diff --git a/hadrian/src/Packages.hs b/hadrian/src/Packages.hs
index 53ecb6897e48a307fd8a3abf568f05e929877664..c4ae780fb33bde41ed9faa6cce286e00cf2f8cc9 100644
--- a/hadrian/src/Packages.hs
+++ b/hadrian/src/Packages.hs
@@ -13,7 +13,7 @@ module Packages (
     -- * Package information
     programName, nonHsMainPackage, autogenPath, programPath, timeoutPath,
     rtsContext, rtsBuildPath, libffiBuildPath, libffiLibraryName,
-    generatedGhcDependencies, ensureConfigured
+    ensureConfigured
     ) where
 
 import Hadrian.Package
@@ -216,12 +216,3 @@ libffiLibraryName = do
         (True , False) -> "ffi"
         (False, False) -> "Cffi"
         (_    , True ) -> "Cffi-6"
-
--- | Generated header files required by GHC in runtime.
-generatedGhcDependencies :: Stage -> Action [FilePath]
-generatedGhcDependencies stage = do
-    let context = vanillaContext stage compiler
-    bh <- buildPath   context <&> (-/- "ghc_boot_platform.h")
-    ch <- contextPath context <&> (-/- "ghc_boot_platform.h")
-    is <- includesDependencies
-    return $ is ++ [bh, ch]
diff --git a/hadrian/src/Rules.hs b/hadrian/src/Rules.hs
index e72623d4cec0c901a8207225e2f7204af7fc48af..3f6397fdccc4acf9ca17b5ae9d10e4b512be9bf2 100644
--- a/hadrian/src/Rules.hs
+++ b/hadrian/src/Rules.hs
@@ -46,7 +46,7 @@ toolArgsTarget = do
                              (Ghc ToolArgs Stage0) [] ["ignored"]
 
     -- need the autogenerated files so that they are precompiled
-    generatedGhcDependencies Stage0 >>= need
+    includesDependencies Stage0 >>= need
     interpret fake_target Rules.Generate.compilerDependencies >>= need
 
     root <- buildRoot
diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs
index ef3d8aa3b404cc8c62cefc077cf08c471e033bc5..c2c3c1437218ef1497604767ecc5aedf020889ee 100644
--- a/hadrian/src/Rules/Generate.hs
+++ b/hadrian/src/Rules/Generate.hs
@@ -1,9 +1,11 @@
 module Rules.Generate (
     isGeneratedCmmFile, compilerDependencies, generatePackageCode,
-    generateRules, copyRules, generatedDependencies, generatedGhcDependencies,
+    generateRules, copyRules, generatedDependencies,
     ghcPrimDependencies
     ) where
 
+import Data.Foldable (for_)
+
 import Base
 import qualified Context
 import Expression
@@ -16,6 +18,7 @@ import Packages
 import Rules.Gmp
 import Rules.Libffi
 import Settings
+import Settings.Builders.DeriveConstants (deriveConstantsPairs)
 import Target
 import Utilities
 
@@ -38,8 +41,8 @@ ghcPrimDependencies = do
     path  <- expr $ buildPath (vanillaContext stage ghcPrim)
     return [path -/- "GHC/Prim.hs", path -/- "GHC/PrimopWrappers.hs"]
 
-derivedConstantsDependencies :: [FilePath]
-derivedConstantsDependencies = fmap (generatedDir -/-)
+derivedConstantsFiles :: [FilePath]
+derivedConstantsFiles =
     [ "DerivedConstants.h"
     , "GHCConstantsHaskellExports.hs"
     , "GHCConstantsHaskellType.hs"
@@ -47,13 +50,13 @@ derivedConstantsDependencies = fmap (generatedDir -/-)
 
 compilerDependencies :: Expr [FilePath]
 compilerDependencies = do
-    root    <- getBuildRoot
     stage   <- getStage
     isGmp   <- (== integerGmp) <$> getIntegerPackage
     ghcPath <- expr $ buildPath (vanillaContext stage compiler)
     gmpPath <- expr gmpBuildPath
     rtsPath <- expr (rtsBuildPath stage)
-    mconcat [ return ((root -/-) <$> derivedConstantsDependencies)
+    libDir <- expr $ stageLibPath stage
+    mconcat [ return $ (libDir -/-) <$> derivedConstantsFiles
             , notStage0 ? isGmp ? return [gmpPath -/- gmpLibraryH]
             , notStage0 ? return ((rtsPath -/-) <$> libffiHeaderFiles)
             , return $ fmap (ghcPath -/-)
@@ -75,15 +78,15 @@ compilerDependencies = do
 
 generatedDependencies :: Expr [FilePath]
 generatedDependencies = do
-    root     <- getBuildRoot
     stage    <- getStage
     rtsPath  <- expr (rtsBuildPath stage)
-    includes <- expr includesDependencies
+    includes <- expr $ includesDependencies stage
+    libDir <- expr $ stageLibPath stage
     mconcat [ package compiler ? compilerDependencies
             , package ghcPrim  ? ghcPrimDependencies
             , package rts      ? return (fmap (rtsPath -/-) libffiHeaderFiles
                 ++ includes
-                ++ fmap (root -/-) derivedConstantsDependencies)
+                ++ ((libDir -/-) <$> derivedConstantsFiles))
             , stage0 ? return includes ]
 
 generate :: FilePath -> Context -> Expr String -> Action ()
@@ -121,21 +124,18 @@ generatePackageCode context@(Context stage pkg _) = do
 
     when (pkg == compiler) $ do
         root -/- primopsTxt stage %> \file -> do
-            includes <- includesDependencies
+            includes <- includesDependencies stage
             need $ [primopsSource] ++ includes
             build $ target context HsCpp [primopsSource] [file]
 
-        root -/- stageString stage -/- "**" -/- "ghc_boot_platform.h" %>
-            go generateGhcBootPlatformH
-
     when (pkg == rts) $ do
         root -/- "**" -/- dir -/- "cmm/AutoApply.cmm" %> \file ->
             build $ target context GenApply [] [file]
         -- TODO: This should be fixed properly, e.g. generated here on demand.
-        (root -/- "**" -/- dir -/- "DerivedConstants.h") <~ (buildRoot <&> (-/- generatedDir))
-        (root -/- "**" -/- dir -/- "ghcautoconf.h") <~ (buildRoot <&> (-/- generatedDir))
-        (root -/- "**" -/- dir -/- "ghcplatform.h") <~ (buildRoot <&> (-/- generatedDir))
-        (root -/- "**" -/- dir -/- "ghcversion.h") <~ (buildRoot <&> (-/- generatedDir))
+        (root -/- "**" -/- dir -/- "DerivedConstants.h") <~ stageLibPath stage
+        (root -/- "**" -/- dir -/- "ghcautoconf.h") <~ stageLibPath stage
+        (root -/- "**" -/- dir -/- "ghcplatform.h") <~ stageLibPath stage
+        (root -/- "**" -/- dir -/- "ghcversion.h") <~ stageLibPath stage
  where
     pattern <~ mdir = pattern %> \file -> do
         dir <- mdir
@@ -162,7 +162,6 @@ copyRules = do
         prefix -/- "ghci-usage.txt"    <~ return "driver"
         prefix -/- "llvm-targets"      <~ return "."
         prefix -/- "llvm-passes"       <~ return "."
-        prefix -/- "platformConstants" <~ (buildRoot <&> (-/- generatedDir))
         prefix -/- "template-hsc.h"    <~ return (pkgPath hsc2hs)
 
         prefix -/- "html/**"           <~ return "utils/haddock/haddock-api/resources"
@@ -175,20 +174,19 @@ generateRules = do
     (root -/- "ghc-stage1") <~+ ghcWrapper Stage1
     (root -/- "ghc-stage2") <~+ ghcWrapper Stage2
 
-    priority 2.0 $ (root -/- generatedDir -/- "ghcautoconf.h") <~ generateGhcAutoconfH
-    priority 2.0 $ (root -/- generatedDir -/- "ghcplatform.h") <~ generateGhcPlatformH
-    priority 2.0 $ (root -/- generatedDir -/-  "ghcversion.h") <~ generateGhcVersionH
     forM_ [Stage0 ..] $ \stage -> do
         let prefix = root -/- stageString stage -/- "lib"
             go gen file = generate file (semiEmptyTarget stage) gen
-        priority 2.0 $ (prefix -/- "settings") %> go generateSettings
-
-    -- TODO: simplify, get rid of fake rts context
-    root -/- generatedDir -/- "**" %> \file -> do
-        withTempDir $ \dir -> build $
-            target (rtsContext Stage1) DeriveConstants [] [file, dir]
+        (prefix -/- "ghcplatform.h") %> go generateGhcPlatformH
+        (prefix -/- "settings") %> go generateSettings
+        (prefix -/- "ghcautoconf.h") %> go generateGhcAutoconfH
+        (prefix -/- "ghcversion.h") %> go generateGhcVersionH
+        -- TODO: simplify, get rid of fake rts context
+        for_ (fst <$> deriveConstantsPairs) $ \constantsFile ->
+            prefix -/- constantsFile %> \file -> do
+                withTempDir $ \dir -> build $
+                    target (rtsContext stage) DeriveConstants [] [file, dir]
   where
-    file <~  gen = file %> \out -> generate out emptyTarget gen
     file <~+ gen = file %> \out -> generate out emptyTarget gen >> makeExecutable out
 
 -- TODO: Use the Types, Luke! (drop partial function)
@@ -225,39 +223,44 @@ cppify = replaceEq '-' '_' . replaceEq '.' '_'
 generateGhcPlatformH :: Expr String
 generateGhcPlatformH = do
     trackGenerateHs
-    hostPlatform   <- getSetting HostPlatform
-    hostArch       <- getSetting HostArch
-    hostOs         <- getSetting HostOs
-    hostVendor     <- getSetting HostVendor
-    targetPlatform <- getSetting TargetPlatform
-    targetArch     <- getSetting TargetArch
-    targetOs       <- getSetting TargetOs
-    targetVendor   <- getSetting TargetVendor
+    stage    <- getStage
+    let chooseSetting x y = getSetting $ if stage == Stage0 then x else y
+    buildPlatform  <- chooseSetting BuildPlatform HostPlatform
+    buildArch      <- chooseSetting BuildArch     HostArch
+    buildOs        <- chooseSetting BuildOs       HostOs
+    buildVendor    <- chooseSetting BuildVendor   HostVendor
+    hostPlatform   <- chooseSetting HostPlatform  TargetPlatform
+    hostArch       <- chooseSetting HostArch      TargetArch
+    hostOs         <- chooseSetting HostOs        TargetOs
+    hostVendor     <- chooseSetting HostVendor    TargetVendor
     ghcUnreg       <- getFlag    GhcUnregisterised
     return . unlines $
         [ "#if !defined(__GHCPLATFORM_H__)"
         , "#define __GHCPLATFORM_H__"
         , ""
-        , "#define BuildPlatform_TYPE  " ++ cppify hostPlatform
-        , "#define HostPlatform_TYPE   " ++ cppify targetPlatform
+        , "#define BuildPlatform_NAME  " ++ show buildPlatform
+        , "#define HostPlatform_NAME   " ++ show hostPlatform
         , ""
-        , "#define " ++ cppify hostPlatform   ++ "_BUILD 1"
-        , "#define " ++ cppify targetPlatform ++ "_HOST 1"
+        , "#define BuildPlatform_TYPE  " ++ cppify buildPlatform
+        , "#define HostPlatform_TYPE   " ++ cppify hostPlatform
         , ""
-        , "#define " ++ hostArch   ++ "_BUILD_ARCH 1"
-        , "#define " ++ targetArch ++ "_HOST_ARCH 1"
-        , "#define BUILD_ARCH " ++ show hostArch
-        , "#define HOST_ARCH "  ++ show targetArch
+        , "#define " ++ cppify buildPlatform   ++ "_BUILD 1"
+        , "#define " ++ cppify hostPlatform ++ "_HOST 1"
         , ""
-        , "#define " ++ hostOs   ++ "_BUILD_OS 1"
-        , "#define " ++ targetOs ++ "_HOST_OS 1"
-        , "#define BUILD_OS " ++ show hostOs
-        , "#define HOST_OS "  ++ show targetOs
+        , "#define " ++ buildArch   ++ "_BUILD_ARCH 1"
+        , "#define " ++ hostArch ++ "_HOST_ARCH 1"
+        , "#define BUILD_ARCH " ++ show buildArch
+        , "#define HOST_ARCH "  ++ show hostArch
         , ""
-        , "#define " ++ hostVendor   ++ "_BUILD_VENDOR 1"
-        , "#define " ++ targetVendor ++ "_HOST_VENDOR 1"
-        , "#define BUILD_VENDOR " ++ show hostVendor
-        , "#define HOST_VENDOR "  ++ show targetVendor
+        , "#define " ++ buildOs   ++ "_BUILD_OS 1"
+        , "#define " ++ hostOs ++ "_HOST_OS 1"
+        , "#define BUILD_OS " ++ show buildOs
+        , "#define HOST_OS "  ++ show hostOs
+        , ""
+        , "#define " ++ buildVendor   ++ "_BUILD_VENDOR 1"
+        , "#define " ++ hostVendor ++ "_HOST_VENDOR 1"
+        , "#define BUILD_VENDOR " ++ show buildVendor
+        , "#define HOST_VENDOR "  ++ show hostVendor
         , ""
         ]
         ++
@@ -351,7 +354,7 @@ generateConfigHs = do
         , ""
         , "import GHC.Version"
         , ""
-        , "#include \"ghc_boot_platform.h\""
+        , "#include \"ghcplatform.h\""
         , ""
         , "cBuildPlatformString :: String"
         , "cBuildPlatformString = BuildPlatform_NAME"
@@ -395,47 +398,6 @@ generateGhcAutoconfH = do
             = "/* #undef " ++ takeWhile (/=' ') (drop 8 s) ++ " */"
         | otherwise = s
 
--- | Generate @ghc_boot_platform.h@ headers.
-generateGhcBootPlatformH :: Expr String
-generateGhcBootPlatformH = do
-    trackGenerateHs
-    stage <- getStage
-    let chooseSetting x y = getSetting $ if stage == Stage0 then x else y
-    buildPlatform  <- chooseSetting BuildPlatform HostPlatform
-    buildArch      <- chooseSetting BuildArch     HostArch
-    buildOs        <- chooseSetting BuildOs       HostOs
-    buildVendor    <- chooseSetting BuildVendor   HostVendor
-    hostPlatform   <- chooseSetting HostPlatform  TargetPlatform
-    hostArch       <- chooseSetting HostArch      TargetArch
-    hostOs         <- chooseSetting HostOs        TargetOs
-    hostVendor     <- chooseSetting HostVendor    TargetVendor
-    return $ unlines
-        [ "#if !defined(__PLATFORM_H__)"
-        , "#define __PLATFORM_H__"
-        , ""
-        , "#define BuildPlatform_NAME  " ++ show buildPlatform
-        , "#define HostPlatform_NAME   " ++ show hostPlatform
-        , ""
-        , "#define " ++ cppify buildPlatform  ++ "_BUILD 1"
-        , "#define " ++ cppify hostPlatform   ++ "_HOST 1"
-        , ""
-        , "#define " ++ buildArch  ++ "_BUILD_ARCH 1"
-        , "#define " ++ hostArch   ++ "_HOST_ARCH 1"
-        , "#define BUILD_ARCH "  ++ show buildArch
-        , "#define HOST_ARCH "   ++ show hostArch
-        , ""
-        , "#define " ++ buildOs  ++ "_BUILD_OS 1"
-        , "#define " ++ hostOs   ++ "_HOST_OS 1"
-        , "#define BUILD_OS "  ++ show buildOs
-        , "#define HOST_OS "   ++ show hostOs
-        , ""
-        , "#define " ++ buildVendor  ++ "_BUILD_VENDOR 1"
-        , "#define " ++ hostVendor   ++ "_HOST_VENDOR 1"
-        , "#define BUILD_VENDOR "  ++ show buildVendor
-        , "#define HOST_VENDOR "   ++ show hostVendor
-        , ""
-        , "#endif /* __PLATFORM_H__ */" ]
-
 -- | Generate @ghcversion.h@ header.
 generateGhcVersionH :: Expr String
 generateGhcVersionH = do
diff --git a/hadrian/src/Settings/Builders/Cabal.hs b/hadrian/src/Settings/Builders/Cabal.hs
index 96f67b4abf1e9038cf2bec43d337891dd46a920c..763f51636b2b7c661404d7f165f6473ae7ee9f51 100644
--- a/hadrian/src/Settings/Builders/Cabal.hs
+++ b/hadrian/src/Settings/Builders/Cabal.hs
@@ -99,15 +99,16 @@ libraryArgs = do
 configureArgs :: Args
 configureArgs = do
     top  <- expr topDirectory
-    root <- getBuildRoot
     pkg  <- getPackage
+    stage <- getStage
+    libPath <- expr $ stageLibPath stage
     let conf key expr = do
             values <- unwords <$> expr
             not (null values) ?
                 arg ("--configure-option=" ++ key ++ "=" ++ values)
         cFlags   = mconcat [ remove ["-Werror"] cArgs
                            , getStagedSettingList ConfCcArgs
-                           , arg $ "-I" ++ top -/- root -/- generatedDir
+                           , arg $ "-I" ++ libPath
                            -- See https://github.com/snowleopard/hadrian/issues/523
                            , arg $ "-iquote"
                            , arg $ top -/- pkgPath pkg
@@ -127,7 +128,7 @@ configureArgs = do
         , conf "--with-curses-libraries"  $ arg =<< getSetting CursesLibDir
         , flag CrossCompiling ? (conf "--host" $ arg =<< getSetting TargetPlatformFull)
         , conf "--with-cc" $ arg =<< getBuilderPath . (Cc CompileC) =<< getStage
-        , notStage0 ? (arg =<< ("--ghc-option=-ghcversion-file=" ++) <$> expr ((-/-) <$> topDirectory <*> ghcVersionH))]
+        , notStage0 ? (arg =<< ("--ghc-option=-ghcversion-file=" ++) <$> expr ((-/-) <$> topDirectory <*> ghcVersionH stage))]
 
 bootPackageConstraints :: Args
 bootPackageConstraints = stage0 ? do
@@ -140,8 +141,9 @@ bootPackageConstraints = stage0 ? do
 
 cppArgs :: Args
 cppArgs = do
-    root <- getBuildRoot
-    arg $ "-I" ++ root -/- generatedDir
+    stage <- getStage
+    libPath <- expr $ stageLibPath stage
+    arg $ "-I" ++ libPath
 
 withBuilderKey :: Builder -> String
 withBuilderKey b = case b of
diff --git a/hadrian/src/Settings/Builders/Common.hs b/hadrian/src/Settings/Builders/Common.hs
index 5856935fb99cdb30253e2751eea8d050d513a040..7d9e0fe716aa3f5048fdc5c980b3a406cc443309 100644
--- a/hadrian/src/Settings/Builders/Common.hs
+++ b/hadrian/src/Settings/Builders/Common.hs
@@ -22,15 +22,16 @@ import UserSettings
 cIncludeArgs :: Args
 cIncludeArgs = do
     pkg     <- getPackage
-    root    <- getBuildRoot
     path    <- getBuildPath
     incDirs <- getContextData includeDirs
     depDirs <- getContextData depIncludeDirs
+    stage <- getStage
     iconvIncludeDir <- getSetting IconvIncludeDir
     gmpIncludeDir   <- getSetting GmpIncludeDir
     ffiIncludeDir   <- getSetting FfiIncludeDir
+    libPath <- expr $ stageLibPath stage
     mconcat [ notStage0 ||^ package compiler ? arg "-Iincludes"
-            , arg $ "-I" ++ root -/- generatedDir
+            , arg $ "-I" ++ libPath
             , arg $ "-I" ++ path
             , pure . map ("-I"++) . filter (/= "") $ [iconvIncludeDir, gmpIncludeDir]
             , flag UseSystemFfi ? arg ("-I" ++ ffiIncludeDir)
diff --git a/hadrian/src/Settings/Builders/DeriveConstants.hs b/hadrian/src/Settings/Builders/DeriveConstants.hs
index 90068b3c4a87e6fe263c645951cdcf418eedf5d9..0747162f43d8371ec1ef3b0ee324d58ffea82f77 100644
--- a/hadrian/src/Settings/Builders/DeriveConstants.hs
+++ b/hadrian/src/Settings/Builders/DeriveConstants.hs
@@ -1,8 +1,19 @@
-module Settings.Builders.DeriveConstants (deriveConstantsBuilderArgs) where
+module Settings.Builders.DeriveConstants (
+    deriveConstantsBuilderArgs, deriveConstantsPairs
+    ) where
 
 import Builder
 import Settings.Builders.Common
 
+deriveConstantsPairs :: [(String, String)]
+deriveConstantsPairs =
+  [ ("DerivedConstants.h", "--gen-header")
+  , ("GHCConstantsHaskellType.hs", "--gen-haskell-type")
+  , ("platformConstants", "--gen-haskell-value")
+  , ("GHCConstantsHaskellWrappers.hs", "--gen-haskell-wrappers")
+  , ("GHCConstantsHaskellExports.hs", "--gen-haskell-exports")
+  ]
+
 -- TODO: do we need to support `includes_CC_OPTS += -DDYNAMIC_BY_DEFAULT`?
 deriveConstantsBuilderArgs :: Args
 deriveConstantsBuilderArgs = builder DeriveConstants ? do
@@ -12,11 +23,8 @@ deriveConstantsBuilderArgs = builder DeriveConstants ? do
             [a, b] -> (a, b)
             _      -> error $ "DeriveConstants: expected two outputs, got " ++ show outs
     mconcat
-        [ output "**/DerivedConstants.h"             ? arg "--gen-header"
-        , output "**/GHCConstantsHaskellType.hs"     ? arg "--gen-haskell-type"
-        , output "**/platformConstants"              ? arg "--gen-haskell-value"
-        , output "**/GHCConstantsHaskellWrappers.hs" ? arg "--gen-haskell-wrappers"
-        , output "**/GHCConstantsHaskellExports.hs"  ? arg "--gen-haskell-exports"
+        [ mconcat $ flip fmap deriveConstantsPairs $ \(fileName, flag) ->
+            output ("**/" ++ fileName) ? arg flag
         , arg "-o", arg outputFile
         , arg "--tmpdir", arg tempDir
         , arg "--gcc-program", arg =<< getBuilderPath (Cc CompileC Stage1)
@@ -28,13 +36,14 @@ deriveConstantsBuilderArgs = builder DeriveConstants ? do
 
 includeCcArgs :: Args
 includeCcArgs = do
-    root <- getBuildRoot
+    stage <- getStage
+    libPath <- expr $ stageLibPath stage
     mconcat [ cArgs
             , cWarnings
             , getSettingList $ ConfCcArgs Stage1
             , flag GhcUnregisterised ? arg "-DUSE_MINIINTERPRETER"
             , arg "-Irts"
             , arg "-Iincludes"
-            , arg $ "-I" ++ root -/- generatedDir
+            , arg $ "-I" ++ libPath
             , notM ghcWithSMP ? arg "-DNOSMP"
             , arg "-fcommon" ]
diff --git a/hadrian/src/Settings/Builders/Ghc.hs b/hadrian/src/Settings/Builders/Ghc.hs
index 2db62aa4e1dc76bbd47723ce30802e0722f65bf0..54315484c10d196b4eb0c4c8ce3b095b33612249 100644
--- a/hadrian/src/Settings/Builders/Ghc.hs
+++ b/hadrian/src/Settings/Builders/Ghc.hs
@@ -161,7 +161,8 @@ commonGhcArgs :: Args
 commonGhcArgs = do
     way  <- getWay
     path <- getBuildPath
-    ghcVersion <- expr ghcVersionH
+    stage <- getStage
+    ghcVersion <- expr $ ghcVersionH stage
     mconcat [ arg "-hisuf", arg $ hisuf way
             , arg "-osuf" , arg $  osuf way
             , arg "-hcsuf", arg $ hcsuf way
@@ -208,10 +209,11 @@ includeGhcArgs :: Args
 includeGhcArgs = do
     pkg     <- getPackage
     path    <- getBuildPath
-    root    <- getBuildRoot
     context <- getContext
     srcDirs <- getContextData srcDirs
     autogen <- expr $ autogenPath context
+    stage <- getStage
+    libPath <- expr $ stageLibPath stage
     let cabalMacros = autogen -/- "cabal_macros.h"
     expr $ need [cabalMacros]
     mconcat [ arg "-i"
@@ -219,6 +221,6 @@ includeGhcArgs = do
             , arg $ "-i" ++ autogen
             , pure [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ]
             , cIncludeArgs
-            , arg $      "-I" ++ root -/- generatedDir
-            , arg $ "-optc-I" ++ root -/- generatedDir
+            , arg $      "-I" ++ libPath
+            , arg $ "-optc-I" ++ libPath
             , pure ["-optP-include", "-optP" ++ cabalMacros] ]
diff --git a/hadrian/src/Settings/Builders/HsCpp.hs b/hadrian/src/Settings/Builders/HsCpp.hs
index e33061c9d033ebb0504489c71eab1e4fec4b5aed..4595e2098e66b89b3884ac219bfec05029b0008b 100644
--- a/hadrian/src/Settings/Builders/HsCpp.hs
+++ b/hadrian/src/Settings/Builders/HsCpp.hs
@@ -6,12 +6,12 @@ import Settings.Builders.Common
 hsCppBuilderArgs :: Args
 hsCppBuilderArgs = builder HsCpp ? do
     stage   <- getStage
-    root    <- getBuildRoot
     ghcPath <- expr $ buildPath (vanillaContext stage compiler)
+    libPath <- expr $ stageLibPath stage
     mconcat [ getSettingList HsCppArgs
             , arg "-P"
             , arg "-Iincludes"
-            , arg $ "-I" ++ root -/- generatedDir
+            , arg $ "-I" ++ libPath
             , arg $ "-I" ++ ghcPath
             , arg "-x", arg "c"
             , arg =<< getInput ]
diff --git a/includes/ghc.mk b/includes/ghc.mk
index 81e7483756c9febc5700dddf306e476f3547835e..52b875cc286dec28a42b13dab13a412f689d15ed 100644
--- a/includes/ghc.mk
+++ b/includes/ghc.mk
@@ -13,10 +13,21 @@
 #
 # Header files built from the configure script's findings
 #
-# XXX: these should go in includes/dist/build?
-includes_H_CONFIG   = includes/ghcautoconf.h
-includes_H_PLATFORM = includes/ghcplatform.h
-includes_H_VERSION  = includes/ghcversion.h
+includes_0_H_CONFIG   = includes/dist/build/ghcautoconf.h
+includes_1_H_CONFIG   = includes/dist-install/build/ghcautoconf.h
+includes_2_H_CONFIG   = $(includes_1_H_CONFIG)
+
+includes_0_H_PLATFORM = includes/dist/build/ghcplatform.h
+includes_1_H_PLATFORM = includes/dist-install/build/ghcplatform.h
+includes_2_H_PLATFORM = $(includes_1_H_PLATFORM)
+
+includes_0_H_VERSION  = includes/dist/build/ghcversion.h
+includes_1_H_VERSION  = includes/dist-install/build/ghcversion.h
+includes_2_H_VERSION  = $(includes_1_H_VERSION)
+
+BUILD_0_INCLUDE_DIR = includes/dist/build
+BUILD_1_INCLUDE_DIR = includes/dist-install/build
+BUILD_2_INCLUDE_DIR = $(BUILD_1_INCLUDE_DIR)
 
 #
 # All header files are in includes/{one of these subdirectories}
@@ -44,6 +55,7 @@ includes_CC_OPTS += -DUSE_MINIINTERPRETER
 endif
 
 includes_CC_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
+includes_CC_OPTS += -I$(BUILD_1_INCLUDE_DIR)
 includes_CC_OPTS += -Irts
 
 ifneq "$(GhcWithSMP)" "YES"
@@ -54,110 +66,164 @@ ifeq "$(DYNAMIC_BY_DEFAULT)" "YES"
 includes_CC_OPTS += -DDYNAMIC_BY_DEFAULT
 endif
 
-
-$(includes_H_VERSION) : mk/project.mk | $$(dir $$@)/.
-	@echo "Creating $@..."
-	@echo "#if !defined(__GHCVERSION_H__)"  > $@
-	@echo "#define __GHCVERSION_H__" >> $@
-	@echo >> $@
-	@echo "#define __GLASGOW_HASKELL__ $(ProjectVersionInt)" >> $@
-	@echo >> $@
-	@if [ -n "$(ProjectPatchLevel1)" ]; then \
-	  echo "#define __GLASGOW_HASKELL_PATCHLEVEL1__ $(ProjectPatchLevel1)" >> $@; \
+define includesHeaderVersion
+# $1 = stage
+$$(includes_$1_H_VERSION) : mk/project.mk | $$$$(dir $$$$@)/.
+	$$(call removeFiles,$$@)
+	@echo "Creating $$@..."
+	@echo "#if !defined(__GHCVERSION_H__)"  > $$@
+	@echo "#define __GHCVERSION_H__" >> $$@
+	@echo >> $$@
+	@echo "#define __GLASGOW_HASKELL__ $$(ProjectVersionInt)" >> $$@
+	@echo >> $$@
+	@if [ -n "$$(ProjectPatchLevel1)" ]; then \
+	  echo "#define __GLASGOW_HASKELL_PATCHLEVEL1__ $$(ProjectPatchLevel1)" >> $$@; \
 	fi
-	@if [ -n "$(ProjectPatchLevel2)" ]; then \
-	  echo "#define __GLASGOW_HASKELL_PATCHLEVEL2__ $(ProjectPatchLevel2)" >> $@; \
+	@if [ -n "$$(ProjectPatchLevel2)" ]; then \
+	  echo "#define __GLASGOW_HASKELL_PATCHLEVEL2__ $$(ProjectPatchLevel2)" >> $$@; \
 	fi
-	@echo >> $@
-	@echo '#define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\'      >> $@
-	@echo '   ((ma)*100+(mi)) <  __GLASGOW_HASKELL__ || \'             >> $@
-	@echo '   ((ma)*100+(mi)) == __GLASGOW_HASKELL__    \'             >> $@
-	@echo '          && (pl1) <  __GLASGOW_HASKELL_PATCHLEVEL1__ || \' >> $@
-	@echo '   ((ma)*100+(mi)) == __GLASGOW_HASKELL__    \'             >> $@
-	@echo '          && (pl1) == __GLASGOW_HASKELL_PATCHLEVEL1__ \'    >> $@
-	@echo '          && (pl2) <= __GLASGOW_HASKELL_PATCHLEVEL2__ )'    >> $@
-	@echo >> $@
-	@echo "#endif /* __GHCVERSION_H__ */"          >> $@
+	@echo >> $$@
+	@echo '#define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\'      >> $$@
+	@echo '   ((ma)*100+(mi)) <  __GLASGOW_HASKELL__ || \'             >> $$@
+	@echo '   ((ma)*100+(mi)) == __GLASGOW_HASKELL__    \'             >> $$@
+	@echo '          && (pl1) <  __GLASGOW_HASKELL_PATCHLEVEL1__ || \' >> $$@
+	@echo '   ((ma)*100+(mi)) == __GLASGOW_HASKELL__    \'             >> $$@
+	@echo '          && (pl1) == __GLASGOW_HASKELL_PATCHLEVEL1__ \'    >> $$@
+	@echo '          && (pl2) <= __GLASGOW_HASKELL_PATCHLEVEL2__ )'    >> $$@
+	@echo >> $$@
+	@echo "#endif /* __GHCVERSION_H__ */"          >> $$@
 	@echo "Done."
 
-ifneq "$(BINDIST)" "YES"
-
-ifeq "$(PORTING_HOST)" "YES"
+endef
 
-$(includes_H_CONFIG) :
-	@echo "*** Cross-compiling: please copy $(includes_H_CONFIG) from the target system"
-	@exit 1
+$(eval $(call includesHeaderVersion,0))
+$(eval $(call includesHeaderVersion,1))
 
-else
+ifneq "$(BINDIST)" "YES"
 
-$(includes_H_CONFIG) : mk/config.h mk/config.mk includes/ghc.mk | $$(dir $$@)/.
-	@echo "Creating $@..."
-	@echo "#if !defined(__GHCAUTOCONF_H__)"  >$@
-	@echo "#define __GHCAUTOCONF_H__" >>$@
+define includesHeaderConfig
+# $1 = stage
+$$(includes_$1_H_CONFIG) : mk/config.h mk/config.mk includes/ghc.mk | $$$$(dir $$$$@)/.
+	$$(call removeFiles,$$@)
+	@echo "Creating $$@..."
+	@echo "#if !defined(__GHCAUTOCONF_H__)"  > $$@
+	@echo "#define __GHCAUTOCONF_H__" >> $$@
 #
 #	Copy the contents of mk/config.h, turning '#define PACKAGE_FOO
 #	"blah"' into '/* #undef PACKAGE_FOO */' to avoid clashes.
 #
-	@sed 's,^\([	 ]*\)#[	 ]*define[	 ][	 ]*\(PACKAGE_[A-Z]*\)[	 ][ 	]*".*".*$$,\1/* #undef \2 */,' mk/config.h >> $@
+	@sed 's,^\([	 ]*\)#[	 ]*define[	 ][	 ]*\(PACKAGE_[A-Z]*\)[	 ][ 	]*".*".*$$$$,\1/* #undef \2 */,' mk/config.h >> $$@
 #
 #	Tack on some extra config information from the build system
 #
-ifeq "$(TablesNextToCode)" "YES"
-	@echo >> $@
-	@echo "#define TABLES_NEXT_TO_CODE 1" >> $@
+ifeq "$$(TablesNextToCode)" "YES"
+	@echo >> $$@
+	@echo "#define TABLES_NEXT_TO_CODE 1" >> $$@
 endif
 #
-ifeq "$(CC_LLVM_BACKEND)" "1"
-	@echo >> $@
-	@echo "#define llvm_CC_FLAVOR 1" >> $@
+ifeq "$$(CC_LLVM_BACKEND)" "1"
+	@echo >> $$@
+	@echo "#define llvm_CC_FLAVOR 1" >> $$@
 endif
 #
-ifeq "$(CC_CLANG_BACKEND)" "1"
-	@echo >> $@
-	@echo "#define clang_CC_FLAVOR 1" >> $@
+ifeq "$$(CC_CLANG_BACKEND)" "1"
+	@echo >> $$@
+	@echo "#define clang_CC_FLAVOR 1" >> $$@
 endif
 #
-	@echo "#endif /* __GHCAUTOCONF_H__ */"          >> $@
+	@echo "#endif /* __GHCAUTOCONF_H__ */"          >> $$@
 	@echo "Done."
 
+endef
+
+$(eval $(call includesHeaderConfig,0))
+$(eval $(call includesHeaderConfig,1))
+
+BUILDPLATFORM_0 = $(BUILDPLATFORM)
+BUILDPLATFORM_1 = $(HOSTPLATFORM)
+BUILDPLATFORM_2 = $(TARGETPLATFORM)
+
+HOSTPLATFORM_0 = $(HOSTPLATFORM)
+HOSTPLATFORM_1 = $(TARGETPLATFORM)
+HOSTPLATFORM_2 = $(TARGETPLATFORM)
+
+BuildPlatform_0_CPP = $(BuildPlatform_CPP)
+BuildPlatform_1_CPP = $(HostPlatform_CPP)
+BuildPlatform_2_CPP = $(TargetPlatform_CPP)
+
+HostPlatform_0_CPP = $(HostPlatform_CPP)
+HostPlatform_1_CPP = $(TargetPlatform_CPP)
+HostPlatform_2_CPP = $(TargetPlatform_CPP)
+
+BuildArch_0_CPP = $(BuildArch_CPP)
+BuildArch_1_CPP = $(HostArch_CPP)
+BuildArch_2_CPP = $(TargetArch_CPP)
+
+HostArch_0_CPP = $(HostArch_CPP)
+HostArch_1_CPP = $(TargetArch_CPP)
+HostArch_2_CPP = $(TargetArch_CPP)
+
+BuildOS_0_CPP = $(BuildOS_CPP)
+BuildOS_1_CPP = $(HostOS_CPP)
+BuildOS_2_CPP = $(TargetOS_CPP)
+
+HostOS_0_CPP = $(HostOS_CPP)
+HostOS_1_CPP = $(TargetOS_CPP)
+HostOS_2_CPP = $(TargetOS_CPP)
+
+BuildVendor_0_CPP = $(BuildVendor_CPP)
+BuildVendor_1_CPP = $(HostVendor_CPP)
+BuildVendor_2_CPP = $(TargetVendor_CPP)
+
+HostVendor_0_CPP = $(HostVendor_CPP)
+HostVendor_1_CPP = $(TargetVendor_CPP)
+HostVendor_2_CPP = $(TargetVendor_CPP)
+
+define includesHeaderPlatform
+# $1 = stage
+$$(includes_$1_H_PLATFORM) : includes/ghc.mk includes/Makefile | $$$$(dir $$$$@)/.
+	$$(call removeFiles,$$@)
+	@echo "Creating $$@..."
+	@echo "#if !defined(__GHCPLATFORM_H__)"  > $$@
+	@echo "#define __GHCPLATFORM_H__" >> $$@
+	@echo >> $$@
+	@echo "#define BuildPlatform_NAME  \"$(BUILDPLATFORM_$1)\"" >> $$@
+	@echo "#define HostPlatform_NAME   \"$(HOSTPLATFORM_$1)\"" >> $$@
+	@echo >> $$@
+	@echo "#define BuildPlatform_TYPE  $(BuildPlatform_$1_CPP)" >> $$@
+	@echo "#define HostPlatform_TYPE   $(HostPlatform_$1_CPP)" >> $$@
+	@echo >> $$@
+	@echo "#define $(BuildPlatform_$1_CPP)_BUILD  1" >> $$@
+	@echo "#define $(HostPlatform_$1_CPP)_HOST  1" >> $$@
+	@echo >> $$@
+	@echo "#define $(BuildArch_$1_CPP)_BUILD_ARCH  1" >> $$@
+	@echo "#define $(HostArch_$1_CPP)_HOST_ARCH  1" >> $$@
+	@echo "#define BUILD_ARCH  \"$(BuildArch_$1_CPP)\"" >> $$@
+	@echo "#define HOST_ARCH  \"$(HostArch_$1_CPP)\"" >> $$@
+	@echo >> $$@
+	@echo "#define $(BuildOS_$1_CPP)_BUILD_OS  1" >> $$@
+	@echo "#define $(HostOS_$1_CPP)_HOST_OS  1" >> $$@
+	@echo "#define BUILD_OS  \"$(BuildOS_$1_CPP)\"" >> $$@
+	@echo "#define HOST_OS  \"$(HostOS_$1_CPP)\"" >> $$@
+	@echo >> $$@
+	@echo "#define $(BuildVendor_$1_CPP)_BUILD_VENDOR  1" >> $$@
+	@echo "#define $(HostVendor_$1_CPP)_HOST_VENDOR  1" >> $$@
+	@echo "#define BUILD_VENDOR  \"$(BuildVendor_$1_CPP)\"" >> $$@
+	@echo "#define HOST_VENDOR  \"$(HostVendor_$1_CPP)\"" >> $$@
+	@echo >> $$@
+ifeq "$$(GhcUnregisterised)" "YES"
+	@echo "#define UnregisterisedCompiler 1" >> $$@
 endif
-
-$(includes_H_PLATFORM) : includes/Makefile | $$(dir $$@)/.
-	$(call removeFiles,$@)
-	@echo "Creating $@..."
-	@echo "#if !defined(__GHCPLATFORM_H__)"  >$@
-	@echo "#define __GHCPLATFORM_H__" >>$@
-	@echo >> $@
-	@echo "#define BuildPlatform_TYPE  $(HostPlatform_CPP)" >> $@
-	@echo "#define HostPlatform_TYPE   $(TargetPlatform_CPP)" >> $@
-	@echo >> $@
-	@echo "#define $(HostPlatform_CPP)_BUILD  1" >> $@
-	@echo "#define $(TargetPlatform_CPP)_HOST  1" >> $@
-	@echo >> $@
-	@echo "#define $(HostArch_CPP)_BUILD_ARCH  1" >> $@
-	@echo "#define $(TargetArch_CPP)_HOST_ARCH  1" >> $@
-	@echo "#define BUILD_ARCH  \"$(HostArch_CPP)\"" >> $@
-	@echo "#define HOST_ARCH  \"$(TargetArch_CPP)\"" >> $@
-	@echo >> $@
-	@echo "#define $(HostOS_CPP)_BUILD_OS  1" >> $@
-	@echo "#define $(TargetOS_CPP)_HOST_OS  1" >> $@
-	@echo "#define BUILD_OS  \"$(HostOS_CPP)\"" >> $@
-	@echo "#define HOST_OS  \"$(TargetOS_CPP)\"" >> $@
-	@echo >> $@
-	@echo "#define $(HostVendor_CPP)_BUILD_VENDOR  1" >> $@
-	@echo "#define $(TargetVendor_CPP)_HOST_VENDOR  1" >> $@
-	@echo "#define BUILD_VENDOR  \"$(HostVendor_CPP)\"" >> $@
-	@echo "#define HOST_VENDOR  \"$(TargetVendor_CPP)\"" >> $@
-	@echo >> $@
-ifeq "$(GhcUnregisterised)" "YES"
-	@echo "#define UnregisterisedCompiler 1" >> $@
-endif
-	@echo >> $@
-	@echo "#endif /* __GHCPLATFORM_H__ */"          >> $@
+	@echo >> $$@
+	@echo "#endif /* __GHCPLATFORM_H__ */" >> $$@
 	@echo "Done."
+endef
 
 endif
 
+$(eval $(call includesHeaderPlatform,0))
+$(eval $(call includesHeaderPlatform,1))
+
 # -----------------------------------------------------------------------------
 # Settings
 
@@ -244,10 +310,10 @@ endif
 DERIVE_CONSTANTS_FLAGS += --target-os "$(TargetOS_CPP)"
 
 ifneq "$(BINDIST)" "YES"
-$(includes_DERIVEDCONSTANTS):           $$(includes_H_CONFIG) $$(includes_H_PLATFORM) $$(includes_H_VERSION) $$(includes_H_FILES) $$(rts_H_FILES)
-$(includes_GHCCONSTANTS_HASKELL_VALUE): $$(includes_H_CONFIG) $$(includes_H_PLATFORM) $$(includes_H_VERSION) $$(includes_H_FILES) $$(rts_H_FILES)
+$(includes_DERIVEDCONSTANTS):           $$(includes_H_FILES) $$(rts_H_FILES)
+$(includes_GHCCONSTANTS_HASKELL_VALUE): $$(includes_H_FILES) $$(rts_H_FILES)
 
-$(includes_DERIVEDCONSTANTS): $(deriveConstants_INPLACE) | $$(dir $$@)/.
+$(includes_DERIVEDCONSTANTS): $(deriveConstants_INPLACE) $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) | $$(dir $$@)/.
 	$< --gen-header -o $@ --tmpdir $(dir $@) $(DERIVE_CONSTANTS_FLAGS)
 
 $(includes_GHCCONSTANTS_HASKELL_TYPE): $(deriveConstants_INPLACE) | $$(dir $$@)/.
@@ -267,10 +333,12 @@ endif
 # Install all header files
 
 $(eval $(call clean-target,includes,,\
-  $(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_VERSION)))
+  $(includes_0_H_CONFIG) $(includes_0_H_PLATFORM) $(includes_0_H_VERSION) \
+  $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) $(includes_1_H_VERSION)))
 
 $(eval $(call all-target,includes,\
-  $(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_VERSION) \
+  $(includes_0_H_CONFIG) $(includes_0_H_PLATFORM) $(includes_0_H_VERSION) \
+  $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) $(includes_1_H_VERSION) \
   $(includes_GHCCONSTANTS_HASKELL_TYPE) \
   $(includes_GHCCONSTANTS_HASKELL_VALUE) \
   $(includes_GHCCONSTANTS_HASKELL_WRAPPERS) \
@@ -280,11 +348,14 @@ $(eval $(call all-target,includes,\
 install: install_includes
 
 .PHONY: install_includes
-install_includes :
+install_includes : $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) $(includes_1_H_VERSION)
 	$(INSTALL_DIR) "$(DESTDIR)$(ghcheaderdir)"
 	$(foreach d,$(includes_H_SUBDIRS), \
 	    $(INSTALL_DIR) "$(DESTDIR)$(ghcheaderdir)/$d" && \
 	    $(INSTALL_HEADER) $(INSTALL_OPTS) includes/$d/*.h "$(DESTDIR)$(ghcheaderdir)/$d/" && \
 	) true
-	$(INSTALL_HEADER) $(INSTALL_OPTS) $(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_VERSION) $(includes_DERIVEDCONSTANTS) "$(DESTDIR)$(ghcheaderdir)/"
+	$(INSTALL_HEADER) $(INSTALL_OPTS) \
+		$(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) $(includes_1_H_VERSION) \
+		$(includes_DERIVEDCONSTANTS) \
+		"$(DESTDIR)$(ghcheaderdir)/"
 
diff --git a/rts/ghc.mk b/rts/ghc.mk
index 9cd66920c7db1e7ae6139b6e3bda380954e2e9cf..26865b5bb7b82eedefc8ad929e28e686edc57fb2 100644
--- a/rts/ghc.mk
+++ b/rts/ghc.mk
@@ -190,8 +190,12 @@ ifeq "$(NEED_DTRACE_PROBES_OBJ)" "YES"
 rts_$1_DTRACE_OBJS = rts/dist/build/RtsProbes.$$($1_osuf)
 
 $$(rts_$1_DTRACE_OBJS) : $$(rts_$1_OBJS)
-	$(DTRACE) -G -C $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) -DDTRACE -s rts/RtsProbes.d -o \
-		$$@ $$(rts_$1_OBJS)
+	$(DTRACE) -G -C \
+		$$(addprefix -I,$$(GHC_INCLUDE_DIRS)) \
+		-I$$(BUILD_1_INCLUDE_DIR) \
+		-DDTRACE -s rts/RtsProbes.d \
+		-o $$@ \
+		$$(rts_$1_OBJS)
 endif
 endif
 
@@ -352,7 +356,12 @@ endif
 # support for registerised builds on this arch. -- BL 2010/02/03
 # WARNING_OPTS += -Wcast-align
 
-STANDARD_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS)) -Irts -Irts/dist/build
+STANDARD_OPTS += \
+	$(addprefix -I,$(GHC_INCLUDE_DIRS)) \
+	-I$(BUILD_1_INCLUDE_DIR) \
+	-Irts \
+	-Irts/dist/build
+
 # COMPILING_RTS is only used when building Win32 DLL support.
 STANDARD_OPTS += -DCOMPILING_RTS -DFS_NAMESPACE=rts
 
@@ -568,6 +577,10 @@ endif
 
 $(eval $(call dependencies,rts,dist,1))
 
+$(rts_dist_depfile_c_asm) : $(includes_dist_H_CONFIG)
+$(rts_dist_depfile_c_asm) : $(includes_dist_H_PLATFORM)
+$(rts_dist_depfile_c_asm) : $(includes_dist_H_VERSION)
+
 $(rts_dist_depfile_c_asm) : $(DTRACEPROBES_H)
 ifneq "$(UseSystemLibFFI)" "YES"
 $(rts_dist_depfile_c_asm) : $(libffi_HEADERS)
@@ -594,7 +607,7 @@ DTRACE_FLAGS = -x cpppath=$(CC)
 endif
 
 DTRACEPROBES_SRC = rts/RtsProbes.d
-$(DTRACEPROBES_H): $(DTRACEPROBES_SRC) includes/ghcplatform.h | $$(dir $$@)/.
+$(DTRACEPROBES_H): $(DTRACEPROBES_SRC) $(includes_1_H_PLATFORM) | $$(dir $$@)/.
 	"$(DTRACE)" $(filter -I%,$(rts_CC_OPTS)) -C $(DTRACE_FLAGS) -h -o $@ -s $<
 endif
 
@@ -610,9 +623,9 @@ ifeq "$(HaveLibMingwEx)" "YES"
 rts_PACKAGE_CPP_OPTS += -DHAVE_LIBMINGWEX
 endif
 
-$(eval $(call manual-package-config,rts))
+$(eval $(call manual-package-config,rts,1))
 
-rts/package.conf.inplace : $(includes_H_CONFIG) $(includes_H_PLATFORM)
+rts/dist/package.conf.inplace : $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) $(includes_1_H_VERSION)
 
 # -----------------------------------------------------------------------------
 # installing
diff --git a/rts/package.conf.in b/rts/package.conf.in
index a0e124a061b7cc2544f1e53b208cc13045874b34..ce3146b4c5f70c8ccd8bae346192e815904d9634 100644
--- a/rts/package.conf.in
+++ b/rts/package.conf.in
@@ -67,7 +67,7 @@ extra-libraries:
 #if defined(INSTALLING)
 include-dirs:           INCLUDE_DIR FFI_INCLUDE_DIR
 #else /* !INSTALLING */
-include-dirs:           TOP"/rts/dist/build" TOP"/includes" TOP"/includes/dist-derivedconstants/header" FFI_INCLUDE_DIR
+include-dirs:           TOP"/rts/dist/build" TOP"/includes" TOP"/includes/dist-derivedconstants/header" FFI_INCLUDE_DIR TOP"/includes/dist-install/build"
 #endif
 
 includes:               Stg.h
diff --git a/rules/build-dependencies.mk b/rules/build-dependencies.mk
index 3a7491fe5192245f74615d93716b4008e67f8a18..de580a737918ab38c8550222250560408684d374 100644
--- a/rules/build-dependencies.mk
+++ b/rules/build-dependencies.mk
@@ -30,7 +30,7 @@ ifneq "$$(NO_GENERATED_MAKEFILE_RULES)" "YES"
 
 # Some of the Haskell files (e.g. utils/hsc2hs/Main.hs) (directly or
 # indirectly) include the generated includes files.
-$$($1_$2_depfile_haskell) : $$(includes_H_CONFIG) $$(includes_H_PLATFORM)
+$$($1_$2_depfile_haskell) : $$(includes_$3_H_CONFIG) $$(includes_$3_H_PLATFORM)
 
 $$($1_$2_depfile_haskell) : $$($1_$2_HS_SRCS) $$($1_$2_HS_BOOT_SRCS) $$$$($1_$2_HC_MK_DEPEND_DEP) | $$$$(dir $$$$@)/.
 	$$(call removeFiles,$$@.tmp)
@@ -65,7 +65,7 @@ endif
              $$@.tmp2 > $$@
 # Some of the C files (directly or indirectly) include the generated
 # includes files.
-$$($1_$2_depfile_c_asm) : $$(includes_H_CONFIG) $$(includes_H_PLATFORM)
+$$($1_$2_depfile_c_asm) : $$(includes_$3_H_CONFIG) $$(includes_$3_H_PLATFORM)
 
 $$($1_$2_depfile_c_asm) : $$($1_$2_C_FILES_DEPS) $$($1_$2_S_FILES) $$($1_$2_CMM_FILES) | $$$$(dir $$$$@)/.
 	$$(call removeFiles,$$@.tmp)
diff --git a/rules/build-package-way.mk b/rules/build-package-way.mk
index 187d9c848d2988ba5e4f2f26c41ce0ed2a9399ba..e5601403ccced2c138b22969db0e25b5da3e9fa0 100644
--- a/rules/build-package-way.mk
+++ b/rules/build-package-way.mk
@@ -16,7 +16,7 @@ $(call trace, build-package-way($1,$2,$3))
 $(call profStart, build-package-way($1,$2,$3))
 
 $(call distdir-way-opts,$1,$2,$3,$4)
-$(call hs-suffix-way-rules,$1,$2,$3)
+$(call hs-suffix-way-rules,$1,$2,$3,$4)
 
 $(call hs-objs,$1,$2,$3)
 
diff --git a/rules/build-prog.mk b/rules/build-prog.mk
index 5d5f0e3ca3107cd98c18dfcba3f984237d39a994..0528c15fc93cdd7497aaa3cedc0a8cd391ad96e1 100644
--- a/rules/build-prog.mk
+++ b/rules/build-prog.mk
@@ -178,7 +178,7 @@ endif
 
 $$(foreach dir,$$($1_$2_HS_SRC_DIRS),\
   $$(eval $$(call hs-suffix-rules-srcdir,$1,$2,$$(dir))))
-$(call hs-suffix-way-rules,$1,$2,$$($1_$2_PROGRAM_WAY))
+$(call hs-suffix-way-rules,$1,$2,$$($1_$2_PROGRAM_WAY),$3)
 
 $(call c-objs,$1,$2,$$($1_$2_PROGRAM_WAY))
 $(call hs-objs,$1,$2,$$($1_$2_PROGRAM_WAY))
diff --git a/rules/hs-suffix-way-rules-srcdir.mk b/rules/hs-suffix-way-rules-srcdir.mk
index 78c1be18f4327ab17e1bda73fd44666653036156..1d01f95219b4395d5eb427436134c783f90612df 100644
--- a/rules/hs-suffix-way-rules-srcdir.mk
+++ b/rules/hs-suffix-way-rules-srcdir.mk
@@ -12,7 +12,7 @@
 
 
 define hs-suffix-way-rules-srcdir
-# args: $1 = dir,  $2 = distdir, $3 = way, $4 = srcdir
+# args: $1 = dir,  $2 = distdir, $3 = way, $4 = srcdir, $5 = stage
 
 ifneq "$$(BINDIST)" "YES"
 
@@ -35,11 +35,21 @@ $1/$2/build/%.$$($3_hcsuf) : $1/$4/%.lhs $$(LAX_DEPS_FOLLOW) $$$$($1_$2_HC_DEP)
 # XXX: for some reason these get used in preference to the direct
 # .hs->.o rule, I don't know why --SDM
 
-$1/$2/build/%.$$($3_osuf) : $1/$4/%.hc includes/ghcautoconf.h includes/ghcplatform.h | $$$$(dir $$$$@)/.
-	$$(call cmd,$1_$2_CC) $$($1_$2_$3_ALL_CC_OPTS) $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) -x c -c $$< -o $$@ $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno $$(addsuffix .$$(dyn_osuf),$$(basename $$@)))
-
-$1/$2/build/%.$$($3_osuf) : $1/$2/build/%.hc includes/ghcautoconf.h includes/ghcplatform.h
-	$$(call cmd,$1_$2_CC) $$($1_$2_$3_ALL_CC_OPTS) $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) -x c -c $$< -o $$@ $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno $$(addsuffix .$$(dyn_osuf),$$(basename $$@)))
+$1/$2/build/%.$$($3_osuf) : $1/$4/%.hc $$(includes_$5_H_CONFIG) $$(includes_$5_H_PLATFORM) | $$$$(dir $$$$@)/.
+	$$(call cmd,$1_$2_CC) \
+		$$($1_$2_$3_ALL_CC_OPTS) \
+		$$(addprefix -I,$$(GHC_INCLUDE_DIRS)) \
+		-I$$(BUILD_$5_INCLUDE_DIR) \
+		-x c -c $$< -o $$@ \
+		$$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno $$(addsuffix .$$(dyn_osuf),$$(basename $$@)))
+
+$1/$2/build/%.$$($3_osuf) : $1/$2/build/%.hc $$(includes_$5_H_CONFIG) $$(includes_$5_H_PLATFORM)
+	$$(call cmd,$1_$2_CC) \
+		$$($1_$2_$3_ALL_CC_OPTS) \
+		$$(addprefix -I,$$(GHC_INCLUDE_DIRS)) \
+		-I$$(BUILD_$5_INCLUDE_DIR) \
+		-x c -c $$< -o $$@ \
+		$$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno $$(addsuffix .$$(dyn_osuf),$$(basename $$@)))
 
 # $1/$2/build/%.$$($3_osuf) : $1/$2/build/%.$$($3_hcsuf)
 # 	$$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -c $$< -o $$@
diff --git a/rules/hs-suffix-way-rules.mk b/rules/hs-suffix-way-rules.mk
index 286e04eee732185eb524ddf9c689d8b5b0131bce..daf1da49269bb03d717835f2837cfc8e089df2e2 100644
--- a/rules/hs-suffix-way-rules.mk
+++ b/rules/hs-suffix-way-rules.mk
@@ -11,7 +11,7 @@
 # -----------------------------------------------------------------------------
 
 
-define hs-suffix-way-rules  # args: $1 = dir,  $2 = distdir, $3 = way
+define hs-suffix-way-rules  # args: $1 = dir,  $2 = distdir, $3 = way, $4 = stage
 
 ifeq "$3 $$($1_$2_DYNAMIC_TOO)" "dyn YES"
 # We only want this rule to be used for Haskell sources, not for
@@ -106,7 +106,7 @@ else
 # [1] https://www.gnu.org/software/make/manual/make.html#Implicit-Rule-Search
 
 $$(foreach dir,$$($1_$2_HS_SRC_DIRS),\
-  $$(eval $$(call hs-suffix-way-rules-srcdir,$1,$2,$3,$$(dir))))
+  $$(eval $$(call hs-suffix-way-rules-srcdir,$1,$2,$3,$$(dir),$4)))
 
 
 ifneq "$$(BINDIST)" "YES"
diff --git a/rules/manual-package-config.mk b/rules/manual-package-config.mk
index 2fc6dea5d30d2519584a7e210b7bc990fece5023..64d6f1aec6070bd2ca7270e56ef8ca57f9dee2f7 100644
--- a/rules/manual-package-config.mk
+++ b/rules/manual-package-config.mk
@@ -11,15 +11,20 @@
 # -----------------------------------------------------------------------------
 
 
-define manual-package-config # args: $1 = dir
-$(call trace, manual-package-config($1))
-$(call profStart, manual-package-config($1))
+define manual-package-config
+# args:
+# $1 = dir
+# $2 = stage
+$(call trace, manual-package-config($1, $2))
+$(call profStart, manual-package-config($1, $2))
 
 $1/dist/package.conf.inplace : $1/package.conf.in $$$$(ghc-pkg_INPLACE) | $$$$(dir $$$$@)/.
 	$$(HS_CPP) -P \
 		-DTOP='"$$(TOP)"' \
 		$$($1_PACKAGE_CPP_OPTS) \
-		-x c $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) $$< -o $$@.raw
+		$$(addprefix -I,$$(GHC_INCLUDE_DIRS)) \
+		-I$$(BUILD_$2_INCLUDE_DIR) \
+		-x c $$< -o $$@.raw
 	grep -v '^#pragma GCC' $$@.raw | \
 	    sed -e 's/""//g' -e 's/:[ 	]*,/: /g' > $$@
 
@@ -34,9 +39,11 @@ $1/dist/package.conf.install: | $$$$(dir $$$$@)/.
 		-DLIB_DIR='"$$(if $$(filter YES,$$(RelocatableBuild)),$$$$topdir,$$(ghclibdir))"' \
 		-DINCLUDE_DIR='"$$(if $$(filter YES,$$(RelocatableBuild)),$$$$topdir,$$(ghclibdir))/include"' \
 		$$($1_PACKAGE_CPP_OPTS) \
-		-x c $$(addprefix -I,$$(GHC_INCLUDE_DIRS)) $1/package.conf.in -o $$@.raw
+		$$(addprefix -I,$$(GHC_INCLUDE_DIRS)) \
+		-I$$(BUILD_$2_INCLUDE_DIR) \
+		-x c $1/package.conf.in -o $$@.raw
 	grep -v '^#pragma GCC' $$@.raw | \
 	    sed -e 's/""//g' -e 's/:[ 	]*,/: /g' >$$@
 
-$(call profEnd, manual-package-config($1))
+$(call profEnd, manual-package-config($1, $2))
 endef
diff --git a/utils/genapply/Main.hs b/utils/genapply/Main.hs
index 4d25054a1cadc57e25a715a8e551c34ea62d2aca..8c194f1ca0faae10b32f53d37500302fc232735b 100644
--- a/utils/genapply/Main.hs
+++ b/utils/genapply/Main.hs
@@ -12,10 +12,13 @@
 -- for details
 module Main(main) where
 
+-- Note [Genapply target as host for RTS macros]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 -- We improperly include *HOST* macros for our target...
 #include "../../includes/ghcconfig.h"
 
--- .. so that this header defines the right stuff.
+-- ...so that this header defines the right stuff.  It is the RTS's host, but
+-- our target, as we are generating code that uses that RTS.
 #include "../../includes/stg/MachRegsForHost.h"
 
 #include "../../includes/rts/Constants.h"
diff --git a/utils/genapply/ghc.mk b/utils/genapply/ghc.mk
index 88b34442751f7319927fbb6c7a3b0d22b245fe69..8da1f7aaf612f9a70159a03187ba70979e42344f 100644
--- a/utils/genapply/ghc.mk
+++ b/utils/genapply/ghc.mk
@@ -16,8 +16,15 @@ utils/genapply_dist_PROGNAME        = genapply
 utils/genapply_dist_INSTALL         = NO
 utils/genapply_dist_INSTALL_INPLACE = YES
 
+utils/dist/package-data.mk : $(includes_1_H_PLATFORM)
+utils/dist/package-data.mk : $(includes_1_H_CONFIG)
+
 ifeq "$(GhcUnregisterised)" "YES"
 utils/genapply_CONFIGURE_OPTS = --flag unregisterised
 endif
 
 $(eval $(call build-prog,utils/genapply,dist,0))
+
+# Purposely do the wrong stage for HOST := TARGET hack.
+# See Note [Genapply target as host for RTS macros].
+utils/genapply_dist_CC_OPTS += -I,$(BUILD_1_INCLUDE_DIR)
diff --git a/utils/hp2ps/Main.h b/utils/hp2ps/Main.h
index 1eea93f0a2c4ba8070d4d05054a8e368bed901e7..9849e493272458fba16dbaab1d7c2dc7c9cbf403 100644
--- a/utils/hp2ps/Main.h
+++ b/utils/hp2ps/Main.h
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "ghcconfig.h"
 #include <stdio.h>
 
 #if defined(__STDC__)
diff --git a/utils/hp2ps/ghc.mk b/utils/hp2ps/ghc.mk
index bd62fbedefb6eddc9be538cd59309421316c02c5..75baa9ac4d2b877e00c56daf855cdc331c61f158 100644
--- a/utils/hp2ps/ghc.mk
+++ b/utils/hp2ps/ghc.mk
@@ -10,6 +10,8 @@
 #
 # -----------------------------------------------------------------------------
 
+utils/hp2ps_CC_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
+
 # stage0
 utils/hp2ps_dist_C_SRCS          = AreaBelow.c Curves.c Error.c Main.c \
                                    Reorder.c TopTwenty.c AuxFile.c Deviation.c \
@@ -22,8 +24,6 @@ utils/hp2ps_dist_INSTALL_INPLACE = YES
 utils/hp2ps_dist_SHELL_WRAPPER              = YES
 utils/hp2ps_dist_INSTALL_SHELL_WRAPPER_NAME = hp2ps
 
-utils/hp2ps_CC_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS))
-
 # stage 1
 utils/hp2ps_dist-install_C_SRCS = $(utils/hp2ps_dist_C_SRCS)
 utils/hp2ps_dist-install_EXTRA_LIBRARIES = $(utils/hp2ps_dist_EXTRA_LIBRARIES)
diff --git a/utils/runghc/Main.hs b/utils/runghc/Main.hs
index fd5947591619d3e94757ed38d824e559532c5c79..9ed650410d0b63788958cf3f8b7f8fff06053dfd 100644
--- a/utils/runghc/Main.hs
+++ b/utils/runghc/Main.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE CPP #-}
-#include "ghcconfig.h"
+#include <ghcplatform.h>
 -----------------------------------------------------------------------------
 --
 -- (c) The University of Glasgow, 2004