diff --git a/hadrian/ghci-cabal.in b/hadrian/ghci-cabal.in
index 2a97b371802ba85364831abd12e74a7fef08dc09..0245ed6b0905bebe797e69bd759ff98a0a443b76 100755
--- a/hadrian/ghci-cabal.in
+++ b/hadrian/ghci-cabal.in
@@ -3,7 +3,8 @@
 # This file is generated by configure from ghci-cabal.in
 
 set -e
-
+export TOOL_OUTPUT=.hadrian_ghci/ghci_args
 # Replace newlines with spaces, as these otherwise break the ghci invocation on windows.
-GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool:ghc/Main.hs -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')"
+CABFLAGS=-v0 "hadrian/build-cabal" tool:compiler/GHC.hs --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS
+GHC_FLAGS="$GHC_FLAGS $(cat $TOOL_OUTPUT | tr '\n\r' ' ')"
 @WithGhc@ --interactive $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m
diff --git a/hadrian/ghci-stack.in b/hadrian/ghci-stack.in
index ef95552b6463f8ffa915f9eebc1613eef34e9810..12f388820590c0025d1267b1a099d7929e63c42e 100755
--- a/hadrian/ghci-stack.in
+++ b/hadrian/ghci-stack.in
@@ -4,6 +4,9 @@
 
 set -e
 
+export TOOL_OUTPUT=.hadrian_ghci/ghci_args
+TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool:compiler/GHC.hs -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS
+
 # Replace newlines with spaces, as these otherwise break the ghci invocation on windows.
-GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')"
+GHC_FLAGS="$GHC_FLAGS $(cat $TOOL_OUTPUT | tr '\n\r' ' ')"
 stack exec -- @WithGhc@ --interactive $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m
diff --git a/hadrian/hie-bios b/hadrian/hie-bios
index 4def2e8823c9e95cc4b15a96189358741b96c39d..49224253b8aeb370bf310171b7251354efad3981 100755
--- a/hadrian/hie-bios
+++ b/hadrian/hie-bios
@@ -3,5 +3,5 @@
 # When run, this program will output a list of arguments which are necessary to
 # load the GHC library component into GHCi. The program is used by `ghcide` in
 # order to automatically set up the correct GHC API session for a project.
-TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool:$1 -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT
+TERM=dumb CABFLAGS=-v0 TOOL_OUTPUT=$HIE_BIOS_OUTPUT $PWD/hadrian/build-cabal tool:$1 -q --build-root=.hie-bios --flavour=ghc-in-ghci
 
diff --git a/hadrian/hie-bios.bat b/hadrian/hie-bios.bat
index fda322af58f3b9921a157d33048a45862f4c90f5..73bbea82be3576965d243df787e410afea1cdb52 100644
--- a/hadrian/hie-bios.bat
+++ b/hadrian/hie-bios.bat
@@ -1,3 +1,4 @@
 set TERM=dumb
 set CABFLAGS=-v0
-%CD%\hadrian\build-cabal.bat tool:%1 -q --build-root=_hie-bios --flavour=ghc-in-ghci > %HIE_BIOS_OUTPUT%
+set TOOL_OUTPUT=%HIE_BIOS_OUTPUT%
+%CD%\hadrian\build-cabal.bat tool:%1 --build-root=_hie-bios --flavour=ghc-in-ghci
diff --git a/hadrian/src/Rules/ToolArgs.hs b/hadrian/src/Rules/ToolArgs.hs
index 105ed8f15a802297c82c7d35b32ecdf11d06a885..d0905d45488049c9c1f476f15a8cd4b189b1ffc4 100644
--- a/hadrian/src/Rules/ToolArgs.hs
+++ b/hadrian/src/Rules/ToolArgs.hs
@@ -12,6 +12,7 @@ import Settings
 import Hadrian.Oracles.Cabal
 import Hadrian.Haskell.Cabal.Type
 import System.Directory (canonicalizePath)
+import System.Environment (lookupEnv)
 
 -- | @tool:@ is used by tooling in order to get the arguments necessary
 -- to set up a GHC API session which can compile modules from GHC. When
@@ -48,11 +49,15 @@ mkToolTarget :: [String] -> Package -> Action ()
 mkToolTarget es p = do
     -- This builds automatically generated dependencies. Not sure how to do
     -- this generically yet.
+    putProgressInfo ("Computing arguments for " ++ pkgName p)
     allDeps
     let fake_target = target (Context stage0InTree p (if windowsHost then vanilla else dynamic))
                         (Ghc ToolArgs stage0InTree) [] ["ignored"]
     arg_list <- interpret fake_target getArgs
-    liftIO $ putStrLn (intercalate "\n" (arg_list ++ es))
+    liftIO $ lookupEnv "TOOL_OUTPUT" >>= \case
+      Nothing -> putStrLn (intercalate "\n" (arg_list ++ es))
+      Just out -> writeFile out (intercalate "\n" (arg_list ++ es))
+
 allDeps :: Action ()
 allDeps = do
    do