diff --git a/compiler/GHC/Linker/Deps.hs b/compiler/GHC/Linker/Deps.hs index e363d12d4d4f89abfee53ff59958a6f6da7f8ae2..a52aabc80f6452711b82b7e3e1034fc7d7e109fc 100644 --- a/compiler/GHC/Linker/Deps.hs +++ b/compiler/GHC/Linker/Deps.hs @@ -59,6 +59,7 @@ import System.Directory data LinkDepsOpts = LinkDepsOpts { ldObjSuffix :: !String -- ^ Suffix of .o files + , ldForceDyn :: !Bool -- ^ Always use .dyn_o? , ldOneShotMode :: !Bool -- ^ Is the driver in one-shot mode? , ldModuleGraph :: !ModuleGraph , ldUnitEnv :: !UnitEnv @@ -351,6 +352,16 @@ throwProgramError opts doc = throwGhcExceptionIO (ProgramError (renderWithContex checkNonStdWay :: LinkDepsOpts -> Interp -> SrcSpan -> IO (Maybe FilePath) checkNonStdWay _opts interp _srcspan + -- On some targets (e.g. wasm) the RTS linker only supports loading + -- dynamic code, in which case we need to ensure the .dyn_o object + -- is picked (instead of .o which is also present because of + -- -dynamic-too) + | ldForceDyn _opts = do + let target_ways = fullWays $ ldWays _opts + pure $ if target_ways `hasWay` WayDyn + then Nothing + else Just $ waysTag (WayDyn `addWay` target_ways) ++ "_o" + | ExternalInterp {} <- interpInstance interp = return Nothing -- with -fexternal-interpreter we load the .o files, whatever way -- they were built. If they were built for a non-std way, then diff --git a/compiler/GHC/Linker/Loader.hs b/compiler/GHC/Linker/Loader.hs index c3f9a8de2e1cdb7d3a3b1acc71757c8ed89595bc..d05539c4612f01c29dd43df54c06beff6628667a 100644 --- a/compiler/GHC/Linker/Loader.hs +++ b/compiler/GHC/Linker/Loader.hs @@ -639,6 +639,7 @@ initLinkDepsOpts hsc_env = opts where opts = LinkDepsOpts { ldObjSuffix = objectSuf dflags + , ldForceDyn = sTargetRTSLinkerOnlySupportsSharedLibs $ settings dflags , ldOneShotMode = isOneShot (ghcMode dflags) , ldModuleGraph = hsc_mod_graph hsc_env , ldUnitEnv = hsc_unit_env hsc_env