-- | Info about modules in the "home" unit. -- Stored in a 'HomePackageTable'. module GHC.Unit.Home.ModInfo ( HomeModInfo (..) , HomeModLinkable(..) , homeModInfoObject , homeModInfoByteCode , emptyHomeModInfoLinkable , justBytecode , justObjects , bytecodeAndObjects ) where import GHC.Prelude import GHC.Unit.Module.ModIface import GHC.Unit.Module.ModDetails import GHC.Linker.Types ( Linkable(..), linkableIsNativeCodeOnly ) import GHC.Utils.Outputable import GHC.Utils.Panic -- | Information about modules in the package being compiled data HomeModInfo = HomeModInfo { hm_iface :: !ModIface -- ^ The basic loaded interface file: every loaded module has one of -- these, even if it is imported from another package , hm_details :: ModDetails -- ^ Extra information that has been created from the 'ModIface' for -- the module, typically during typechecking -- This field is LAZY because a ModDetails is constructed by knot tying. , hm_linkable :: !HomeModLinkable -- ^ The actual artifact we would like to link to access things in -- this module. See Note [Home module build products] -- -- 'hm_linkable' might be empty: -- -- 1. If this is an .hs-boot module -- -- 2. Temporarily during compilation if we pruned away -- the old linkable because it was out of date. -- -- When re-linking a module ('GHC.Driver.Main.HscNoRecomp'), we construct the -- 'HomeModInfo' by building a new 'ModDetails' from the old -- 'ModIface' (only). } homeModInfoByteCode :: HomeModInfo -> Maybe Linkable homeModInfoByteCode = homeMod_bytecode . hm_linkable homeModInfoObject :: HomeModInfo -> Maybe Linkable homeModInfoObject = homeMod_object . hm_linkable emptyHomeModInfoLinkable :: HomeModLinkable emptyHomeModInfoLinkable = HomeModLinkable Nothing Nothing -- See Note [Home module build products] data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe Linkable) , homeMod_object :: !(Maybe Linkable) } instance Outputable HomeModLinkable where ppr (HomeModLinkable l1 l2) = ppr l1 $$ ppr l2 justBytecode :: Linkable -> HomeModLinkable justBytecode lm = assertPpr (not (linkableIsNativeCodeOnly lm)) (ppr lm) $ emptyHomeModInfoLinkable { homeMod_bytecode = Just lm } justObjects :: Linkable -> HomeModLinkable justObjects lm = assertPpr (linkableIsNativeCodeOnly lm) (ppr lm) $ emptyHomeModInfoLinkable { homeMod_object = Just lm } bytecodeAndObjects :: Linkable -> Linkable -> HomeModLinkable bytecodeAndObjects bc o = assertPpr (not (linkableIsNativeCodeOnly bc) && linkableIsNativeCodeOnly o) (ppr bc $$ ppr o) (HomeModLinkable (Just bc) (Just o)) {- Note [Home module build products] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When compiling a home module we can produce some combination of the following build products. 1. A byte code linkable, for use with the byte code interpreter. 2. An object file linkable, for linking a final executable or the byte code interpreter What we have produced is recorded in the `HomeModLinkable` type. In the case that these linkables are produced they are stored in the relevant field so that subsequent modules can retrieve and use them as necessary. * `-fbyte-code` will *only* produce a byte code linkable. This is the default in GHCi. * `-fobject-code` will *only* produce an object file linkable. This is the default in -c and --make mode. * `-fbyte-code-and-object-code` produces both a byte-code and object file linkable. So both fields are populated. Why would you want to produce both an object file and byte code linkable? If you also want to use `-fprefer-byte-code` then you should probably also use this flag to make sure that byte code is generated for your modules. -}