X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fghci%2FLinker.lhs;h=bd0bb353084b75269737a6423d71331752cb7211;hb=edc0bafd3fcd01b85a2e8894e5dfe149eb0e0857;hp=45cbdc095fd468851ed0b9e272e10fa35c69b6b4;hpb=6a16aa336536e5e425a5dea9e812bdad762749e5;p=ghc-hetmet.git diff --git a/compiler/ghci/Linker.lhs b/compiler/ghci/Linker.lhs index 45cbdc0..bd0bb35 100644 --- a/compiler/ghci/Linker.lhs +++ b/compiler/ghci/Linker.lhs @@ -51,10 +51,9 @@ import ErrUtils import SrcLoc import qualified Maybes import UniqSet -import FiniteMap import Constants import FastString -import Config ( cProjectVersion ) +import Config -- Standard libraries import Control.Monad @@ -62,6 +61,7 @@ import Control.Monad import Data.Char import Data.IORef import Data.List +import qualified Data.Map as Map import Foreign import Control.Concurrent.MVar @@ -429,8 +429,13 @@ preloadLib dflags lib_paths framework_paths lib_spec Object static_ish -> do b <- preload_static lib_paths static_ish maybePutStrLn dflags (if b then "done" - else "not found") - + else "not found") + + Archive static_ish + -> do b <- preload_static_archive lib_paths static_ish + maybePutStrLn dflags (if b then "done" + else "not found") + DLL dll_unadorned -> do maybe_errstr <- loadDynamic lib_paths dll_unadorned case maybe_errstr of @@ -468,6 +473,10 @@ preloadLib dflags lib_paths framework_paths lib_spec = do b <- doesFileExist name if not b then return False else loadObj name >> return True + preload_static_archive _paths name + = do b <- doesFileExist name + if not b then return False + else loadArchive name >> return True \end{code} @@ -633,6 +642,7 @@ getLinkDeps hsc_env hpt pls maybe_normal_osuf span mods text "module" <+> ppr mod <+> text "cannot be linked; it is only available as a boot module"))) + no_obj :: Outputable a => a -> IO b no_obj mod = dieWith span $ ptext (sLit "cannot find object file for module ") <> quotes (ppr mod) $$ @@ -657,7 +667,7 @@ getLinkDeps hsc_env hpt pls maybe_normal_osuf span mods -- ...and then find the linkable for it mb_lnk <- findObjectLinkableMaybe mod loc ; case mb_lnk of { - Nothing -> no_obj mod ; + Nothing -> no_obj mod ; Just lnk -> adjust_linkable lnk }} @@ -928,6 +938,8 @@ data LibrarySpec -- file in all the directories specified in -- v_Library_paths before giving up. + | Archive FilePath -- Full path name of a .a file, including trailing .a + | DLL String -- "Unadorned" name of a .DLL/.so -- e.g. On unix "qt" denotes "libqt.so" -- On WinDoze "burble" denotes "burble.DLL" @@ -952,10 +964,11 @@ partOfGHCi :: [PackageName] partOfGHCi | isWindowsTarget || isDarwinTarget = [] | otherwise = map PackageName - ["base", "haskell98", "template-haskell", "editline"] + ["base", "template-haskell", "editline"] showLS :: LibrarySpec -> String showLS (Object nm) = "(static) " ++ nm +showLS (Archive nm) = "(static archive) " ++ nm showLS (DLL nm) = "(dynamic) " ++ nm showLS (DLLPath nm) = "(dynamic) " ++ nm showLS (Framework nm) = "(framework) " ++ nm @@ -1000,7 +1013,7 @@ linkPackages' dflags new_pks pls = do | Just pkg_cfg <- lookupPackage pkg_map new_pkg = do { -- Link dependents first pkgs' <- link pkgs [ Maybes.expectJust "link_one" $ - lookupFM ipid_map ipid + Map.lookup ipid ipid_map | ipid <- depends pkg_cfg ] -- Now link the package itself ; linkPackage dflags pkg_cfg @@ -1016,6 +1029,12 @@ linkPackage dflags pkg let dirs = Packages.libraryDirs pkg let libs = Packages.hsLibraries pkg + -- The FFI GHCi import lib isn't needed as + -- compiler/ghci/Linker.lhs + rts/Linker.c link the + -- interpreted references to FFI to the compiled FFI. + -- We therefore filter it out so that we don't get + -- duplicate symbol errors. + libs' = filter ("HSffi" /=) libs -- Because of slight differences between the GHC dynamic linker and -- the native system linker some packages have to link with a -- different list of libraries when using GHCi. Examples include: libs @@ -1027,11 +1046,12 @@ linkPackage dflags pkg then Packages.extraLibraries pkg else Packages.extraGHCiLibraries pkg) ++ [ lib | '-':'l':lib <- Packages.ldOptions pkg ] - classifieds <- mapM (locateOneObj dirs) libs + classifieds <- mapM (locateOneObj dirs) libs' -- Complication: all the .so's must be loaded before any of the .o's. let dlls = [ dll | DLL dll <- classifieds ] objs = [ obj | Object obj <- classifieds ] + archs = [ arch | Archive arch <- classifieds ] maybePutStr dflags ("Loading package " ++ display (sourcePackageId pkg) ++ " ... ") @@ -1053,6 +1073,7 @@ linkPackage dflags pkg -- Ordering isn't important here, because we do one final link -- step to resolve everything. mapM_ loadObj objs + mapM_ loadArchive archs maybePutStr dflags "linking ... " ok <- resolveObjs @@ -1084,29 +1105,32 @@ loadFrameworks pkg -- If it isn't present, we assume it's a dynamic library. locateOneObj :: [FilePath] -> String -> IO LibrarySpec locateOneObj dirs lib + | not ("HS" `isPrefixOf` lib) + -- For non-Haskell libraries (e.g. gmp, iconv) we assume dynamic library + = assumeDll | not isDynamicGhcLib - -- When the GHC package was not compiled as dynamic library - -- (=DYNAMIC not set), we search for .o libraries. - = do { mb_obj_path <- findFile mk_obj_path dirs - ; case mb_obj_path of - Just obj_path -> return (Object obj_path) - Nothing -> return (DLL lib) } - + -- 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 | otherwise -- When the GHC package was compiled as dynamic library (=DYNAMIC set), -- we search for .so libraries first. - = do { mb_lib_path <- findFile mk_dyn_lib_path dirs - ; case mb_lib_path of - Just _ -> return (DLL dyn_lib_name) - Nothing -> - do { mb_obj_path <- findFile mk_obj_path dirs - ; case mb_obj_path of - Just obj_path -> return (Object obj_path) - Nothing -> return (DLL lib) }} -- We assume + = findDll `orElse` findObject `orElse` findArchive `orElse` assumeDll where mk_obj_path dir = dir (lib <.> "o") + mk_arch_path dir = dir ("lib" ++ lib <.> "a") dyn_lib_name = lib ++ "-ghc" ++ cProjectVersion mk_dyn_lib_path dir = dir mkSOName dyn_lib_name + findObject = liftM (fmap Object) $ findFile mk_obj_path dirs + findArchive = liftM (fmap Archive) $ findFile mk_arch_path dirs + findDll = liftM (fmap DLL) $ findFile mk_dyn_lib_path dirs + assumeDll = return (DLL lib) + infixr `orElse` + f `orElse` g = do m <- f + case m of + Just x -> return x + Nothing -> g -- ---------------------------------------------------------------------------- -- Loading a dyanmic library (dlopen()-ish on Unix, LoadLibrary-ish on Win32)