diff --git a/ChangeLog.md b/ChangeLog.md index 9644700f3f..e1f13fde4e 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -19,6 +19,10 @@ Other enhancements: Bug fixes: +* `stack ghci` now does not invalidate `.o` files on repeated runs, + meaning any modules compiled with `-fobject-code` will be cached + between ghci runs. See + [#4038](https://github.com/commercialhaskell/stack/pull/4038). * `~/.stack/config.yaml` and `stack.yaml` terminating by newline * The previous released caused a regression where some `stderr` from the `ghc-pkg` command showed up in the terminal. This output is now silenced. diff --git a/src/Stack/Constants/Config.hs b/src/Stack/Constants/Config.hs index 1fb525daa6..74cec0ef05 100644 --- a/src/Stack/Constants/Config.hs +++ b/src/Stack/Constants/Config.hs @@ -15,6 +15,7 @@ module Stack.Constants.Config , hpcRelativeDir , hpcDirFromDir , objectInterfaceDirL + , ghciDirL , templatesDir ) where @@ -32,11 +33,18 @@ objectInterfaceDirL = to $ \env -> -- FIXME is this idomatic lens code? root = view projectRootL env in root workDir $(mkRelDir "odir/") +-- | GHCi files directory. +ghciDirL :: HasBuildConfig env => Getting r env (Path Abs Dir) +ghciDirL = to $ \env -> -- FIXME is this idomatic lens code? + let workDir = view workDirL env + root = view projectRootL env + in root workDir $(mkRelDir "ghci/") + -- | The directory containing the files used for dirtiness check of source files. buildCachesDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => Path Abs Dir -- ^ Package directory. -> m (Path Abs Dir) -buildCachesDir dir = +buildCachesDir dir = liftM ( $(mkRelDir "stack-build-caches")) (distDirFromDir dir) diff --git a/src/Stack/Ghci.hs b/src/Stack/Ghci.hs index bf98d7782b..4a39966646 100644 --- a/src/Stack/Ghci.hs +++ b/src/Stack/Ghci.hs @@ -398,8 +398,10 @@ runGhci GhciOpts{..} targets mainIsTargets pkgs extraFiles exposePackages = do tmpDirectory <- ( $(mkRelDir "haskell-stack-ghci")) <$> (parseAbsDir =<< liftIO getCanonicalTemporaryDirectory) + ghciDir <- view ghciDirL + ensureDir ghciDir ensureDir tmpDirectory - macrosOptions <- writeMacrosFile tmpDirectory pkgs + macrosOptions <- writeMacrosFile ghciDir pkgs if ghciNoLoadModules then execGhci macrosOptions else do @@ -411,7 +413,7 @@ runGhci GhciOpts{..} targets mainIsTargets pkgs extraFiles exposePackages = do execGhci (macrosOptions ++ scriptOptions) writeMacrosFile :: HasRunner env => Path Abs Dir -> [GhciPkgInfo] -> RIO env [String] -writeMacrosFile tmpDirectory pkgs = do +writeMacrosFile outputDirectory pkgs = do fps <- fmap (nubOrd . catMaybes . concat) $ forM pkgs $ \pkg -> forM (ghciPkgOpts pkg) $ \(_, bio) -> do let cabalMacros = bioCabalMacros bio @@ -423,22 +425,22 @@ writeMacrosFile tmpDirectory pkgs = do return Nothing files <- liftIO $ mapM (S8.readFile . toFilePath) fps if null files then return [] else do - out <- liftIO $ writeHashedFile tmpDirectory $(mkRelFile "cabal_macros.h") $ + out <- liftIO $ writeHashedFile outputDirectory $(mkRelFile "cabal_macros.h") $ S8.concat $ map (<> "\n#undef CURRENT_PACKAGE_KEY\n#undef CURRENT_COMPONENT_ID\n") files return ["-optP-include", "-optP" <> toFilePath out] writeGhciScript :: (MonadIO m) => Path Abs Dir -> GhciScript -> m [String] -writeGhciScript tmpDirectory script = do - scriptPath <- liftIO $ writeHashedFile tmpDirectory $(mkRelFile "ghci-script") $ +writeGhciScript outputDirectory script = do + scriptPath <- liftIO $ writeHashedFile outputDirectory $(mkRelFile "ghci-script") $ LBS.toStrict $ scriptToLazyByteString script let scriptFilePath = toFilePath scriptPath setScriptPerms scriptFilePath return ["-ghci-script=" <> scriptFilePath] writeHashedFile :: Path Abs Dir -> Path Rel File -> ByteString -> IO (Path Abs File) -writeHashedFile tmpDirectory relFile contents = do +writeHashedFile outputDirectory relFile contents = do relSha <- shaPathForBytes contents - let outDir = tmpDirectory relSha + let outDir = outputDirectory relSha outFile = outDir relFile alreadyExists <- doesFileExist outFile unless alreadyExists $ do