@@ -58,6 +58,7 @@ import GHC.Types.Error (errMsgDiagnostic,
5858 singleMessage )
5959import GHC.Unit.State
6060
61+
6162#if MIN_VERSION_ghc(9,13,0)
6263import GHC.Driver.Make (checkHomeUnitsClosed )
6364#endif
@@ -80,6 +81,11 @@ instance Pretty Log where
8081 LogDLLLoadError errorString ->
8182 " Error dynamically loading libm.so.6:" <+> pretty errorString
8283
84+ data HomeUnitConfig = HomeUnitConfig
85+ { homeUnitDynFlags :: DynFlags
86+ , homeUnitTargets :: [GHC. Target ]
87+ , homeUnitHash :: Maybe B. ByteString
88+ }
8389-- This is pristine information about a component
8490data RawComponentInfo = RawComponentInfo
8591 { rawComponentUnitId :: UnitId
@@ -95,6 +101,8 @@ data RawComponentInfo = RawComponentInfo
95101 -- | Maps cradle dependencies, such as `stack.yaml`, or `.cabal` file
96102 -- to last modification time. See Note [Multi Cradle Dependency Info].
97103 , rawComponentDependencyInfo :: DependencyInfo
104+ -- | the
105+ , rawComponentHash :: Maybe B. ByteString
98106 }
99107
100108-- This is processed information about the component, in particular the dynflags will be modified.
@@ -209,13 +217,13 @@ setOptions :: GhcMonad m
209217 -> ComponentOptions
210218 -> DynFlags
211219 -> FilePath -- ^ root dir, see Note [Root Directory]
212- -> m (NonEmpty ( DynFlags , [ GHC. Target ]) )
220+ -> m (NonEmpty HomeUnitConfig )
213221setOptions haddockOpt cfp (ComponentOptions theOpts compRoot _) dflags rootDir = do
214222 ((theOpts',_errs,_warns),units) <- processCmdLineP unit_flags [] (map noLoc theOpts)
215223 case NE. nonEmpty units of
216224 Just us -> initMulti us
217225 Nothing -> do
218- (df, targets) <- initOne (map unLoc theOpts')
226+ (HomeUnitConfig df targets mHash ) <- initOne (map unLoc theOpts')
219227 -- A special target for the file which caused this wonderful
220228 -- component to be created. In case the cradle doesn't list all the targets for
221229 -- the component, in which case things will be horribly broken anyway.
@@ -235,7 +243,7 @@ setOptions haddockOpt cfp (ComponentOptions theOpts compRoot _) dflags rootDir =
235243 -- we will report it as an error for that file
236244 let abs_fp = toAbsolute rootDir (fromNormalizedFilePath cfp)
237245 let special_target = Compat. mkSimpleTarget df abs_fp
238- pure $ (df, special_target : targets) :| []
246+ pure $ HomeUnitConfig df ( special_target : targets) mHash :| []
239247 where
240248 initMulti unitArgFiles =
241249 forM unitArgFiles $ \ f -> do
@@ -246,7 +254,7 @@ setOptions haddockOpt cfp (ComponentOptions theOpts compRoot _) dflags rootDir =
246254 initOne $ HieBios. removeRTS $ HieBios. removeVerbosityOpts args
247255 initOne this_opts = do
248256 (dflags', targets') <- addCmdOpts this_opts dflags
249- let dflags'' =
257+ let ( dflags'',mHash) =
250258 case unitIdString (homeUnitId_ dflags') of
251259 -- cabal uses main for the unit id of all executable packages
252260 -- This makes multi-component sessions confused about what
@@ -255,10 +263,11 @@ setOptions haddockOpt cfp (ComponentOptions theOpts compRoot _) dflags rootDir =
255263 -- This works because there won't be any dependencies on the
256264 -- executable unit.
257265 " main" ->
258- let hash = B. unpack $ B16. encode $ H. finalize $ H. updates H. init (map B. pack this_opts)
266+ let hashBytes = H. finalize $ H. updates H. init (map B. pack this_opts)
267+ hash = B. unpack $ B16. encode hashBytes
259268 hashed_uid = Compat. toUnitId (Compat. stringToUnit (" main-" ++ hash))
260- in setHomeUnitId_ hashed_uid dflags'
261- _ -> dflags'
269+ in ( setHomeUnitId_ hashed_uid dflags', Just hashBytes)
270+ _ -> ( dflags', Nothing )
262271
263272 let targets = makeTargetsAbsolute root targets'
264273 root = case workingDirectory dflags'' of
@@ -279,14 +288,14 @@ setOptions haddockOpt cfp (ComponentOptions theOpts compRoot _) dflags rootDir =
279288 Compat. setUpTypedHoles $
280289 makeDynFlagsAbsolute compRoot -- makeDynFlagsAbsolute already accounts for workingDirectory
281290 dflags''
282- return (dflags''', targets)
291+ return (HomeUnitConfig dflags''' targets mHash )
283292
284293addComponentInfo ::
285294 MonadUnliftIO m =>
286295 Recorder (WithPriority Log ) ->
287- (String -> [String ] -> IO CacheDirs ) ->
296+ (String -> Maybe B. ByteString -> [String ] -> IO CacheDirs ) ->
288297 DependencyInfo ->
289- NonEmpty ( DynFlags , [ GHC. Target ]) ->
298+ NonEmpty HomeUnitConfig ->
290299 (Maybe FilePath , NormalizedFilePath , ComponentOptions ) ->
291300 Map. Map (Maybe FilePath ) [RawComponentInfo ] ->
292301 m (Map. Map (Maybe FilePath ) [RawComponentInfo ], ([ComponentInfo ], [ComponentInfo ]))
@@ -298,15 +307,15 @@ addComponentInfo recorder getCacheDirs dep_info newDynFlags (hieYaml, cfp, opts)
298307 -- We will modify the unitId and DynFlags used for
299308 -- compilation but these are the true source of
300309 -- information.
301- new_deps = fmap (\ (df, targets) -> RawComponentInfo (homeUnitId_ df) df targets cfp opts dep_info) newDynFlags
310+ new_deps = fmap (\ (HomeUnitConfig df targets mHash ) -> RawComponentInfo (homeUnitId_ df) df targets cfp opts dep_info mHash ) newDynFlags
302311 all_deps = new_deps `NE.appendList` fromMaybe [] oldDeps
303312 -- Get all the unit-ids for things in this component
304313
305314 all_deps' <- forM all_deps $ \ RawComponentInfo {.. } -> do
306315 let prefix = show rawComponentUnitId
307316 -- See Note [Avoiding bad interface files]
308317 let cacheDirOpts = componentOptions opts
309- cacheDirs <- liftIO $ getCacheDirs prefix cacheDirOpts
318+ cacheDirs <- liftIO $ getCacheDirs prefix rawComponentHash cacheDirOpts
310319 processed_df <- setCacheDirs recorder cacheDirs rawComponentDynFlags
311320 -- The final component information, mostly the same but the DynFlags don't
312321 -- contain any packages which are also loaded
@@ -422,14 +431,18 @@ setCacheDirs recorder CacheDirs{..} dflags = do
422431 & maybe id setHieDir hieCacheDir
423432 & maybe id setODir oCacheDir
424433
425- getCacheDirsDefault :: String -> [String ] -> IO CacheDirs
426- getCacheDirsDefault prefix opts = do
427- dir <- Just <$> getXdgDirectory XdgCache (cacheDir </> prefix ++ " -" ++ opts_hash)
434+ getCacheDirsDefault :: String -> Maybe B. ByteString -> [String ] -> IO CacheDirs
435+ getCacheDirsDefault prefix mFirstHash opts = do
436+ dir <- Just <$> getXdgDirectory XdgCache (cacheDir </> prefix' ++ " -" ++ opts_hash)
428437 return $ CacheDirs dir dir dir
429438 where
430439 -- Create a unique folder per set of different GHC options, assuming that each different set of
431440 -- GHC options will create incompatible interface files.
432- opts_hash = B. unpack $ B16. encode $ H. finalize $ H. updates H. init (map B. pack opts)
441+ prefix' = if isJust mFirstHash then " main" else prefix
442+ basectx = case mFirstHash of
443+ Just h -> H. updates H. init [h]
444+ Nothing -> H. init
445+ opts_hash = B. unpack $ B16. encode $ H. finalize $ H. updates basectx (map B. pack opts)
433446
434447setNameCache :: NameCache -> HscEnv -> HscEnv
435448setNameCache nc hsc = hsc { hsc_NC = nc }
0 commit comments