diff --git a/compiler/GHC/Linker/Deps.hs b/compiler/GHC/Linker/Deps.hs index e23b68d7c7a985be4a86b67adb9d28c05c92c0ec..a6736c8bc16bf61386b6d7c2e700e00eb4a635c2 100644 --- a/compiler/GHC/Linker/Deps.hs +++ b/compiler/GHC/Linker/Deps.hs @@ -60,6 +60,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 -- ^ Module graph , ldUnitEnv :: !UnitEnv -- ^ Unit environment @@ -349,6 +350,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 bcf4ba9cc591e67e0ac40bd03b5f267d7d2ba6e8..adc729f31edd48e2167bfbb66e295098f69360c4 100644 --- a/compiler/GHC/Linker/Loader.hs +++ b/compiler/GHC/Linker/Loader.hs @@ -637,6 +637,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