diff --git a/hadrian/bindist/Makefile b/hadrian/bindist/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..79f9a9f2f2de1279e80bc72e0d3f28468ccf6b40
--- /dev/null
+++ b/hadrian/bindist/Makefile
@@ -0,0 +1,146 @@
+MAKEFLAGS += --no-builtin-rules
+.SUFFIXES:
+
+include mk/install.mk
+include mk/config.mk
+
+.PHONY: default
+default:
+	@echo 'Run "make install" to install'
+	@false
+
+#-----------------------------------------------------------------------
+# INSTALL RULES
+
+# Hacky function to check equality of two strings
+# TODO : find if a better function exists
+eq=$(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))
+
+define installscript
+# $1 = package name
+# $2 = wrapper path
+# $3 = bindir
+# $4 = ghcbindir
+# $5 = Executable binary path
+# $6 = Library Directory
+# $7 = Docs Directory
+# $8 = Includes Directory
+# We are installing wrappers to programs by searching corresponding
+# wrappers. If wrapper is not found, we are attaching the common wrapper
+# to it. This implementation is a bit hacky and depends on consistency
+# of program names. For hadrian build this will work as programs have a
+# consistent naming procedure.
+	rm -f '$2'
+	$(CREATE_SCRIPT) '$2'
+	@echo "#!$(SHELL)" >>  '$2'
+	@echo "exedir=\"$4\"" >> '$2'
+	@echo "exeprog=\"$1\"" >> '$2'
+	@echo "executablename=\"$5\"" >> '$2'
+	@echo "bindir=\"$3\"" >> '$2'
+	@echo "libdir=\"$6\"" >> '$2'
+	@echo "docdir=\"$7\"" >> '$2'
+	@echo "includedir=\"$8\"" >> '$2'
+	@echo "" >> '$2'
+	cat wrappers/$1 >> '$2'
+	$(EXECUTABLE_FILE) '$2' ;
+endef
+
+# Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'
+# fields in the package .conf files
+define patchpackageconf
+#
+# $1 = package name (ex: 'bytestring')
+# $2 = path to .conf file
+# $3 = Docs Directory
+# $4 = (relative) path from $${pkgroot} to docs directory ($3)
+#
+# We fix the paths to haddock files by using the relative path from the pkgroot
+# to the doc files.
+	cat '$2' | sed 's|haddock-interfaces.*|haddock-interfaces: "$${pkgroot}/$4/html/libraries/$1/$1.haddock"|' \
+	         | sed 's|haddock-html.*|haddock-html: "$${pkgroot}/$4/html/libraries/$1"|' \
+		 | sed 's|    $${pkgroot}/../../docs/html/.*||' \
+	       > '$2.copy'
+# The rts package doesn't actually supply haddocks, so we stop advertising them
+# altogether.
+	((echo "$1" | grep rts) && (cat '$2.copy' | sed 's|haddock-.*||' > '$2.copy.copy')) || (cat '$2.copy' > '$2.copy.copy')
+# We finally replace the original file.
+	mv '$2.copy.copy' '$2'
+endef
+
+# QUESTION : should we use shell commands?
+
+
+.PHONY: install
+install: install_lib install_bin install_includes
+install: install_docs install_wrappers install_ghci
+install: install_mingw update_package_db
+
+ActualBinsDir=${ghclibdir}/bin
+ActualLibsDir=${ghclibdir}/lib
+WrapperBinsDir=${bindir}
+
+# We need to install binaries relative to libraries.
+BINARIES = $(wildcard ./bin/*)
+install_bin:
+	@echo "Copying binaries to $(ActualBinsDir)"
+	$(INSTALL_DIR) "$(ActualBinsDir)"
+	for i in $(BINARIES); do \
+		cp -R $$i "$(ActualBinsDir)"; \
+	done
+
+install_ghci:
+	@echo "Copying and installing ghci"
+	$(CREATE_SCRIPT) '$(WrapperBinsDir)/ghci'
+	@echo "#!$(SHELL)" >>  '$(WrapperBinsDir)/ghci'
+	cat wrappers/ghci-script >> '$(WrapperBinsDir)/ghci'
+	$(EXECUTABLE_FILE) '$(WrapperBinsDir)/ghci'
+
+LIBRARIES = $(wildcard ./lib/*)
+install_lib:
+	@echo "Copying libraries to $(ActualLibsDir)"
+	$(INSTALL_DIR) "$(ActualLibsDir)"
+	for i in $(LIBRARIES); do \
+		cp -R $$i "$(ActualLibsDir)/"; \
+	done
+
+INCLUDES = $(wildcard ./include/*)
+install_includes:
+	@echo "Copying libraries to $(includedir)"
+	$(INSTALL_DIR) "$(includedir)"
+	for i in $(INCLUDES); do \
+		cp -R $$i "$(includedir)/"; \
+	done
+
+DOCS = $(wildcard ./docs/*)
+install_docs:
+	@echo "Copying libraries to $(docdir)"
+	$(INSTALL_DIR) "$(docdir)"
+	for i in $(DOCS); do \
+		cp -R $$i "$(docdir)/"; \
+	done
+
+BINARY_NAMES=$(shell ls ./wrappers/)
+install_wrappers:
+	@echo "Installing Wrapper scripts"
+	$(INSTALL_DIR) "$(WrapperBinsDir)"
+	$(foreach p, $(BINARY_NAMES),\
+		$(call installscript,$p,$(WrapperBinsDir)/$p,$(WrapperBinsDir),$(ActualBinsDir),$(ActualBinsDir)/$p,$(ActualLibsDir),$(docdir),$(includedir)))
+
+PKG_CONFS = $(shell find "$(ActualLibsDir)/package.conf.d" -name '*.conf' | sed 's:   :xxx:g')
+update_package_db:
+	@echo "$(PKG_CONFS)"
+	@echo "Updating the package DB"
+	$(foreach p, $(PKG_CONFS),\
+		$(call patchpackageconf,$(shell echo $(notdir $p) | sed 's/-\([0-9]*[0-9]\.\)*conf//g'),$(shell echo "$p" | sed 's:xxx:   :g'),$(docdir),$(shell realpath --relative-to="$(libdir)" "$(docdir)")))
+	'$(WrapperBinsDir)/ghc-pkg' recache
+
+# The 'foreach' that copies the mingw directory will only trigger a copy
+# when the wildcard matches, therefore only on Windows.
+MINGW = $(wildcard ./mingw)
+install_mingw:
+	@echo "Installing MingGW"
+	$(INSTALL_DIR) "$(prefix)/mingw"
+	$(foreach d, $(MINGW),\
+		cp -R ./mingw "$(prefix)")
+# END INSTALL
+# ----------------------------------------------------------------------
diff --git a/hadrian/src/CommandLine.hs b/hadrian/src/CommandLine.hs
index 41b2f8d0b91a65fc6185e867c48f4a7020ba7502..461898cdfdceb662b2ee1eeb0abd67856fcf851b 100644
--- a/hadrian/src/CommandLine.hs
+++ b/hadrian/src/CommandLine.hs
@@ -146,7 +146,7 @@ readTestConfig config =
 
 readTestConfigFile :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs)
 readTestConfigFile filepath =
-    maybe (Left "Cannot parse test-speed") (Right . set) filepath
+    maybe (Left "Cannot parse test-config-file") (Right . set) filepath
   where
     set filepath flags =  flags { testArgs = (testArgs flags) { testConfigFile = filepath } }
 
diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs
index c02d9787f9e25372d6b8fc4e85a98f5607738a5c..9f5aba84019b33b96b922508c025e1b22c2b47d9 100644
--- a/hadrian/src/Rules/BinaryDist.hs
+++ b/hadrian/src/Rules/BinaryDist.hs
@@ -101,6 +101,7 @@ bindistRules = do
         -- We 'need' all binaries and libraries
         targets <- mapM pkgTarget =<< stagePackages Stage1
         need targets
+        needIservBins
 
         version        <- setting ProjectVersion
         targetPlatform <- setting TargetPlatformFull
@@ -180,8 +181,9 @@ bindistRules = do
         moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath
 
     -- Generate the Makefile that enables the "make install" part
-    root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath ->
-        writeFile' makefilePath bindistMakefile
+    root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
+        top <- topDirectory
+        copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
 
     root -/- "bindist" -/- "ghc-*" -/- "wrappers/*" %> \wrapperPath ->
         writeFile' wrapperPath $ wrapper (takeFileName wrapperPath)
@@ -216,153 +218,6 @@ pkgTarget pkg
     | isLibrary pkg = pkgConfFile (vanillaContext Stage1 pkg)
     | otherwise     = programPath =<< programContext Stage1 pkg
 
--- TODO: Augment this Makefile to match the various parameters that the current
--- bindist scripts support.
--- | A trivial Makefile that only takes @$prefix@ into account, and not e.g
--- @$datadir@ (for docs) and other variables, yet.
-bindistMakefile :: String
-bindistMakefile = unlines
-    [ "MAKEFLAGS += --no-builtin-rules"
-    , ".SUFFIXES:"
-    , ""
-    , "include mk/install.mk"
-    , "include mk/config.mk"
-    , ""
-    , ".PHONY: default"
-    , "default:"
-    , "\t@echo 'Run \"make install\" to install'"
-    , "\t@false"
-    , ""
-    , "#-----------------------------------------------------------------------"
-    , "# INSTALL RULES"
-    , ""
-    , "# Hacky function to check equality of two strings"
-    , "# TODO : find if a better function exists"
-    , "eq=$(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))"
-    , ""
-    , "define installscript"
-    , "# $1 = package name"
-    , "# $2 = wrapper path"
-    , "# $3 = bindir"
-    , "# $4 = ghcbindir"
-    , "# $5 = Executable binary path"
-    , "# $6 = Library Directory"
-    , "# $7 = Docs Directory"
-    , "# $8 = Includes Directory"
-    , "# We are installing wrappers to programs by searching corresponding"
-    , "# wrappers. If wrapper is not found, we are attaching the common wrapper"
-    , "# to it. This implementation is a bit hacky and depends on consistency"
-    , "# of program names. For hadrian build this will work as programs have a"
-    , "# consistent naming procedure."
-    , "\trm -f '$2'"
-    , "\t$(CREATE_SCRIPT) '$2'"
-    , "\t@echo \"#!$(SHELL)\" >>  '$2'"
-    , "\t@echo \"exedir=\\\"$4\\\"\" >> '$2'"
-    , "\t@echo \"exeprog=\\\"$1\\\"\" >> '$2'"
-    , "\t@echo \"executablename=\\\"$5\\\"\" >> '$2'"
-    , "\t@echo \"bindir=\\\"$3\\\"\" >> '$2'"
-    , "\t@echo \"libdir=\\\"$6\\\"\" >> '$2'"
-    , "\t@echo \"docdir=\\\"$7\\\"\" >> '$2'"
-    , "\t@echo \"includedir=\\\"$8\\\"\" >> '$2'"
-    , "\t@echo \"\" >> '$2'"
-    , "\tcat wrappers/$1 >> '$2'"
-    , "\t$(EXECUTABLE_FILE) '$2' ;"
-    , "endef"
-    , ""
-    , "# Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'"
-    , "# fields in the package .conf files"
-    , "define patchpackageconf"
-    , "# $1 = package name (ex: 'bytestring')"
-    , "# $2 = path to .conf file"
-    , "# $3 = Docs Directory"
-    , "\tcat '$2' | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\"
-    , "\t         | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\"
-    , "\t       > '$2.copy'"
-    , "\tmv '$2.copy' '$2'"
-    , "endef"
-    , ""
-    , "# QUESTION : should we use shell commands?"
-    , ""
-    , ""
-    , ".PHONY: install"
-    , "install: install_lib install_bin install_includes"
-    , "install: install_docs install_wrappers install_ghci"
-    , "install: install_mingw update_package_db"
-    , ""
-    , "ActualBinsDir=${ghclibdir}/bin"
-    , "ActualLibsDir=${ghclibdir}/lib"
-    , "WrapperBinsDir=${bindir}"
-    , ""
-    , "# We need to install binaries relative to libraries."
-    , "BINARIES = $(wildcard ./bin/*)"
-    , "install_bin:"
-    , "\t@echo \"Copying binaries to $(ActualBinsDir)\""
-    , "\t$(INSTALL_DIR) \"$(ActualBinsDir)\""
-    , "\tfor i in $(BINARIES); do \\"
-    , "\t\tcp -R $$i \"$(ActualBinsDir)\"; \\"
-    , "\tdone"
-    , ""
-    , "install_ghci:"
-    , "\t@echo \"Installing ghci wrapper\""
-    , "\t@echo \"#!$(SHELL)\" >  '$(WrapperBinsDir)/ghci'"
-    , "\tcat wrappers/ghci-script >> '$(WrapperBinsDir)/ghci'"
-    , "\t$(EXECUTABLE_FILE) '$(WrapperBinsDir)/ghci'"
-    , ""
-    , "LIBRARIES = $(wildcard ./lib/*)"
-    , "install_lib:"
-    , "\t@echo \"Copying libraries to $(ActualLibsDir)\""
-    , "\t$(INSTALL_DIR) \"$(ActualLibsDir)\""
-    , "\tfor i in $(LIBRARIES); do \\"
-    , "\t\tcp -R $$i \"$(ActualLibsDir)/\"; \\"
-    , "\tdone"
-    , ""
-    , "INCLUDES = $(wildcard ./include/*)"
-    , "install_includes:"
-    , "\t@echo \"Copying libraries to $(includedir)\""
-    , "\t$(INSTALL_DIR) \"$(includedir)\""
-    , "\tfor i in $(INCLUDES); do \\"
-    , "\t\tcp -R $$i \"$(includedir)/\"; \\"
-    , "\tdone"
-    , ""
-    , "DOCS = $(wildcard ./docs/*)"
-    , "install_docs:"
-    , "\t@echo \"Copying libraries to $(docdir)\""
-    , "\t$(INSTALL_DIR) \"$(docdir)\""
-    , "\tfor i in $(DOCS); do \\"
-    , "\t\tcp -R $$i \"$(docdir)/\"; \\"
-    , "\tdone"
-    , ""
-    , "BINARY_NAMES=$(shell ls ./wrappers/)"
-    , "install_wrappers:"
-    , "\t@echo \"Installing Wrapper scripts\""
-    , "\t$(INSTALL_DIR) \"$(WrapperBinsDir)\""
-    , "\t$(foreach p, $(BINARY_NAMES),\\"
-    , "\t\t$(call installscript,$p,$(WrapperBinsDir)/$p," ++
-      "$(WrapperBinsDir),$(ActualBinsDir),$(ActualBinsDir)/$p," ++
-      "$(ActualLibsDir),$(docdir),$(includedir)))"
-    , "\trm -f '$(WrapperBinsDir)/ghci-script'" -- FIXME: we shouldn't generate it in the first place
-    , ""
-    , "PKG_CONFS = $(wildcard $(ActualLibsDir)/package.conf.d/*)"
-    , "update_package_db:"
-    , "\t@echo \"Updating the package DB\""
-    , "\t$(foreach p, $(PKG_CONFS),\\"
-    , "\t\t$(call patchpackageconf," ++
-      "$(shell echo $(notdir $p) | sed 's/-\\([0-9]*[0-9]\\.\\)*conf//g')," ++
-      "$p,$(docdir)))"
-    , "\t'$(WrapperBinsDir)/ghc-pkg' recache"
-    , ""
-    , "# The 'foreach' that copies the mingw directory will only trigger a copy"
-    , "# when the wildcard matches, therefore only on Windows."
-    , "MINGW = $(wildcard ./mingw)"
-    , "install_mingw:"
-    , "\t@echo \"Installing MingGW\""
-    , "\t$(INSTALL_DIR) \"$(prefix)/mingw\""
-    , "\t$(foreach d, $(MINGW),\\"
-    , "\t\tcp -R ./mingw \"$(prefix)\")"
-    , "# END INSTALL"
-    , "# ----------------------------------------------------------------------"
-    ]
-
 wrapper :: FilePath -> String
 wrapper "ghc"         = ghcWrapper
 wrapper "ghc-pkg"     = ghcPkgWrapper
diff --git a/hadrian/src/Settings/Builders/Ghc.hs b/hadrian/src/Settings/Builders/Ghc.hs
index 81fc9d183a82f5738e0ddb7d8b7a3576b040b063..0f5ed94b9b309e0adf82977b559802f9fe900fa5 100644
--- a/hadrian/src/Settings/Builders/Ghc.hs
+++ b/hadrian/src/Settings/Builders/Ghc.hs
@@ -97,13 +97,24 @@ ghcLinkArgs = builder (Ghc LinkHs) ? do
             , arg ("-l" ++ libffiName')
             ]
 
+        -- This is the -rpath argument that is required for the bindist scenario
+        -- to work. Indeed, when you install a bindist, the actual executables
+        -- end up nested somewhere under $libdir, with the wrapper scripts
+        -- taking their place in $bindir, and 'rpath' therefore doesn't seem
+        -- to give us the right paths for such a case.
+        -- TODO: Could we get away with just one rpath...?
+        bindistRpath = "$ORIGIN" -/- ".." -/- ".." -/- originToLibsDir
+
     mconcat [ dynamic ? mconcat
                 [ arg "-dynamic"
                 -- TODO what about windows?
                 , isLibrary pkg ? pure [ "-shared", "-dynload", "deploy" ]
-                , hostSupportsRPaths ? arg ("-optl-Wl,-rpath," ++ rpath)
-                -- The darwin linker doesn't support/require the -zorigin option
-                , hostSupportsRPaths ? not darwin ? arg "-optl-Wl,-zorigin"
+                , hostSupportsRPaths ? mconcat
+                      [ arg ("-optl-Wl,-rpath," ++ rpath)
+                      , isProgram pkg ? arg ("-optl-Wl,-rpath," ++ bindistRpath)
+                      -- The darwin linker doesn't support/require the -zorigin option
+                      , not darwin ? arg "-optl-Wl,-zorigin"
+                      ]
                 ]
             , arg "-no-auto-link-packages"
             ,      nonHsMainPackage pkg  ? arg "-no-hs-main"
diff --git a/validate b/validate
index 6b529cf55bfb577c54e094b6da305a67f04e6a10..1aa7ddf4fd4d61dec32460ccb414069c019d060a 100755
--- a/validate
+++ b/validate
@@ -25,6 +25,7 @@ Flags:
                     2008-07-01: 14% slower than the default.
   --quiet           More pretty build log.
                     See Note [Default build system verbosity].
+  --hadrian         Build the compiler and run the tests through hadrian.
   --help            shows this usage help.
 
   validate runs 'make -j\$THREADS', where by default THREADS is the number of
@@ -54,6 +55,7 @@ be_quiet=0
 # heavy cost of xz, which is the typical default. The options are defined in
 # mk/config.mk.in
 tar_comp=gzip
+use_hadrian=NO
 
 while [ $# -gt 0 ]
 do
@@ -82,6 +84,10 @@ do
     --quiet)
         be_quiet=1
         ;;
+    --hadrian)
+	use_hadrian=YES
+	hadrian_build_root=_validatebuild
+	;;
     --help)
         show_help
         exit 0;;
@@ -96,7 +102,12 @@ done
 check_packages () {
     if [ "$bindistdir" = "" ]
     then
-        ghc_pkg=inplace/bin/ghc-pkg
+	if [ "$use_hadrian" = "YES" ]
+	then
+	    ghc_pkg=$hadrian_build_root/stage1/bin/ghc-pkg
+	else
+            ghc_pkg=inplace/bin/ghc-pkg
+	fi
     else
         ghc_pkg="$bindistdir"/bin/ghc-pkg
     fi
@@ -127,26 +138,47 @@ fi
 
 echo "using THREADS=${threads}" >&2
 
-if type gmake > /dev/null 2> /dev/null
+if [ "$use_hadrian" = "NO" ]
 then
     make="gmake"
+   if type gmake > /dev/null 2> /dev/null
+   then
+       make="gmake"
+   else
+       make="make"
+   fi
+   if [ $be_quiet -eq 1 ]; then
+       # See Note [Default build system verbosity].
+       make="$make -s"
+   fi
+   $make -C utils/checkUniques
 else
-    make="make"
-fi
-
-if [ $be_quiet -eq 1 ]; then
-    # See Note [Default build system verbosity].
-    make="$make -s"
+    # Just build hadrian.
+    hadrian/build.sh --help > /dev/null
+    cd hadrian
+    hadrian_cmd=$(cabal new-exec -- which hadrian)
+    cd ..
+    # TODO: define a hadrian Flavour that mimics
+    # mk/flavours/validate.mk and use it here
+    # Until then, we're using the default flavour.
+    hadrian="$hadrian_cmd -j$threads --build-root=$hadrian_build_root"
+    if [ $be_quiet -eq 0 ]; then
+	hadrian="$hadrian -V"
+    fi
+    echo "Hadrian command: $hadrian"
 fi
 
-$make -C utils/checkUniques
-
 if [ $testsuite_only -eq 0 ]; then
 
 thisdir=`pwd`
 
 if [ $no_clean -eq 0 ]; then
-    $make maintainer-clean
+    if [ "$use_hadrian" = "NO" ]
+    then
+	$make maintainer-clean
+    else
+	$hadrian clean && rm -rf $hadrian_build_root
+    fi
 
     INSTDIR="$thisdir/inst"
 
@@ -154,48 +186,88 @@ if [ $no_clean -eq 0 ]; then
     ./configure --prefix="$INSTDIR" $config_args
 fi
 
-echo "Validating=YES"       >  mk/are-validating.mk
-echo "ValidateSpeed=$speed" >> mk/are-validating.mk
-echo "ValidateHpc=$hpc"     >> mk/are-validating.mk
-
-# Note [Default build system verbosity].
-#
-# From https://gitlab.haskell.org/ghc/ghc/wikis/design/build-system:
-#
-#   "The build system should clearly report what it's doing (and sometimes
-#   why), without being too verbose. It should emit actual command lines as
-#   much as possible, so that they can be inspected and cut & pasted."
-#
-# That should be the default. Only suppress commands, by setting V=0 and using
-# `make -s`, when user explicitly asks for it with `./validate --quiet`.
-if [ $be_quiet -eq 1 ]; then
-    # See Note [Default build system verbosity].
-    echo "V=0"                  >> mk/are-validating.mk # Less gunk
-fi
+if [ "$use_hadrian" = "NO" ]
+then
+    echo "Validating=YES"       >  mk/are-validating.mk
+    echo "ValidateSpeed=$speed" >> mk/are-validating.mk
+    echo "ValidateHpc=$hpc"     >> mk/are-validating.mk
+
+    # Note [Default build system verbosity].
+    #
+    # From https://gitlab.haskell.org/ghc/ghc/wikis/design/build-system:
+    #
+    #   "The build system should clearly report what it's doing (and sometimes
+    #   why), without being too verbose. It should emit actual command lines as
+    #   much as possible, so that they can be inspected and cut & pasted."
+    #
+    # That should be the default. Only suppress commands, by setting V=0 and using
+    # `make -s`, when user explicitly asks for it with `./validate --quiet`.
+    if [ $be_quiet -eq 1 ]; then
+	# See Note [Default build system verbosity].
+	echo "V=0"                  >> mk/are-validating.mk # Less gunk
+    fi
 
-$make -j$threads
-# For a "debug make", add "--debug=b --debug=m"
+    $make -j$threads
+    # For a "debug make", add "--debug=b --debug=m"
+else
+    # TODO: define a hadrian Flavour that mimics
+    # mk/flavours/validate.mk and use it here
+    $hadrian
+fi
 
 check_packages post-build
 
+bindistdir="bindisttest/install   dir"
+ghc="$bindistdir/bin/ghc"
+
 # -----------------------------------------------------------------------------
 # Build and test a binary distribution (not --fast)
 
 if [ $speed != "FAST" ]; then
-
-    $make binary-dist-prep TAR_COMP=$tar_comp
-    $make test_bindist TEST_PREP=YES TAR_COMP=$tar_comp
-
-    #
-    # Install the xhtml package into the bindist.
-    # This verifies that we can install a package into the
-    # bindist with Cabal.
-    #
-    bindistdir="bindisttest/install   dir"
+    if [ "$use_hadrian" = "NO" ]
+    then
+	$make binary-dist-prep TAR_COMP=$tar_comp
+	$make test_bindist TEST_PREP=YES TAR_COMP=$tar_comp
+    else
+	$hadrian binary-dist --docs=no-sphinx
+	cfgdir=$(find $hadrian_build_root/bindist/ -name 'configure' | head -1)
+	dir=$(dirname $cfgdir)
+	cd "$dir"
+	./configure --prefix="$thisdir/$bindistdir" && make install
+	cd $thisdir
+	"$ghc" -e 'Data.Text.IO.putStrLn (Data.Text.pack "bindist test: OK")'
+    fi
 
     check_packages post-install
 
-    $make validate_build_xhtml BINDIST_PREFIX="$thisdir/$bindistdir"
+    if [ "$use_hadrian" = "NO" ]
+    then
+	$make validate_build_xhtml BINDIST_PREFIX="$thisdir/$bindistdir"
+    else
+        cd libraries/xhtml
+        dynamicGhc=$("../../$ghc" --info | grep "GHC Dynamic" | cut -d',' -f3 | cut -d'"' -f2)
+        if [ "$dynamicGhc" = "NO" ]
+        then
+            libFlags="--enable-shared --disable-library-vanilla"
+        else
+            libFlags="--disable-shared --enable-library-vanilla"
+        fi
+        libFlags="$libFlags --disable-library-prof"
+
+       "../../$ghc" --make Setup
+       ./Setup configure \
+            --with-ghc="$thisdir/$ghc" \
+            --with-haddock="$thisdir/$bindistdir/bin/haddock" \
+            $libFlags \
+		    --global --builddir=dist-bindist \
+		    --prefix="$thisdir/$bindistdir"
+	    ./Setup build --builddir=dist-bindist
+	    ./Setup haddock -v0 --ghc-options=-optP-P --builddir=dist-bindist
+	    ./Setup install --builddir=dist-bindist
+	    ./Setup clean --builddir=dist-bindist
+	    rm -f Setup Setup.exe Setup.hi Setup.o
+	    cd ../../
+    fi
 
     check_packages post-xhtml
 fi
@@ -229,14 +301,17 @@ case "$speed" in
 SLOW)
         MAKE_TEST_TARGET=slowtest
         BINDIST="BINDIST=YES"
+	HADRIAN_TEST_SPEED=slow
         ;;
 NORMAL)
         MAKE_TEST_TARGET=test
         BINDIST="BINDIST=YES"
+	HADRIAN_TEST_SPEED=normal
         ;;
 FAST)
         MAKE_TEST_TARGET=fasttest
         BINDIST="BINDIST=NO"
+	HADRIAN_TEST_SPEED=fast
         ;;
 esac
 
@@ -252,21 +327,33 @@ fi
 
 rm -f testsuite_summary.txt testsuite_summary_stage1.txt
 
-# Use LOCAL=0, see Note [Running tests in /tmp].
-$make -C testsuite/tests $BINDIST $PYTHON_ARG \
-      $MAKE_TEST_TARGET stage=2 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \
-      NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../testsuite_summary.txt \
-      JUNIT_FILE=../../testsuite.xml \
-      2>&1 | tee testlog
-
-# Run a few tests using the stage1 compiler.
-# See Note [Why is there no stage1 setup function?].
-# Don't use BINDIST=YES, as stage1 is not available in a bindist.
-$make -C testsuite/tests/stage1 $PYTHON_ARG \
-      $MAKE_TEST_TARGET stage=1 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \
-      NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../../testsuite_summary_stage1.txt \
-      JUNIT_FILE=../../../testsuite_stage1.xml \
-      2>&1 | tee testlog-stage1
+if [ "$use_hadrian" = "NO" ]
+then
+    # Use LOCAL=0, see Note [Running tests in /tmp].
+    $make -C testsuite/tests $BINDIST $PYTHON_ARG \
+	  $MAKE_TEST_TARGET stage=2 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \
+	  NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../testsuite_summary.txt \
+	  JUNIT_FILE=../../testsuite.xml \
+	  2>&1 | tee testlog
+
+    # Run a few tests using the stage1 compiler.
+    # See Note [Why is there no stage1 setup function?].
+    # Don't use BINDIST=YES, as stage1 is not available in a bindist.
+    $make -C testsuite/tests/stage1 $PYTHON_ARG \
+	  $MAKE_TEST_TARGET stage=1 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \
+	  NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../../testsuite_summary_stage1.txt \
+	  JUNIT_FILE=../../../testsuite_stage1.xml \
+	  2>&1 | tee testlog-stage1
+else
+    testghc="$thisdir/$ghc"
+    arg="test --test-speed=$HADRIAN_TEST_SPEED \
+              --test-compiler=\"$testghc\" \
+              --summary=$thisdir/testsuite_summary.txt \
+              --summary-junit=$thisdir/testsuite.xml"
+    sh -c "$hadrian $arg"
+    # TODO: Run testsuite/tests/stage1 using the stage 1 compiler when
+    # BINDIST=NO.
+fi
 
 echo
 echo '==== STAGE 1 TESTS ==== '