summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hadrian/README.md38
-rwxr-xr-xhadrian/ghci.sh3
-rw-r--r--hadrian/hadrian.cabal1
-rw-r--r--hadrian/src/Builder.hs6
-rw-r--r--hadrian/src/Main.hs1
-rw-r--r--hadrian/src/Oracles/Setting.hs2
-rw-r--r--hadrian/src/Rules.hs35
-rwxr-xr-xhadrian/src/Settings.hs4
-rw-r--r--hadrian/src/Settings/Builders/Ghc.hs13
-rw-r--r--hadrian/src/Settings/Flavours/GhcInGhci.hs25
10 files changed, 123 insertions, 5 deletions
diff --git a/hadrian/README.md b/hadrian/README.md
index 179d9d07ce..77c3cd0950 100644
--- a/hadrian/README.md
+++ b/hadrian/README.md
@@ -158,6 +158,27 @@ build stage2:lib:text
build stage1:exe:haddock
```
+#### Fast feedback using ghci
+
+Running the `./hadrian/ghci.sh` script will load the main compiler into
+a ghci session. This is intended for fast development feedback, modules are only
+typechecked so it isn't possible to run any functions in the repl.
+
+```
+./hadrian/ghci.sh
+```
+
+You can also use this target with `ghcid`.
+
+```
+ghcid --command="./hadrian/ghci.sh"
+```
+
+The first time this command is run hadrian will need to compile a few dependencies
+which will take 1-2 minutes. Loading GHC into GHCi itself takes about 30 seconds and
+reloads after that take in the region of 1-5 seconds depending on which modules
+need to be recompiled.
+
#### Testing
To run GHC testsuite, use `build test`. See
@@ -203,6 +224,23 @@ a compiler built using Stage2. This is useful for cross-compilation. Detailed
instructions can be found in the corresponding
[part of the user settings manual](doc/user-settings.md#specifying-the-final-stage-to-build).
+#### Integrating Hadrian into other tooling
+
+The `tool-args` target is designed to allow hadrian to be integrated into other
+tooling which uses the GHC API.
+`tool-args` prints out a list of flags which hadrian will use to compile
+a module in the `compiler` directory. Using these flags you can then set up
+a GHC API session with the correct environment to load a module into your own
+GHC session. This is how `haskell-ide-engine` is able to support hadrian.
+
+```
+> ./hadrian/build.sh tool-args
+-hide-all-packages -no-user-package-db -package-db _build/stage0/lib/packag...
+```
+
+
+The `./hadrian/ghci.sh` script is implemented using this target.
+
Troubleshooting
---------------
diff --git a/hadrian/ghci.sh b/hadrian/ghci.sh
new file mode 100755
index 0000000000..4a70946269
--- /dev/null
+++ b/hadrian/ghci.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+ghci $(TERM=dumb CABFLAGS=-v0 . "hadrian/build.cabal.sh" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@") -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs
diff --git a/hadrian/hadrian.cabal b/hadrian/hadrian.cabal
index a5a1ead0e7..a0b364855f 100644
--- a/hadrian/hadrian.cabal
+++ b/hadrian/hadrian.cabal
@@ -97,6 +97,7 @@ executable hadrian
, Settings.Flavours.Quick
, Settings.Flavours.QuickCross
, Settings.Flavours.Quickest
+ , Settings.Flavours.GhcInGhci
, Settings.Packages
, Settings.Warnings
, Stage
diff --git a/hadrian/src/Builder.hs b/hadrian/src/Builder.hs
index 6d334d80f4..d855aa5bde 100644
--- a/hadrian/src/Builder.hs
+++ b/hadrian/src/Builder.hs
@@ -45,7 +45,11 @@ instance NFData CcMode
-- * Compile a C source file.
-- * Extract source dependencies by passing @-M@ command line argument.
-- * Link object files & static libraries into an executable.
-data GhcMode = CompileHs | CompileCWithGhc | FindHsDependencies | LinkHs
+data GhcMode = CompileHs
+ | CompileCWithGhc
+ | FindHsDependencies
+ | LinkHs
+ | ToolArgs
deriving (Eq, Generic, Show)
instance Binary GhcMode
diff --git a/hadrian/src/Main.hs b/hadrian/src/Main.hs
index 083e6838d8..fe5dbbb937 100644
--- a/hadrian/src/Main.hs
+++ b/hadrian/src/Main.hs
@@ -50,6 +50,7 @@ main = do
Rules.SourceDist.sourceDistRules
Rules.Test.testRules
Rules.topLevelTargets
+ Rules.toolArgsTarget
shakeArgsWith options CommandLine.optDescrs $ \_ targets -> do
Environment.setupEnvironment
diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs
index 4666539f93..a869a31e12 100644
--- a/hadrian/src/Oracles/Setting.hs
+++ b/hadrian/src/Oracles/Setting.hs
@@ -3,7 +3,7 @@ module Oracles.Setting (
getSettingList, anyTargetPlatform, anyTargetOs, anyTargetArch, anyHostOs,
ghcWithInterpreter, ghcEnableTablesNextToCode, useLibFFIForAdjustors,
ghcCanonVersion, cmdLineLengthLimit, iosHost, osxHost, windowsHost,
- hostSupportsRPaths, topDirectory, libsuf
+ hostSupportsRPaths, topDirectory, libsuf, ghcVersionStage
) where
import Hadrian.Expression
diff --git a/hadrian/src/Rules.hs b/hadrian/src/Rules.hs
index c5be5a7ff9..e4de23f34d 100644
--- a/hadrian/src/Rules.hs
+++ b/hadrian/src/Rules.hs
@@ -1,4 +1,5 @@
-module Rules (buildRules, oracleRules, packageTargets, topLevelTargets) where
+module Rules (buildRules, oracleRules, packageTargets, topLevelTargets
+ , toolArgsTarget ) where
import qualified Hadrian.Oracles.ArgsHash
import qualified Hadrian.Oracles.Cabal.Rules
@@ -26,6 +27,38 @@ import Target
import UserSettings
import Utilities
+
+-- | @tool-args@ 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
+-- run, the target prints out the arguments that would be passed to @ghc@
+-- during normal compilation to @stdout@.
+--
+-- This target is called by the `ghci.sh` script in order to load all of GHC's
+-- modules into GHCi.
+toolArgsTarget :: Rules ()
+toolArgsTarget = do
+ "tool-args" ~> do
+ let fake_target = target (Context Stage0 compiler dynamic)
+ (Ghc ToolArgs Stage0) [] ["ignored"]
+
+ -- need the autogenerated files so that they are precompiled
+ generatedGhcDependencies Stage0 >>= need
+ interpret fake_target Rules.Generate.compilerDependencies >>= need
+
+ root <- buildRoot
+ let dir = buildDir (vanillaContext Stage0 compiler)
+ need [ root <//> dir -/- "Config.hs" ]
+ need [ root <//> dir -/- "Fingerprint.hs" ]
+ need [ root <//> dir -/- "Parser.hs" ]
+ need [ root <//> dir -/- "Lexer.hs" ]
+ need [ root <//> dir -/- "CmmParse.hs" ]
+ need [ root <//> dir -/- "CmmLex.hs" ]
+
+ -- Find out the arguments that are needed to load a module into the
+ -- session
+ arg_list <- interpret fake_target getArgs
+ liftIO $ putStrLn (intercalate " " arg_list)
+
allStages :: [Stage]
allStages = [minBound .. maxBound]
diff --git a/hadrian/src/Settings.hs b/hadrian/src/Settings.hs
index bc0f8cecaa..3089c0a4e6 100755
--- a/hadrian/src/Settings.hs
+++ b/hadrian/src/Settings.hs
@@ -18,6 +18,7 @@ import Settings.Flavours.Profiled
import Settings.Flavours.Quick
import Settings.Flavours.Quickest
import Settings.Flavours.QuickCross
+import Settings.Flavours.GhcInGhci
getArgs :: Args
getArgs = expr flavour >>= args
@@ -38,7 +39,8 @@ hadrianFlavours =
[ defaultFlavour, developmentFlavour Stage1, developmentFlavour Stage2
, performanceFlavour, profiledFlavour, quickFlavour, quickestFlavour
, quickCrossFlavour
- , performanceLlvmFlavour, profiledLlvmFlavour, quickLlvmFlavour ]
+ , performanceLlvmFlavour, profiledLlvmFlavour, quickLlvmFlavour
+ , ghcInGhciFlavour ]
flavour :: Action Flavour
flavour = do
diff --git a/hadrian/src/Settings/Builders/Ghc.hs b/hadrian/src/Settings/Builders/Ghc.hs
index 0d0d58a09f..940eab546a 100644
--- a/hadrian/src/Settings/Builders/Ghc.hs
+++ b/hadrian/src/Settings/Builders/Ghc.hs
@@ -11,7 +11,18 @@ import qualified Context as Context
import Rules.Libffi (libffiName)
ghcBuilderArgs :: Args
-ghcBuilderArgs = mconcat [compileAndLinkHs, compileC, findHsDependencies]
+ghcBuilderArgs = mconcat [ compileAndLinkHs, compileC, findHsDependencies
+ , toolArgs]
+
+toolArgs :: Args
+toolArgs = do
+ builder (Ghc ToolArgs) ? mconcat
+ [ packageGhcArgs
+ , includeGhcArgs
+ , map ("-optc" ++) <$> getStagedSettingList ConfCcArgs
+ , map ("-optP" ++) <$> getStagedSettingList ConfCppArgs
+ , map ("-optP" ++) <$> getContextData cppOpts
+ ]
compileAndLinkHs :: Args
compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do
diff --git a/hadrian/src/Settings/Flavours/GhcInGhci.hs b/hadrian/src/Settings/Flavours/GhcInGhci.hs
new file mode 100644
index 0000000000..82fd0f2411
--- /dev/null
+++ b/hadrian/src/Settings/Flavours/GhcInGhci.hs
@@ -0,0 +1,25 @@
+module Settings.Flavours.GhcInGhci (ghcInGhciFlavour) where
+
+import Expression
+import Flavour
+import {-# SOURCE #-} Settings.Default
+import Settings.Flavours.Common
+
+-- Please update doc/flavours.md when changing this file.
+ghcInGhciFlavour :: Flavour
+ghcInGhciFlavour = defaultFlavour
+ { name = "ghc-in-ghci"
+ , args = defaultBuilderArgs <> ghciArgs <> defaultPackageArgs
+ , libraryWays = pure [vanilla, dynamic]
+ , rtsWays = pure [vanilla, threaded, dynamic]
+ , dynamicGhcPrograms = return False }
+
+ghciArgs :: Args
+ghciArgs = sourceArgs SourceArgs
+ { hsDefault = mconcat $
+ [ pure ["-O0", "-H64m"]
+ , naturalInBaseFixArgs
+ ]
+ , hsLibrary = mempty
+ , hsCompiler = mempty
+ , hsGhc = mempty }