aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Distribution/Helper.hs24
-rw-r--r--src/CabalHelper/Runtime/Main.hs85
-rw-r--r--src/CabalHelper/Shared/InterfaceTypes.hs18
-rw-r--r--tests/GhcSession.hs53
4 files changed, 121 insertions, 59 deletions
diff --git a/lib/Distribution/Helper.hs b/lib/Distribution/Helper.hs
index bef95ba..f98955c 100644
--- a/lib/Distribution/Helper.hs
+++ b/lib/Distribution/Helper.hs
@@ -56,6 +56,7 @@ module Distribution.Helper (
, ghcOptions
, sourceDirs
, entrypoints
+ , needsBuildOutput
-- * Query environment
, QueryEnv
@@ -206,7 +207,8 @@ data SomeLocalBuildInfo = SomeLocalBuildInfo {
slbiGhcOptions :: [(ChComponentName, [String])],
slbiSourceDirs :: [(ChComponentName, [String])],
- slbiEntrypoints :: [(ChComponentName, ChEntrypoint)]
+ slbiEntrypoints :: [(ChComponentName, ChEntrypoint)],
+ slbiNeedsBuildOutput :: [(ChComponentName, NeedsBuildOutput)]
} deriving (Eq, Ord, Read, Show)
-- | A lazy, cached, query against a package's Cabal configuration. Use
@@ -295,6 +297,9 @@ components (ComponentQuery sc) = map (\(cn, f) -> f cn) `liftM` sc
-- to compute the home module closure for a component.
entrypoints :: MonadIO m => ComponentQuery m ChEntrypoint
+-- | The component has a non-default module renaming, so needs build output ().
+needsBuildOutput :: MonadIO m => ComponentQuery m NeedsBuildOutput
+
-- | A component's @source-dirs@ field, beware since if this is empty implicit
-- behaviour in GHC kicks in.
sourceDirs :: MonadIO m => ComponentQuery m [FilePath]
@@ -321,12 +326,13 @@ ghcMergedPkgOptions = Query $ slbiGhcMergedPkgOptions `liftM` getSlbi
configFlags = Query $ slbiConfigFlags `liftM` getSlbi
nonDefaultConfigFlags = Query $ slbiNonDefaultConfigFlags `liftM` getSlbi
-ghcSrcOptions = ComponentQuery $ Query $ slbiGhcSrcOptions `liftM` getSlbi
-ghcPkgOptions = ComponentQuery $ Query $ slbiGhcPkgOptions `liftM` getSlbi
-ghcOptions = ComponentQuery $ Query $ slbiGhcOptions `liftM` getSlbi
-ghcLangOptions = ComponentQuery $ Query $ slbiGhcLangOptions `liftM` getSlbi
-sourceDirs = ComponentQuery $ Query $ slbiSourceDirs `liftM` getSlbi
-entrypoints = ComponentQuery $ Query $ slbiEntrypoints `liftM` getSlbi
+ghcSrcOptions = ComponentQuery $ Query $ slbiGhcSrcOptions `liftM` getSlbi
+ghcPkgOptions = ComponentQuery $ Query $ slbiGhcPkgOptions `liftM` getSlbi
+ghcOptions = ComponentQuery $ Query $ slbiGhcOptions `liftM` getSlbi
+ghcLangOptions = ComponentQuery $ Query $ slbiGhcLangOptions `liftM` getSlbi
+sourceDirs = ComponentQuery $ Query $ slbiSourceDirs `liftM` getSlbi
+entrypoints = ComponentQuery $ Query $ slbiEntrypoints `liftM` getSlbi
+needsBuildOutput = ComponentQuery $ Query $ slbiNeedsBuildOutput `liftM` getSlbi
-- | Run @cabal configure@
reconfigure :: MonadIO m
@@ -398,6 +404,7 @@ getSomeConfigState = ask >>= \QueryEnv {..} -> do
, "source-dirs"
, "entrypoints"
+ , "needsbuildoutput"
]
let [ Just (ChResponsePkgDbs slbiPackageDbStack),
Just (ChResponseFlags slbiPackageFlags),
@@ -415,7 +422,8 @@ getSomeConfigState = ask >>= \QueryEnv {..} -> do
Just (ChResponseCompList slbiGhcOptions),
Just (ChResponseCompList slbiSourceDirs),
- Just (ChResponseEntrypoints slbiEntrypoints)
+ Just (ChResponseEntrypoints slbiEntrypoints),
+ Just (ChResponseNeedsBuild slbiNeedsBuildOutput)
] = res
slbiCompilerVersion = (comp, compVer)
return $ SomeLocalBuildInfo {..}
diff --git a/src/CabalHelper/Runtime/Main.hs b/src/CabalHelper/Runtime/Main.hs
index 737b590..0173fe9 100644
--- a/src/CabalHelper/Runtime/Main.hs
+++ b/src/CabalHelper/Runtime/Main.hs
@@ -70,6 +70,8 @@ import Distribution.Simple.LocalBuildInfo
, withComponentsLBI
, withLibLBI
, withExeLBI
+ , allLibModules
+ , componentBuildDir
)
import Distribution.Simple.GHC
( componentGhcOptions
@@ -149,15 +151,22 @@ import Distribution.Types.UnqualComponentName
#if CH_MIN_VERSION_Cabal(2,0,0)
-- CPP >= 2.0
-import Distribution.Backpack (OpenUnitId(..))
+import Distribution.Backpack
+ ( OpenUnitId(..),
+ OpenModule(..)
+ )
import Distribution.ModuleName
( ModuleName
)
import Distribution.Types.ComponentId
( unComponentId
)
+import Distribution.Types.ComponentLocalBuildInfo
+ ( maybeComponentInstantiatedWith
+ )
import Distribution.Types.ModuleRenaming
- ( ModuleRenaming(..)
+ ( ModuleRenaming(..),
+ isDefaultRenaming
)
import Distribution.Types.MungedPackageId
( MungedPackageId
@@ -226,6 +235,7 @@ usage = do
++" | ghc-lang-options [--with-inplace]\n"
++" | package-db-stack\n"
++" | entrypoints\n"
+ ++" | needsbuildoutput\n"
++" | source-dirs\n"
++" | licenses\n"
++" ) ...\n"
@@ -244,6 +254,7 @@ commands = [ "print-lbi"
, "ghc-lang-options"
, "package-db-stack"
, "entrypoints"
+ , "needsbuildoutput"
, "source-dirs"
, "licenses"]
@@ -324,6 +335,7 @@ main = do
"ghc-options":flags -> do
res <- componentOptions lvd True flags id
+ -- putStrLn $ "\n*************ghc-options:" ++ show res
return $ Just $ ChResponseCompList (res ++ [(ChSetupHsName, [])])
"ghc-src-options":flags -> do
@@ -383,14 +395,9 @@ main = do
"entrypoints":[] -> do
#if CH_MIN_VERSION_Cabal(2,0,0)
includeDirMap <- recursiveDepInfo lbi v distdir
- appendFile "/tmp/cbli.txt" "\n--------------------------------------"
eps <- componentsMap lbi v distdir $ \c clbi _bi -> do
- appendFile "/tmp/cbli.txt" ("\n" ++ show clbi)
let (_,_,seps) = recursiveIncludeDirs includeDirMap (componentUnitId clbi)
- appendFile "/tmp/cbli.txt" ("\n" ++ show (componentEntrypoints c) )
- appendFile "/tmp/cbli.txt" "\n-------"
return seps
- appendFile "/tmp/cbli.txt" "\n--------------------------------------"
#else
eps <- componentsMap lbi v distdir $ \c _clbi _bi ->
return $ componentEntrypoints c
@@ -400,6 +407,17 @@ main = do
let eps' = eps ++ [(ChSetupHsName, ChSetupEntrypoint)]
return $ Just $ ChResponseEntrypoints eps'
+ "needsbuildoutput":[] -> do
+#if CH_MIN_VERSION_Cabal(2,0,0)
+ includeDirMap <- recursiveDepInfo lbi v distdir
+ nbs <- componentsMap lbi v distdir $ \c clbi _bi ->
+ return $ needsBuildOutput includeDirMap (componentUnitId clbi)
+#else
+ nbs <- componentsMap lbi v distdir $ \c _clbi _bi ->
+ return $ NoBuildOutput
+#endif
+ return $ Just $ ChResponseNeedsBuild nbs
+
"source-dirs":[] -> do
res <- componentsMap lbi v distdir $$ \_ _ bi -> return $ hsSourceDirs bi
return $ Just $ ChResponseCompList (res ++ [(ChSetupHsName, [])])
@@ -471,9 +489,9 @@ componentsMap lbi _v _distdir f = do
l' <- readIORef lr
r <- f c clbi bi
#if CH_MIN_VERSION_Cabal(2,0,0)
- writeIORef lr $ (componentNameToCh (ChUnitId $ unUnitId $ componentUnitId clbi) name, r):l'
+ writeIORef lr $ (componentNameToCh (unUnitId $ componentUnitId clbi) name, r):l'
#else
- writeIORef lr $ (componentNameToCh ChNoUnitId name, r):l'
+ writeIORef lr $ (componentNameToCh "" name, r):l'
#endif
reverse <$> readIORef lr
@@ -482,11 +500,13 @@ componentOptions' (lbi, v, distdir) inplaceFlag flags rf f = do
let pd = localPkgDescr lbi
#if CH_MIN_VERSION_Cabal(2,0,0)
includeDirMap <- recursiveDepInfo lbi v distdir
+ -- putStrLn $ "\nincludeDirMap=" ++ show includeDirMap ++ "\n"
#endif
componentsMap lbi v distdir $ \c clbi bi ->
let
- outdir = componentOutDir lbi c
+ -- outdir = componentOutDir lbi c
+ outdir = componentBuildDir lbi clbi
(clbi', adopts) = case flags of
_ | not inplaceFlag -> (clbi, mempty)
["--with-inplace"] -> (clbi, mempty)
@@ -524,6 +544,8 @@ removeInplaceDeps _v lbi pd clbi includeDirs = let
, componentIncludes = incs }
in (hasIdeps',c')
+ cleanRecursiveOpts :: Component
+ -> BuildInfo -> ComponentLocalBuildInfo -> GhcOptions
cleanRecursiveOpts comp libbi libclbi =
let
-- libbi = libBuildInfo lib
@@ -534,6 +556,7 @@ removeInplaceDeps _v lbi pd clbi includeDirs = let
opts = (componentGhcOptions normal lbi libbi libclbi' liboutdir) {
ghcOptPackageDBs = []
}
+
in
opts { ghcOptSourcePath = ghcOptSourcePath opts <> toNubListR extraIncludes
, ghcOptPackages = ghcOptPackages opts <> toNubListR extraDeps }
@@ -544,8 +567,10 @@ removeInplaceDeps _v lbi pd clbi includeDirs = let
(Just (lib, libclbi),_) | hasIdeps ->
let
libbi = libBuildInfo lib
+ opts = cleanRecursiveOpts (CLib lib) libbi libclbi
in
- cleanRecursiveOpts (CLib lib) libbi libclbi
+ -- ghcOptInputModules = toNubListR $ allLibModules lib clbi,
+ opts { ghcOptInputModules = ghcOptInputModules opts <> (toNubListR $ allLibModules lib libclbi) }
(_,Just (exe,execlbi)) | hasIdeps ->
let
exebi = buildInfo exe
@@ -588,7 +613,7 @@ recursiveDepInfo lbi v distdir = do
, componentEntrypoints c))
return $ Map.fromList $ map snd includeDirs
-type SubDeps = ([UnitId],[FilePath], [(OpenUnitId, ModuleRenaming)], ChEntrypoint)
+type SubDeps = ([UnitId], [FilePath], [(OpenUnitId, ModuleRenaming)], ChEntrypoint)
recursiveIncludeDirs :: Map.Map UnitId SubDeps
-> UnitId -> ([FilePath], [(OpenUnitId, ModuleRenaming)]
@@ -600,12 +625,30 @@ recursiveIncludeDirs includeDirs unit = go ([],[],Nothing) [unit]
Nothing -> go acc us
Just (us',sfp,sci,sep) -> go (afp++sfp,aci++sci,combineEp amep sep) (us++us')
+needsBuildOutput :: Map.Map UnitId SubDeps
+ -> UnitId -> NeedsBuildOutput
+needsBuildOutput includeDirs unit = go [unit]
+ where
+ isIndef (IndefFullUnitId _ _) = True
+ isIndef _ = False
+ go [] = NoBuildOutput
+ go (u:us) = case Map.lookup u includeDirs of
+ Nothing -> go us
+ Just (us',sfp,sci,sep) ->
+ if any (isIndef . fst) sci
+ then ProduceBuildOutput
+ else go (us++us')
+
combineEp Nothing e = Just e
combineEp (Just ChSetupEntrypoint) e = Just e
combineEp (Just (ChLibEntrypoint es1 os1 ss1)) (ChLibEntrypoint es2 os2 ss2) = Just (ChLibEntrypoint (nub $ es2++es1) (nub $ os2++os1) (nub $ ss2++ss1))
combineEp (Just (ChLibEntrypoint es1 os1 ss1)) (ChExeEntrypoint mi os2) = Just (ChExeEntrypoint mi (nub $ os2++es1++os1++ss1))
combineEp (Just (ChExeEntrypoint _ os1)) (ChLibEntrypoint es2 os2 ss2) = Just (ChLibEntrypoint es2 (nub $ os2++os1) ss2)
combineEp (Just (ChExeEntrypoint _ os1)) (ChExeEntrypoint mi os2) = Just (ChExeEntrypoint mi (nub $ os2++os1))
+
+instantiatedGhcPackage :: (ModuleName,OpenModule) -> [(OpenUnitId, ModuleRenaming)]
+instantiatedGhcPackage (_,OpenModule oui@(DefiniteUnitId _) _) = [(oui,DefaultRenaming)]
+instantiatedGhcPackage (_, _) = []
#endif
initialBuildStepsForAllComponents distdir pd lbi v =
@@ -635,12 +678,16 @@ toDataVersion = id
componentNameToCh _uid CLibName = ChLibName
#if CH_MIN_VERSION_Cabal(1,25,0)
-- CPP >= 1.25
-componentNameToCh uid (CSubLibName n) = ChSubLibName (unUnqualComponentName' n) uid
-componentNameToCh uid (CFLibName n) = ChFLibName (unUnqualComponentName' n) uid
+#if CH_MIN_VERSION_Cabal(2,0,0)
+componentNameToCh uid (CSubLibName n) = ChSubLibName uid
+#else
+componentNameToCh _uid (CSubLibName n) = ChSubLibName (unUnqualComponentName' n)
+#endif
+componentNameToCh uid (CFLibName n) = ChFLibName (unUnqualComponentName' n)
#endif
-componentNameToCh uid (CExeName n) = ChExeName (unUnqualComponentName' n) uid
-componentNameToCh uid (CTestName n) = ChTestName (unUnqualComponentName' n) uid
-componentNameToCh uid (CBenchName n) = ChBenchName (unUnqualComponentName' n) uid
+componentNameToCh _uid (CExeName n) = ChExeName (unUnqualComponentName' n)
+componentNameToCh _uid (CTestName n) = ChTestName (unUnqualComponentName' n)
+componentNameToCh _uid (CBenchName n) = ChBenchName (unUnqualComponentName' n)
#if CH_MIN_VERSION_Cabal(1,25,0)
-- CPP >= 1.25
@@ -717,8 +764,8 @@ componentEntrypoints (CBench Benchmark {})
#if CH_MIN_VERSION_Cabal(2,0,0)
isInplaceCompInc :: ComponentLocalBuildInfo -> (OpenUnitId, ModuleRenaming) -> Bool
isInplaceCompInc clbi (DefiniteUnitId uid, _mr) = unDefUnitId uid `elem` componentInternalDeps clbi
--- isInplaceCompInc clbi (IndefFullUnitId uid _, _mmr) = False
-isInplaceCompInc clbi (IndefFullUnitId uid _, _mmr) = unComponentId uid `elem` map unUnitId (componentInternalDeps clbi)
+isInplaceCompInc clbi (IndefFullUnitId uid _, _mmr) = False
+-- isInplaceCompInc clbi (IndefFullUnitId uid _, _mmr) = unComponentId uid `elem` map unUnitId (componentInternalDeps clbi)
#endif
#if CH_MIN_VERSION_Cabal(2,0,0)
diff --git a/src/CabalHelper/Shared/InterfaceTypes.hs b/src/CabalHelper/Shared/InterfaceTypes.hs
index bf61bb7..2f2e6a3 100644
--- a/src/CabalHelper/Shared/InterfaceTypes.hs
+++ b/src/CabalHelper/Shared/InterfaceTypes.hs
@@ -37,6 +37,7 @@ import Data.Version
data ChResponse
= ChResponseCompList [(ChComponentName, [String])]
| ChResponseEntrypoints [(ChComponentName, ChEntrypoint)]
+ | ChResponseNeedsBuild [(ChComponentName, NeedsBuildOutput)]
| ChResponseList [String]
| ChResponsePkgDbs [ChPkgDb]
| ChResponseLbi String
@@ -47,15 +48,11 @@ data ChResponse
data ChComponentName = ChSetupHsName
| ChLibName
- | ChSubLibName String ChUnitId
- | ChFLibName String ChUnitId
- | ChExeName String ChUnitId
- | ChTestName String ChUnitId
- | ChBenchName String ChUnitId
- deriving (Eq, Ord, Read, Show, Generic)
-
-data ChUnitId = ChNoUnitId
- | ChUnitId String
+ | ChSubLibName String
+ | ChFLibName String
+ | ChExeName String
+ | ChTestName String
+ | ChBenchName String
deriving (Eq, Ord, Read, Show, Generic)
newtype ChModuleName = ChModuleName String
@@ -78,3 +75,6 @@ data ChPkgDb = ChPkgGlobal
| ChPkgUser
| ChPkgSpecific FilePath
deriving (Eq, Ord, Read, Show, Generic)
+
+data NeedsBuildOutput = ProduceBuildOutput | NoBuildOutput
+ deriving (Eq, Ord, Read, Show, Generic)
diff --git a/tests/GhcSession.hs b/tests/GhcSession.hs
index 127dd8e..e8d3977 100644
--- a/tests/GhcSession.hs
+++ b/tests/GhcSession.hs
@@ -32,12 +32,12 @@ main = do
topdir <- getCurrentDirectory
res <- mapM (setup topdir test) $ case args of
[] -> [
- -- ("tests/exelib" , parseVer "1.10")
- -- , ("tests/exeintlib", parseVer "2.0")
- -- , ("tests/fliblib" , parseVer "2.0")
- ("tests/bkpregex" , parseVer "2.0")
+ -- ("tests/exelib" , parseVer "1.10",False)
+ -- , ("tests/exeintlib", parseVer "2.0", False)
+ -- , ("tests/fliblib" , parseVer "2.0", False)
+ ("tests/bkpregex" , parseVer "2.0", True)
]
- xs -> map (,parseVer "0") xs
+ xs -> map (,parseVer "0",False) xs
if any (==False) $ concat res
then exitFailure
@@ -52,8 +52,8 @@ cabalInstallBuiltinCabalVersion =
parseVer . trim <$> readProcess "cabal"
["act-as-setup", "--", "--numeric-version"] ""
-setup :: FilePath -> (FilePath -> IO [Bool]) -> (FilePath, Version) -> IO [Bool]
-setup topdir act (srcdir, min_cabal_ver) = do
+setup :: FilePath -> (FilePath -> IO [Bool]) -> (FilePath, Version,Bool) -> IO [Bool]
+setup topdir act (srcdir, min_cabal_ver,invokeCabalBuild) = do
ci_ver <- cabalInstallVersion
c_ver <- cabalInstallBuiltinCabalVersion
let mreason
@@ -70,13 +70,19 @@ setup topdir act (srcdir, min_cabal_ver) = do
putStrLn $ "Skipping test '" ++ srcdir ++ "' because " ++ reason ++ "."
return []
Nothing -> do
- withSystemTempDirectory "cabal-helper.ghc-session.test" $ \dir -> do
+ -- withSystemTempDirectory "cabal-helper.ghc-session.test" $ \dir -> do
+ let dir = "/tmp/xxxx"
+ e <- doesDirectoryExist dir
+ when e $ removeDirectoryRecursive dir
+ createDirectoryIfMissing True dir
+ do
setCurrentDirectory $ topdir </> srcdir
run "cabal" [ "sdist", "--output-dir", dir ]
setCurrentDirectory dir
run "cabal" [ "configure" ]
--- run "cabal" [ "build" ]
+ when invokeCabalBuild $ do
+ run "cabal" [ "build" ]
act dir
where
@@ -89,21 +95,20 @@ setup topdir act (srcdir, min_cabal_ver) = do
test :: FilePath -> IO [Bool]
test dir = do
let qe = mkQueryEnv dir (dir </> "dist")
+ let packageDir = dir </> "dist" </> "package.conf.inplace"
+ cs <- runQuery qe $ components $ (,,,) <$> entrypoints <.> ghcOptions <.> needsBuildOutput
+ forM cs $ \(ep, opts, nb, cn) -> do
- cs <- runQuery qe $ components $ (,) <$> entrypoints
- putStrLn "\n--------------------------------eps-----------------------------"
- forM cs $ \(ep, cn) -> do
- putStrLn $ "\n" ++ show (ep,cn)
- putStrLn "\n--------------------------------eps end-----------------------------"
-
- cs <- runQuery qe $ components $ (,,) <$> entrypoints <.> ghcOptions
- putStrLn "\n--------------------------------components-----------------------------"
- forM cs $ \(ep, opts, cn) -> do
- putStrLn $ "\n" ++ show cn ++ ": " ++ show opts
- putStrLn "\n--------------------------------components end-------------------------"
- forM cs $ \(ep, opts, cn) -> do
- let opts' = "-Werror" : opts
- let sopts = intercalate " " $ map formatArg $ "ghc" : opts'
+ putStrLn $ "\n" ++ show cn ++ ":::: " ++ show nb
+
+ exists <- doesDirectoryExist packageDir
+ let opts' = if exists
+ then ("-package-db " ++ packageDir) : "-Werror" : opts
+ else "-Werror" : opts
+
+ -- let opts' = "-Werror" : opts
+ -- let opts' = "-v 3" : "-Werror" : opts
+ let sopts = intercalate " " $ map formatArg $ "\nghc" : opts'
putStrLn $ "\n" ++ show cn ++ ": " ++ sopts
hFlush stdout
compileModule ep opts'
@@ -115,6 +120,8 @@ test dir = do
compileModule :: ChEntrypoint -> [String] -> IO Bool
compileModule ep opts = do
+ putStrLn $ "compiling:" ++ show ep
+
E.handle (\(ec :: ExitCode) -> print ec >> return False) $ do
#if __GLASGOW_HASKELL__ <= 704