From 05419e55cab272ed39790695f448b311f22669f7 Mon Sep 17 00:00:00 2001
From: John Ericson <git@JohnEricson.me>
Date: Wed, 8 May 2019 02:52:35 -0400
Subject: [PATCH] Per stage headers, ghc_boot_platform.h -> stage 0
 ghcplatform.h

The generated headers are now generated per stage, which means we can
skip hacks like `ghc_boot_platform.h` and just have that be the stage 0
header as proper. In general, stages are to be embraced: freely generate
everything in each stage but then just build what you depend on, and
everything is symmetrical and efficient. Trying to avoid stages because
bootstrapping is a mind bender just creates tons of bespoke
mini-mind-benders that add up to something far crazier.

Hadrian was pretty close to this "stage-major" approach already, and so
was fairly easy to fix. Make needed more work, however: it did know
about stages so at least there was a scaffold, but few packages except
for the compiler cared, and the compiler used its own counting system.
That said, make and Hadrian now work more similarly, which is good for
the transition to Hadrian. The merits of embracing stage aside, the
change may be worthy for easing that transition alone.
---
 .gitignore                                    |   4 +-
 compiler/HsVersions.h                         |  12 +-
 compiler/ghc.cabal.in                         |   2 +-
 compiler/ghc.mk                               | 146 +++--------
 ghc.mk                                        |  12 +-
 ghc/ghc.mk                                    |   5 -
 hadrian/src/Base.hs                           |  23 +-
 hadrian/src/Builder.hs                        |   4 +-
 hadrian/src/Packages.hs                       |  11 +-
 hadrian/src/Rules.hs                          |   2 +-
 hadrian/src/Rules/Generate.hs                 | 148 ++++-------
 hadrian/src/Settings/Builders/Cabal.hs        |  12 +-
 hadrian/src/Settings/Builders/Common.hs       |   5 +-
 .../src/Settings/Builders/DeriveConstants.hs  |  25 +-
 hadrian/src/Settings/Builders/Ghc.hs          |  10 +-
 hadrian/src/Settings/Builders/HsCpp.hs        |   4 +-
 includes/ghc.mk                               | 247 +++++++++++-------
 rts/ghc.mk                                    |  25 +-
 rts/package.conf.in                           |   2 +-
 rules/build-dependencies.mk                   |   4 +-
 rules/build-package-way.mk                    |   2 +-
 rules/build-prog.mk                           |   2 +-
 rules/hs-suffix-way-rules-srcdir.mk           |  22 +-
 rules/hs-suffix-way-rules.mk                  |   4 +-
 rules/manual-package-config.mk                |  19 +-
 utils/genapply/Main.hs                        |   5 +-
 utils/genapply/ghc.mk                         |   7 +
 utils/hp2ps/Main.h                            |   1 -
 utils/hp2ps/ghc.mk                            |   4 +-
 utils/runghc/Main.hs                          |   2 +-
 30 files changed, 383 insertions(+), 388 deletions(-)

diff --git a/.gitignore b/.gitignore
index 89492fd97746..f5db603a6a54 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 0b7665429da1..daeec9dd3da0 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 ea12b5563def..7e21924c343e 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 441b6989727f..3f94e879267c 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 677508de8e62..cb6bbb87a0f7 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 b1f9f57d8192..3bff2f58c936 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 bc4eab354e7f..f7f1029d4ee9 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 587c62fa160e..34027d7bbb0a 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 53ecb6897e48..c4ae780fb33b 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 e72623d4cec0..3f6397fdccc4 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 ef3d8aa3b404..c2c3c1437218 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 96f67b4abf1e..763f51636b2b 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 5856935fb99c..7d9e0fe716aa 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 90068b3c4a87..0747162f43d8 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 2db62aa4e1dc..54315484c10d 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 e33061c9d033..4595e2098e66 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 81e7483756c9..52b875cc286d 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 9cd66920c7db..26865b5bb7b8 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 a0e124a061b7..ce3146b4c5f7 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 3a7491fe5192..de580a737918 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 187d9c848d29..e5601403ccce 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 5d5f0e3ca310..0528c15fc93c 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 78c1be18f432..1d01f95219b4 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 286e04eee732..daf1da49269b 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 2fc6dea5d30d..64d6f1aec607 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 4d25054a1cad..8c194f1ca0fa 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 88b34442751f..8da1f7aaf612 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 1eea93f0a2c4..9849e4932724 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 bd62fbedefb6..75baa9ac4d2b 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 fd5947591619..9ed650410d0b 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
-- 
GitLab