diff options
-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 } |