[project @ 2003-04-10 15:46:11 by simonpj]
[ghc-hetmet.git] / ghc / compiler / ghci / Linker.lhs
index a3dc62e..7ee6e2e 100644 (file)
@@ -13,12 +13,13 @@ necessary.
 
 \begin{code}
 
-{-# OPTIONS -optc-DNON_POSIX_SOURCE #-}
+{-# OPTIONS -optc-DNON_POSIX_SOURCE -#include "Linker.h" #-}
 
 module Linker ( HValue, initLinker, showLinkerState,
                linkLibraries, linkExpr,
                unload, extendLinkEnv, 
-               LibrarySpec(..)
+               LibrarySpec(..),
+               linkPackages,
        ) where
 
 #include "../includes/config.h"
@@ -27,22 +28,19 @@ module Linker ( HValue, initLinker, showLinkerState,
 import ObjLink         ( loadDLL, loadObj, unloadObj, resolveObjs, initLinker )
 import ByteCodeLink    ( HValue, ClosureEnv, extendClosureEnv, linkBCO )
 import ByteCodeItbls   ( ItblEnv )
-import ByteCodeAsm     ( CompiledByteCode(..), bcosFreeNames,
-                         UnlinkedBCO, UnlinkedBCOExpr, nameOfUnlinkedBCO )
+import ByteCodeAsm     ( CompiledByteCode(..), bcoFreeNames, UnlinkedBCO(..))
 
-import Packages                ( PackageConfig(..), PackageName, PackageConfigMap, lookupPkg,
-                         packageDependents, packageNameString )
-import DriverState     ( v_Library_paths, v_Cmdline_libraries, getPackageConfigMap )
+import Packages
+import DriverState     ( v_Library_paths, v_Opt_l, getStaticOpts )
+#ifdef darwin_TARGET_OS
+import DriverState     ( v_Cmdline_frameworks, v_Framework_paths )
+#endif
 import Finder          ( findModule, findLinkable )
-import HscTypes                ( Linkable(..), isObjectLinkable, nameOfObject, byteCodeOfObject,
-                         Unlinked(..), isInterpretable, isObject, Dependencies(..),
-                         HscEnv(..), PersistentCompilerState(..), ExternalPackageState(..),
-                         HomePackageTable, PackageIfaceTable, ModIface(..), HomeModInfo(..),
-                         lookupIface )
+import HscTypes
 import Name            ( Name,  nameModule, isExternalName )
 import NameEnv
 import NameSet         ( nameSetToList )
-import Module          ( ModLocation(..), Module, ModuleName, isHomeModule, moduleName, lookupModuleEnvByName )
+import Module
 import FastString      ( FastString(..), unpackFS )
 import ListSetOps      ( minusList )
 import CmdLineOpts     ( DynFlags(verbosity) )
@@ -50,7 +48,6 @@ import BasicTypes     ( SuccessFlag(..), succeeded, failed )
 import Outputable
 import Panic            ( GhcException(..) )
 import Util             ( zipLazy, global )
-import ErrUtils                ( Message )
 
 -- Standard libraries
 import Control.Monad   ( when, filterM, foldM )
@@ -59,7 +56,7 @@ import Data.IORef     ( IORef, readIORef, writeIORef )
 import Data.List       ( partition, nub )
 
 import System.IO       ( putStr, putStrLn, hPutStrLn, stderr, fixIO )
-import System.Directory        ( doesFileExist, getModificationTime )
+import System.Directory        ( doesFileExist )
 
 import Control.Exception ( block, throwDyn )
 
@@ -169,7 +166,7 @@ showLinkerState
 
 \begin{code}
 linkExpr :: HscEnv -> PersistentCompilerState
-        -> UnlinkedBCOExpr -> IO HValue          -- IO BCO# really
+        -> UnlinkedBCO -> IO HValue
 
 -- Link a single expression, *including* first linking packages and 
 -- modules that this expression depends on.
@@ -177,7 +174,7 @@ linkExpr :: HscEnv -> PersistentCompilerState
 -- Raises an IO exception if it can't find a compiled version of the
 -- dependents to link.
 
-linkExpr hsc_env pcs (root_ul_bco, aux_ul_bcos)
+linkExpr hsc_env pcs root_ul_bco
   = do {  
        -- Find what packages and linkables are required
      (lnks, pkgs) <- getLinkDeps hpt pit needed_mods ;
@@ -195,20 +192,19 @@ linkExpr hsc_env pcs (root_ul_bco, aux_ul_bcos)
         ce = closure_env pls
 
        -- Link the necessary packages and linkables
-   ; (_, (root_hval:_)) <- linkSomeBCOs False ie ce all_bcos
+   ; (_, (root_hval:_)) <- linkSomeBCOs False ie ce [root_ul_bco]
    ; return root_hval
    }}
    where
      pit    = eps_PIT (pcs_EPS pcs)
      hpt    = hsc_HPT hsc_env
      dflags = hsc_dflags hsc_env
-     all_bcos   = root_ul_bco : aux_ul_bcos
-     free_names = nameSetToList (bcosFreeNames all_bcos)
-  
+     free_names = nameSetToList (bcoFreeNames root_ul_bco)
+
      needed_mods :: [Module]
      needed_mods = [ nameModule n | n <- free_names, isExternalName n ]
  
-dieWith msg = throwDyn (UsageError (showSDoc msg))
+dieWith msg = throwDyn (ProgramError (showSDoc msg))
 
 getLinkDeps :: HomePackageTable -> PackageIfaceTable
            -> [Module]                         -- If you need these
@@ -231,8 +227,8 @@ getLinkDeps hpt pit mods
        } ;
        
        -- 3.  For each dependent module, find its linkable
-       --     This will either be in the HPT or (in the case of one-shot compilation)
-       --     we may need to use maybe_getFileLinkable
+       --     This will either be in the HPT or (in the case of one-shot
+       --     compilation) we may need to use maybe_getFileLinkable
        lnks_needed <- mapM get_linkable mods_needed ;
 
        return (lnks_needed, pkgs_needed) }
