aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gröber <dxld@darkboxed.org>2018-10-22 01:20:56 +0200
committerDaniel Gröber <dxld@darkboxed.org>2018-10-27 20:48:56 +0200
commit783eadafe6e6333123add96d2fc0276c8b4cc1d9 (patch)
treefe16786a713d727ab5975f9b1f0f852005308053
parent069225e2e61562c8166a446d201457425b91ce57 (diff)
Suport using Stack's built-in GHC to build the helper
-rw-r--r--lib/Distribution/Helper.hs84
-rw-r--r--src/CabalHelper/Compiletime/Compile.hs35
-rw-r--r--src/CabalHelper/Compiletime/Program/Stack.hs7
-rw-r--r--src/CabalHelper/Compiletime/Types.hs42
-rw-r--r--tests/CompileTest.hs1
5 files changed, 82 insertions, 87 deletions
diff --git a/lib/Distribution/Helper.hs b/lib/Distribution/Helper.hs
index 0190129..452bb91 100644
--- a/lib/Distribution/Helper.hs
+++ b/lib/Distribution/Helper.hs
@@ -54,6 +54,7 @@ module Distribution.Helper (
, mkQueryEnv
, qeReadProcess
, qePrograms
+ , qeCompPrograms
, qeProjLoc
, qeDistDir
@@ -82,7 +83,6 @@ module Distribution.Helper (
-- * Managing @dist/@
, prepare
- , reconfigure
, writeAutogenFiles
-- * Reexports
@@ -177,10 +177,11 @@ mkQueryEnv projloc distdir = do
return $ QueryEnv
{ qeReadProcess = \mcwd exe args stdin ->
readCreateProcess (proc exe args){ cwd = mcwd } stdin
- , qePrograms = defaultPrograms
- , qeDistDir = distdir
- , qeCacheRef = cr
+ , qePrograms = defaultPrograms
+ , qeCompPrograms = defaultCompPrograms
, qeProjLoc = projloc
+ , qeDistDir = distdir
+ , qeCacheRef = cr
}
-- | Construct paths to project configuration files.
@@ -244,25 +245,6 @@ unitQuery u = Query $ \qe -> getUnitInfo qe u
allUnits :: (UnitInfo -> a) -> Query pt [a]
allUnits f = map f <$> (mapM unitQuery =<< projectUnits)
--- | Run @cabal configure@
-reconfigure :: MonadIO m
- => (FilePath -> [String] -> String -> IO String)
- -> Programs -- ^ Program paths
- -> [String] -- ^ Command line arguments to be passed to @cabal@
- -> m ()
-reconfigure readProc progs cabalOpts = do
- let progOpts =
- [ "--with-ghc=" ++ ghcProgram progs ]
- -- Only pass ghc-pkg if it was actually set otherwise we
- -- might break cabal's guessing logic
- ++ if ghcPkgProgram progs /= "ghc-pkg"
- then [ "--with-ghc-pkg=" ++ ghcPkgProgram progs ]
- else []
- ++ cabalOpts
- _ <- liftIO $ readProc (cabalProgram progs) ("configure":progOpts) ""
- return ()
-
-
getProjInfo :: QueryEnv pt -> IO (ProjInfo pt)
getProjInfo qe@QueryEnv{..} = do
cache@QueryCache{qcProjInfo, qcUnitInfos} <- readIORef qeCacheRef
@@ -321,7 +303,7 @@ checkUpdateUnitInfo qe proj_info unit munit_info = do
where
reconf = do
reconfigureUnit qe unit
- helper <- wrapper proj_info qe
+ helper <- getHelperExe proj_info qe
readUnitInfo qe helper unit
-- | Restrict 'UnitInfo' cache to units that are still active
@@ -386,7 +368,7 @@ getFileModTime f = do
readProjInfo
:: QueryEnvI c pt -> ProjConf pt -> ProjConfModTimes -> IO (ProjInfo pt)
-readProjInfo qe pc pcm = join $ withVerbosity $ do
+readProjInfo qe pc pcm = withVerbosity $ do
case (qeProjLoc qe, qeDistDir qe, pc) of
((,,)
projloc
@@ -432,7 +414,12 @@ readProjInfo qe pc pcm = join $ withVerbosity $ do
cabal_files <- Stack.listPackageCabalFiles qe
units <- mapM (Stack.getUnit qe) cabal_files
proj_paths <- Stack.projPaths qe
+ cprogs <-
+ guessCompProgramPaths $
+ Stack.patchCompPrograms proj_paths $
+ qeCompPrograms qe
Just (cabalVer:_) <- runMaybeT $
+ let ?cprogs = cprogs in
let ?progs = qePrograms qe in
listCabalVersions' (Just (sppGlobalPkgDb proj_paths))
-- ^ See [Note Stack Cabal Version]
@@ -541,14 +528,14 @@ invokeHelper
prepare :: QueryEnv pt -> IO ()
prepare qe = do
proj_info <- getProjInfo qe
- void $ wrapper proj_info qe
+ void $ getHelperExe proj_info qe
-- | Create @cabal_macros.h@ and @Paths_\<pkg\>@ possibly other generated files
-- in the usual place. See 'Distribution.Simple.Build.initialBuildSteps'.
writeAutogenFiles :: Unit -> Query pt ()
writeAutogenFiles Unit{uCabalFile, uDistDir} = Query $ \qe -> do
proj_info <- getProjInfo qe
- exe <- wrapper proj_info qe
+ exe <- getHelperExe proj_info qe
void $ invokeHelper qe exe uCabalFile uDistDir ["write-autogen-files"]
-- | Get the path to the sandbox package-db in a project
@@ -570,16 +557,15 @@ buildPlatform = display Distribution.System.buildPlatform
lookupEnv' :: String -> IO (Maybe String)
lookupEnv' k = lookup k <$> getEnvironment
-guessProgramPaths :: (Verbose, Progs) => (Progs => IO a) -> IO a
-guessProgramPaths act = do
+-- | Determine ghc-pkg path from ghc path
+guessCompProgramPaths :: Verbose => CompPrograms -> IO CompPrograms
+guessCompProgramPaths progs = do
let v | ?verbose = deafening
| otherwise = silent
-
- mGhcPath0 | same ghcProgram ?progs dprogs = Nothing
- | otherwise = Just $ ghcProgram ?progs
- mGhcPkgPath0 | same ghcPkgProgram ?progs dprogs = Nothing
- | otherwise = Just $ ghcPkgProgram ?progs
-
+ mGhcPath0 | same ghcProgram progs dprogs = Nothing
+ | otherwise = Just $ ghcProgram progs
+ mGhcPkgPath0 | same ghcPkgProgram progs dprogs = Nothing
+ | otherwise = Just $ ghcPkgProgram progs
(_compiler, _mplatform, progdb)
<- GHC.configure
v
@@ -589,31 +575,31 @@ guessProgramPaths act = do
let getProg p = ProgDb.programPath <$> ProgDb.lookupProgram p progdb
mghcPath1 = getProg ProgDb.ghcProgram
mghcPkgPath1 = getProg ProgDb.ghcPkgProgram
+ return progs
+ { ghcProgram = fromMaybe (ghcProgram progs) mghcPath1
+ , ghcPkgProgram = fromMaybe (ghcProgram progs) mghcPkgPath1
+ }
- let ?progs = ?progs
- { ghcProgram = fromMaybe (ghcProgram ?progs) mghcPath1
- , ghcPkgProgram = fromMaybe (ghcProgram ?progs) mghcPkgPath1
- }
- act
- where
+ where
same f o o' = f o == f o'
- dprogs = defaultPrograms
+ dprogs = defaultCompPrograms
-withVerbosity :: (Verbose => a) -> IO a
-withVerbosity a = do
+withVerbosity :: (Verbose => IO a) -> IO a
+withVerbosity act = do
x <- lookup "CABAL_HELPER_DEBUG" <$> getEnvironment
let ?verbose =
case x of
Just xs | not (null xs) -> True
_ -> False
- return a
+ act
-wrapper
+getHelperExe
:: ProjInfo pt -> QueryEnvI c pt -> IO FilePath
-wrapper proj_info QueryEnv{..} = do
- join $ withVerbosity $ do
- let ?progs = qePrograms
+getHelperExe proj_info QueryEnv{..} = do
+ withVerbosity $ do
let comp = wrapper' qeProjLoc qeDistDir proj_info
+ let ?progs = qePrograms
+ ?cprogs = qeCompPrograms
eexe <- compileHelper comp
case eexe of
Left rv ->
diff --git a/src/CabalHelper/Compiletime/Compile.hs b/src/CabalHelper/Compiletime/Compile.hs
index 3f8a771..431043b 100644
--- a/src/CabalHelper/Compiletime/Compile.hs
+++ b/src/CabalHelper/Compiletime/Compile.hs
@@ -326,9 +326,10 @@ cabalMinVersionMacro (Version (mj1:mj2:mi:_) _) =
cabalMinVersionMacro _ =
error "cabalMinVersionMacro: Version must have at least 3 components"
-invokeGhc :: Env => GhcInvocation -> IO (Either ExitCode FilePath)
+invokeGhc
+ :: (Verbose, CProgs) => GhcInvocation -> IO (Either ExitCode FilePath)
invokeGhc GhcInvocation {..} = do
- rv <- callProcessStderr' Nothing (ghcProgram ?progs) $ concat
+ rv <- callProcessStderr' Nothing (ghcProgram ?cprogs) $ concat
[ [ "-outputdir", giOutDir
, "-o", giOutput
]
@@ -364,7 +365,7 @@ exeName CabalVersion {cabalVersion} = intercalate "-"
, "Cabal" ++ showVersion cabalVersion
]
-readProcess' :: Env => FilePath -> [String] -> String -> IO String
+readProcess' :: Verbose => FilePath -> [String] -> String -> IO String
readProcess' exe args inp = do
vLog $ intercalate " " $ map formatProcessArg (exe:args)
outp <- readProcess exe args inp
@@ -372,7 +373,7 @@ readProcess' exe args inp = do
return outp
callProcessStderr'
- :: Env => Maybe FilePath -> FilePath -> [String] -> IO ExitCode
+ :: Verbose => Maybe FilePath -> FilePath -> [String] -> IO ExitCode
callProcessStderr' mwd exe args = do
let cd = case mwd of
Nothing -> []; Just wd -> [ "cd", formatProcessArg wd++";" ]
@@ -381,7 +382,7 @@ callProcessStderr' mwd exe args = do
, cwd = mwd }
waitForProcess h
-callProcessStderr :: Env => Maybe FilePath -> FilePath -> [String] -> IO ()
+callProcessStderr :: Verbose => Maybe FilePath -> FilePath -> [String] -> IO ()
callProcessStderr mwd exe args = do
rv <- callProcessStderr' mwd exe args
case rv of
@@ -482,9 +483,9 @@ runCabalInstall (PackageDbDir db) (CabalSourceDir srcdir) ever = do
withGHCProgramOptions :: Env => [String]
withGHCProgramOptions =
- concat [ [ "--with-ghc=" ++ oGhcProgram ]
- , if oGhcProgram /= ghcPkgProgram defaultPrograms
- then [ "--with-ghc-pkg=" ++ oGhcPkgProgram ]
+ concat [ [ "--with-ghc=" ++ ghcProgram ?cprogs ]
+ , if ghcProgram ?cprogs /= ghcPkgProgram defaultCompPrograms
+ then [ "--with-ghc-pkg=" ++ ghcPkgProgram ?cprogs ]
else []
]
@@ -533,7 +534,7 @@ compileSetupHs db srcdir = do
file = srcdir </> "Setup"
- callProcessStderr (Just srcdir) oGhcProgram $ concat
+ callProcessStderr (Just srcdir) (ghcProgram ?cprogs) $ concat
[ [ "--make"
, "-package-conf", db
]
@@ -691,7 +692,7 @@ listCabalVersions' mdb = do
args = ["list", "--simple-output", "Cabal"] ++ maybeToList mdbopt
catMaybes . map (fmap snd . parsePkgId . fromString) . words
- <$> readProcess' oGhcPkgProgram args ""
+ <$> readProcess' (ghcProgram ?cprogs) args ""
cabalVersionExistsInPkgDb :: Env => Version -> PackageDbDir -> IO Bool
cabalVersionExistsInPkgDb cabalVer db@(PackageDbDir db_path) = do
@@ -702,14 +703,14 @@ cabalVersionExistsInPkgDb cabalVer db@(PackageDbDir db_path) = do
vers <- listCabalVersions' (Just db)
return $ cabalVer `elem` vers)
-ghcVersion :: Env => IO Version
+ghcVersion :: (Verbose, CProgs) => IO Version
ghcVersion = do
- parseVer . trim <$> readProcess' oGhcProgram ["--numeric-version"] ""
+ parseVer . trim <$> readProcess' (ghcProgram ?cprogs) ["--numeric-version"] ""
-ghcPkgVersion :: Env => IO Version
+ghcPkgVersion :: (Verbose, CProgs) => IO Version
ghcPkgVersion =
parseVer . trim . dropWhile (not . isDigit)
- <$> readProcess' oGhcPkgProgram ["--version"] ""
+ <$> readProcess' (ghcPkgProgram ?cprogs) ["--version"] ""
newtype CabalInstallVersion = CabalInstallVersion { cabalInstallVer :: Version }
cabalInstallVersion :: Env => IO CabalInstallVersion
@@ -717,15 +718,15 @@ cabalInstallVersion = do
CabalInstallVersion . parseVer . trim
<$> readProcess' oCabalProgram ["--numeric-version"] ""
-createPkgDb :: Env => CabalVersion -> IO PackageDbDir
+createPkgDb :: (Verbose, CProgs) => CabalVersion -> IO PackageDbDir
createPkgDb cabalVer = do
db@(PackageDbDir db_path) <- getPrivateCabalPkgDb cabalVer
exists <- doesDirectoryExist db_path
when (not exists) $
- callProcessStderr Nothing oGhcPkgProgram ["init", db_path]
+ callProcessStderr Nothing (ghcPkgProgram ?cprogs) ["init", db_path]
return db
-getPrivateCabalPkgDb :: Env => CabalVersion -> IO PackageDbDir
+getPrivateCabalPkgDb :: (Verbose, CProgs) => CabalVersion -> IO PackageDbDir
getPrivateCabalPkgDb cabalVer = do
appdir <- appCacheDir
ghcVer <- ghcVersion
diff --git a/src/CabalHelper/Compiletime/Program/Stack.hs b/src/CabalHelper/Compiletime/Program/Stack.hs
index e7f280d..322ccaf 100644
--- a/src/CabalHelper/Compiletime/Program/Stack.hs
+++ b/src/CabalHelper/Compiletime/Program/Stack.hs
@@ -20,7 +20,7 @@ Description : Stack program interface
License : GPL-3
-}
-{-# LANGUAGE GADTs, DataKinds #-}
+{-# LANGUAGE NamedFieldPuns, GADTs, DataKinds #-}
module CabalHelper.Compiletime.Program.Stack where
@@ -64,6 +64,7 @@ projPaths qe@QueryEnv {qeProjLoc=ProjLocStackDir projdir} = do
{ sppGlobalPkgDb = PackageDbDir $ look "global-pkg-db:"
, sppSnapPkgDb = PackageDbDir $ look "snapshot-pkg-db:"
, sppLocalPkgDb = PackageDbDir $ look "local-pkg-db:"
+ , sppCompExe = look "compiler-exe:"
}
paths :: QueryEnvI c 'Stack
@@ -85,3 +86,7 @@ listPackageCabalFiles qe@QueryEnv{qeProjLoc=ProjLocStackDir projdir} = do
workdirArg :: QueryEnvI c 'Stack -> [String]
workdirArg QueryEnv{qeDistDir=DistDirStack mworkdir} =
maybeToList $ ("--work-dir="++) . unRelativePath <$> mworkdir
+
+patchCompPrograms :: StackProjPaths -> CompPrograms -> CompPrograms
+patchCompPrograms StackProjPaths{sppCompExe} cprogs =
+ cprogs { ghcProgram = sppCompExe }
diff --git a/src/CabalHelper/Compiletime/Types.hs b/src/CabalHelper/Compiletime/Types.hs
index cc8561f..5ae712a 100644
--- a/src/CabalHelper/Compiletime/Types.hs
+++ b/src/CabalHelper/Compiletime/Types.hs
@@ -101,7 +101,10 @@ data QueryEnvI cache (proj_type :: ProjType) = QueryEnv
-- processes. Useful if you need to, for example, redirect standard error
-- output away from the user\'s terminal.
- , qePrograms :: Programs
+ , qePrograms :: !Programs
+ -- ^ Field accessor for 'QueryEnv'.
+
+ , qeCompPrograms :: !CompPrograms
-- ^ Field accessor for 'QueryEnv'.
, qeProjLoc :: !(ProjLoc proj_type)
@@ -232,15 +235,16 @@ data StackProjPaths = StackProjPaths
{ sppGlobalPkgDb :: !PackageDbDir
, sppSnapPkgDb :: !PackageDbDir
, sppLocalPkgDb :: !PackageDbDir
+ , sppCompExe :: !FilePath
}
+
+-- Beware: GHC 8.0.2 doesn't like these being recursively defined for some
+-- reason so just keep them unrolled.
type Verbose = (?verbose :: Bool)
-type Progs = (?progs :: Programs)
--- TODO: rname to `CompEnv` or something
-type Env =
- ( ?verbose :: Bool
- , ?progs :: Programs
- )
+type Env = (?cprogs :: CompPrograms, ?progs :: Programs, ?verbose :: Bool)
+type Progs = (?cprogs :: CompPrograms, ?progs :: Programs)
+type CProgs = (?cprogs :: CompPrograms)
-- | Configurable paths to various programs we use.
data Programs = Programs {
@@ -248,21 +252,25 @@ data Programs = Programs {
cabalProgram :: FilePath,
-- | The path to the @stack@ program.
- stackProgram :: FilePath,
+ stackProgram :: FilePath
+ } deriving (Eq, Ord, Show, Read, Generic, Typeable)
- -- | The path to the @ghc@ program.
- ghcProgram :: FilePath,
+data CompPrograms = CompPrograms
+ { ghcProgram :: FilePath
+ -- ^ The path to the @ghc@ program.
- -- | The path to the @ghc-pkg@ program. If
- -- not changed it will be derived from the path to 'ghcProgram'.
- ghcPkgProgram :: FilePath
+ , ghcPkgProgram :: FilePath
+ -- ^ The path to the @ghc-pkg@ program. If not changed it will be derived
+ -- from the path to 'ghcProgram'.
} deriving (Eq, Ord, Show, Read, Generic, Typeable)
-- | By default all programs use their unqualified names, i.e. they will be
-- searched for on @PATH@.
defaultPrograms :: Programs
-defaultPrograms = Programs "cabal" "stack" "ghc" "ghc-pkg"
+defaultPrograms = Programs "cabal" "stack"
+defaultCompPrograms :: CompPrograms
+defaultCompPrograms = CompPrograms "ghc" "ghc-pkg"
data CompileOptions = CompileOptions
{ oVerbose :: Bool
@@ -274,12 +282,6 @@ data CompileOptions = CompileOptions
oCabalProgram :: Env => FilePath
oCabalProgram = cabalProgram ?progs
-oGhcProgram :: Env => FilePath
-oGhcProgram = ghcProgram ?progs
-
-oGhcPkgProgram :: Env => FilePath
-oGhcPkgProgram = ghcPkgProgram ?progs
-
defaultCompileOptions :: CompileOptions
defaultCompileOptions =
CompileOptions False Nothing Nothing defaultPrograms
diff --git a/tests/CompileTest.hs b/tests/CompileTest.hs
index ef43734..26ec0e3 100644
--- a/tests/CompileTest.hs
+++ b/tests/CompileTest.hs
@@ -45,6 +45,7 @@ setupHOME = do
main :: IO ()
main = do
let ?progs = defaultPrograms
+ let ?cprogs = defaultCompPrograms
let ?opts = defaultCompileOptions { oVerbose = True }
let ?verbose = True