summaryrefslogtreecommitdiff
path: root/compiler/ghci/Linker.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ghci/Linker.hs')
-rw-r--r--compiler/ghci/Linker.hs74
1 files changed, 42 insertions, 32 deletions
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
index f62998ce86..9fa89fec5e 100644
--- a/compiler/ghci/Linker.hs
+++ b/compiler/ghci/Linker.hs
@@ -504,24 +504,20 @@ dieWith dflags span msg = throwGhcExceptionIO (ProgramError (showSDoc dflags (mk
checkNonStdWay :: DynFlags -> SrcSpan -> IO (Maybe FilePath)
-checkNonStdWay dflags srcspan =
- if interpWays == haskellWays
- then return Nothing
- -- see #3604: object files compiled for way "dyn" need to link to the
- -- dynamic packages, so we can't load them into a statically-linked GHCi.
- -- we have to treat "dyn" in the same way as "prof".
- --
- -- In the future when GHCi is dynamically linked we should be able to relax
- -- this, but they we may have to make it possible to load either ordinary
- -- .o files or -dynamic .o files into GHCi (currently that's not possible
- -- because the dynamic objects contain refs to e.g. __stginit_base_Prelude_dyn
- -- whereas we have __stginit_base_Prelude_.
- else if objectSuf dflags == normalObjectSuffix && not (null haskellWays)
- then failNonStd dflags srcspan
- else return $ Just $ if dynamicGhc
- then "dyn_o"
- else "o"
- where haskellWays = filter (not . wayRTSOnly) (ways dflags)
+checkNonStdWay dflags srcspan
+ | interpWays == haskellWays = return Nothing
+ -- Only if we are compiling with the same ways as GHC is built
+ -- with, can we dynamically load those object files. (see #3604)
+
+ | objectSuf dflags == normalObjectSuffix && not (null haskellWays)
+ = failNonStd dflags srcspan
+
+ | otherwise = return (Just (interpTag ++ "o"))
+ where
+ haskellWays = filter (not . wayRTSOnly) (ways dflags)
+ interpTag = case mkBuildTag interpWays of
+ "" -> ""
+ tag -> tag ++ "_"
normalObjectSuffix :: String
normalObjectSuffix = phaseInputExt StopLn
@@ -529,11 +525,13 @@ normalObjectSuffix = phaseInputExt StopLn
failNonStd :: DynFlags -> SrcSpan -> IO (Maybe FilePath)
failNonStd dflags srcspan = dieWith dflags srcspan $
ptext (sLit "Dynamic linking required, but this is a non-standard build (eg. prof).") $$
- ptext (sLit "You need to build the program twice: once the") <+> ghciWay <+> ptext (sLit "way, and then") $$
+ ptext (sLit "You need to build the program twice: once") <+>
+ ghciWay <> ptext (sLit ", and then") $$
ptext (sLit "in the desired way using -osuf to set the object file suffix.")
- where ghciWay = if dynamicGhc
- then ptext (sLit "dynamic")
- else ptext (sLit "normal")
+ where ghciWay
+ | dynamicGhc = ptext (sLit "with -dynamic")
+ | rtsIsProfiled = ptext (sLit "with -prof")
+ | otherwise = ptext (sLit "the normal way")
getLinkDeps :: HscEnv -> HomePackageTable
-> PersistentLinkerState
@@ -663,7 +661,7 @@ getLinkDeps hsc_env hpt pls replace_osuf span mods
ok <- doesFileExist new_file
if (not ok)
then dieWith dflags span $
- ptext (sLit "cannot find normal object file ")
+ ptext (sLit "cannot find object file ")
<> quotes (text new_file) $$ while_linking_expr
else return (DotO new_file)
adjust_ul _ (DotA fp) = panic ("adjust_ul DotA " ++ show fp)
@@ -1199,22 +1197,34 @@ locateLib dflags is_hs dirs lib
-- for a dynamic library (#5289)
-- otherwise, assume loadDLL can find it
--
- = findDll `orElse` findArchive `orElse` tryGcc `orElse` tryGccPrefixed `orElse` assumeDll
-
- | not dynamicGhc
- -- When the GHC package was not compiled as dynamic library
- -- (=DYNAMIC not set), we search for .o libraries or, if they
- -- don't exist, .a libraries.
- = findObject `orElse` findArchive `orElse` assumeDll
+ = findDll `orElse`
+ findArchive `orElse`
+ tryGcc `orElse`
+ tryGccPrefixed `orElse`
+ assumeDll
- | otherwise
+ | dynamicGhc
-- When the GHC package was compiled as dynamic library (=DYNAMIC set),
-- we search for .so libraries first.
= findHSDll `orElse` findDynObject `orElse` assumeDll
+
+ | rtsIsProfiled
+ -- When the GHC package is profiled, only a libHSfoo_p.a archive will do.
+ = findArchive `orElse`
+ assumeDll
+
+ | otherwise
+ -- HSfoo.o is the best, but only works for the normal way
+ -- libHSfoo.a is the backup option.
+ = findObject `orElse`
+ findArchive `orElse`
+ assumeDll
+
where
obj_file = lib <.> "o"
dyn_obj_file = lib <.> "dyn_o"
- arch_file = "lib" ++ lib <.> "a"
+ arch_file = "lib" ++ lib ++ lib_tag <.> "a"
+ lib_tag = if is_hs && rtsIsProfiled then "_p" else ""
hs_dyn_lib_name = lib ++ '-':programName dflags ++ projectVersion dflags
hs_dyn_lib_file = mkHsSOName platform hs_dyn_lib_name