@@ -266,8 +262,8 @@ getLinkDeps hpt pit mods
                -- so use the Finder to get a ModLocation...
          do { mb_stuff <- findModule mod_name ;
               case mb_stuff of {
-                 Nothing -> no_obj mod_name ;
-                 Just (_, loc) -> do {
+                 Left _ -> no_obj mod_name ;
+                 Right (_, loc) -> do {
 
                -- ...and then find the linkable for it
               mb_lnk <- findLinkable mod_name loc ;
@@ -275,7 +271,7 @@ getLinkDeps hpt pit mods
                  Nothing -> no_obj mod_name ;
                  Just lnk -> return lnk
          }}}} 
-\end{code}                       
+\end{code}
 
 
 %************************************************************************
@@ -391,23 +387,38 @@ linkLibraries :: DynFlags
 -- specified on the command line. 
 linkLibraries dflags objs
    = do        { lib_paths <- readIORef v_Library_paths
-       ; minus_ls  <- readIORef v_Cmdline_libraries
+       ; opt_l  <- getStaticOpts v_Opt_l
+       ; let minus_ls = [ lib | '-':'l':lib <- opt_l ]
+#ifdef darwin_TARGET_OS
+       ; framework_paths <- readIORef v_Framework_paths
+       ; frameworks <- readIORef v_Cmdline_frameworks
+#endif
         ; let cmdline_lib_specs = map Object objs ++ map DLL minus_ls
-       
+#ifdef darwin_TARGET_OS
+               ++ map Framework frameworks
+#endif
        ; if (null cmdline_lib_specs) then return () 
          else do {
 
                -- Now link them
+#ifdef darwin_TARGET_OS
+       ; mapM_ (preloadLib dflags lib_paths framework_paths) cmdline_lib_specs
+#else
        ; mapM_ (preloadLib dflags lib_paths) cmdline_lib_specs
-
+#endif
        ; maybePutStr dflags "final link ... "
        ; ok <- resolveObjs
        ; if succeeded ok then maybePutStrLn dflags "done."
          else throwDyn (InstallationError "linking extra libraries/objects failed")
        }}
      where
+#ifdef darwin_TARGET_OS
+        preloadLib :: DynFlags -> [String] -> [String] -> LibrarySpec -> IO ()
+        preloadLib dflags lib_paths framework_paths lib_spec
+#else
         preloadLib :: DynFlags -> [String] -> LibrarySpec -> IO ()
         preloadLib dflags lib_paths lib_spec
+#endif
            = do maybePutStr dflags ("Loading object " ++ showLS lib_spec ++ " ... ")
                 case lib_spec of
                    Object static_ish
@@ -420,7 +431,14 @@ linkLibraries dflags objs
                                Nothing -> return ()
                                Just mm -> preloadFailed mm lib_paths lib_spec
                             maybePutStrLn dflags "done"
-
+#ifdef darwin_TARGET_OS
+                   Framework framework
+                      -> do maybe_errstr <- loadFramework framework_paths framework
+                            case maybe_errstr of
+                               Nothing -> return ()
+                               Just mm -> preloadFailed mm framework_paths lib_spec
+                            maybePutStrLn dflags "done"
+#endif
         preloadFailed :: String -> [String] -> LibrarySpec -> IO ()
         preloadFailed sys_errmsg paths spec
            = do maybePutStr dflags
@@ -490,7 +508,7 @@ linkSomeBCOs :: Bool        -- False <=> add _all_ BCOs to returned closure env
                                        
 
 linkSomeBCOs toplevs_only ie ce_in ul_bcos
-   = do let nms = map nameOfUnlinkedBCO ul_bcos
+   = do let nms = map unlinkedBCOName ul_bcos
         hvals <- fixIO 
                     ( \ hvs -> let ce_out = extendClosureEnv ce_in (zipLazy nms hvs)
                                in  mapM (linkBCO ie ce_out) ul_bcos )
@@ -619,11 +637,11 @@ data LibrarySpec
 -- of DLL handles that rts/Linker.c maintains, and that in turn is 
 -- used by lookupSymbol.  So we must call addDLL for each library 
 -- just to get the DLL handle into the list.
-partOfGHCi 
-#          ifndef mingw32_TARGET_OS
-           = [ "base", "haskell98", "haskell-src", "readline" ]
+partOfGHCi
+#          if defined(mingw32_TARGET_OS) || defined(darwin_TARGET_OS)
+           = [ ]
 #          else
-          = [ ]
+           = [ "base", "haskell98", "haskell-src", "readline" ]
 #          endif
 
 showLS (Object nm)  = "(static) " ++ nm
@@ -678,6 +696,7 @@ linkPackage dflags pkg
    = do 
         let dirs      =  Packages.library_dirs pkg
         let libs      =  Packages.hs_libraries pkg ++ extra_libraries pkg
+                               ++ [ lib | '-':'l':lib <- extra_ld_opts pkg ]
         classifieds   <- mapM (locateOneObj dirs) libs
 #ifdef darwin_TARGET_OS
         let fwDirs    =  Packages.framework_dirs pkg