summaryrefslogtreecommitdiff
path: root/hadrian
diff options
context:
space:
mode:
Diffstat (limited to 'hadrian')
-rw-r--r--hadrian/src/Packages.hs68
-rw-r--r--hadrian/src/Settings/Default.hs2
2 files changed, 55 insertions, 15 deletions
diff --git a/hadrian/src/Packages.hs b/hadrian/src/Packages.hs
index fa87d8edcd..a1916b20cd 100644
--- a/hadrian/src/Packages.hs
+++ b/hadrian/src/Packages.hs
@@ -4,7 +4,7 @@ module Packages (
array, base, binary, bytestring, cabal, checkApiAnnotations, checkPpr,
compareSizes, compiler, containers, deepseq, deriveConstants, directory,
exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh,
- ghcCompact, ghcHeap, ghci, ghcPkg, ghcPrim, haddock, haskeline,
+ ghcCompact, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline,
hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy,
libffi, libiserv, mtl, parsec, pretty, primitive, process, remoteIserv, rts,
runGhc, stm, templateHaskell, terminfo, text, time, timeout, touchy,
@@ -34,7 +34,7 @@ ghcPackages =
[ array, base, binary, bytestring, cabal, checkPpr, checkApiAnnotations
, compareSizes, compiler, containers, deepseq, deriveConstants, directory
, exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh
- , ghcCompact, ghcHeap, ghci, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs
+ , ghcCompact, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs
, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, libiserv, mtl
, parsec, pretty, process, rts, runGhc, stm, templateHaskell
, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml
@@ -69,6 +69,8 @@ ghcBootTh = lib "ghc-boot-th"
ghcCompact = lib "ghc-compact"
ghcHeap = lib "ghc-heap"
ghci = lib "ghci"
+ghciWrapper = prg "ghci-wrapper" `setPath` "driver/ghci"
+ -- See Note [Hadrian's ghci-wrapper package]
ghcPkg = util "ghc-pkg"
ghcPrim = lib "ghc-prim"
haddock = util "haddock"
@@ -138,18 +140,21 @@ programName Context {..} = do
-- use Cabal conditionals + a 'profiling' flag
-- to declare the executable name, and I'm not sure
-- this is allowed (or desired for that matter).
- return $ prefix ++ case package of
- p | p == ghc -> "ghc"
- | p == hpcBin -> "hpc"
- | p == iserv -> "ghc-iserv" ++ concat [
- if wayUnit' `wayUnit` way
- then suffix
- else ""
- | (wayUnit', suffix) <- [
- (Profiling, "-prof"),
- (Dynamic, "-dyn")
- ]]
- _ -> pkgName package
+ return $ prefix ++ basename
+ where
+ basename
+ | package == ghc = "ghc"
+ | package == ghciWrapper = "ghci" -- See Note [Hadrian's ghci-wrapper package]
+ | package == hpcBin = "hpc"
+ | package == iserv = "ghc-iserv" ++ concat [
+ if wayUnit' `wayUnit` way
+ then suffix
+ else ""
+ | (wayUnit', suffix) <- [
+ (Profiling, "-prof"),
+ (Dynamic, "-dyn")
+ ]]
+ | otherwise = pkgName package
-- | The 'FilePath' to a program executable in a given 'Context'.
programPath :: Context -> Action FilePath
@@ -172,7 +177,7 @@ timeoutPath = "testsuite/timeout/install-inplace/bin/timeout" <.> exe
-- TODO: Can we extract this information from Cabal files?
-- | Some program packages should not be linked with Haskell main function.
nonHsMainPackage :: Package -> Bool
-nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit])
+nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit, ghciWrapper])
-- TODO: Combine this with 'programName'.
-- | Path to the @autogen@ directory generated by 'buildAutogenFiles'.
@@ -181,6 +186,8 @@ autogenPath context@Context {..}
| isLibrary package = autogen "build"
| package == ghc = autogen "build/ghc"
| package == hpcBin = autogen "build/hpc"
+ | package == ghciWrapper = autogen "build/ghci"
+ -- See Note [Hadrian's ghci-wrapper package]
| otherwise = autogen $ "build" -/- pkgName package
where
autogen dir = contextPath context <&> (-/- dir -/- "autogen")
@@ -218,3 +225,34 @@ libffiLibraryName = do
(True , False) -> "ffi"
(False, False) -> "Cffi"
(_ , True ) -> "Cffi-6"
+
+
+{-
+Note [Hadrian's ghci-wrapper package]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+On Linux platforms the `ghci` executable is a shell-script wrapper produced
+by the binary distribution `install` rule. However, this approach is not
+viable work on Windows platforms, where binary distributions are usable
+directly after unzipping, without any need for the user to run `make install`.
+
+Moreover, Windows has rather special requirements regarding console setup and
+teardown. Consequently on Windows ghci.exe is a purpose-built executable, the
+C source of which is found in driver/ghci. Getting Hadrian to build this via
+Cabal requires a few headstands:
+
+ - Hadrian generally assumes that the name of the executable produced by a
+ 'Program' package is the same as the package name. However, this is not
+ the case here: we name the package `ghci-wrapper` to avoid conflicting
+ with the `ghci` library yet we want the final executable to be named
+ `ghci.exe`. We accomplish this by overriding 'Packages.programName'.
+
+ - The executable requires a few C sources (which live in `driver/utils`) in
+ addition to the main ghci.c. Ideally these would be built independently as
+ a static library which could then be linked into the executable;
+ unfortunately Cabal doesn't support this. We instead add the sources to
+ the C-Sources list in the Cabal file.
+
+ - Unfortunately, Cabal/Hadrian's handling of C-sources appears to fall on
+ its face when a relative path is used (e.g. `../cwrapper.c`). Consequently
+ we copy the files into `driver/ghci` in the configure script.
+-}
diff --git a/hadrian/src/Settings/Default.hs b/hadrian/src/Settings/Default.hs
index d965133a88..deb9bd80b7 100644
--- a/hadrian/src/Settings/Default.hs
+++ b/hadrian/src/Settings/Default.hs
@@ -124,6 +124,8 @@ stage1Packages = do
++ [ libiserv | not cross ]
++ [ runGhc | not cross ]
++ [ touchy | windowsHost ]
+ -- See Note [Hadrian's ghci-wrapper package]
+ ++ [ ghciWrapper | windowsHost ]
++ [ unix | not windowsHost ]
++ [ win32 | windowsHost ]