diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2019-03-10 17:43:10 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-03-12 09:04:52 -0400 |
commit | 2d7dd0285bbc364f89d4d97928674f7ea73ed2c8 (patch) | |
tree | 64afbe9484037925efe0575e77971f532ac155fd /hadrian | |
parent | 4cf2160afe0e08fe29576895a1eced863d3a521d (diff) | |
download | haskell-2d7dd0285bbc364f89d4d97928674f7ea73ed2c8.tar.gz |
Hadrian: Add ./hadrian/ghci.sh script for fast development feedback
Running the `./hadrian/ghci` target 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.
You can also use this target with `ghcid`.
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.
Internally this works by calling a new hadrian target called `tool-args`.
This target prints out the package and include flags which are necessary
to load files into ghci. The same target is intended to be used by other
tooling which uses the GHC API in order to set up the correct GHC API
session. For example, using this target it is also possible to use HIE
when developing on GHC.
Diffstat (limited to 'hadrian')
-rw-r--r-- | hadrian/README.md | 38 | ||||
-rwxr-xr-x | hadrian/ghci.sh | 3 | ||||
-rw-r--r-- | hadrian/hadrian.cabal | 1 | ||||
-rw-r--r-- | hadrian/src/Builder.hs | 6 | ||||
-rw-r--r-- | hadrian/src/Main.hs | 1 | ||||
-rw-r--r-- | hadrian/src/Oracles/Setting.hs | 2 | ||||
-rw-r--r-- | hadrian/src/Rules.hs | 35 | ||||
-rwxr-xr-x | hadrian/src/Settings.hs | 4 | ||||
-rw-r--r-- | hadrian/src/Settings/Builders/Ghc.hs | 13 | ||||
-rw-r--r-- | hadrian/src/Settings/Flavours/GhcInGhci.hs | 25 |
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 } |