{-# OPTIONS -optc-DNON_POSIX_SOURCE -#include "Linker.h" #-}
-module Linker ( HValue, initDynLinker, showLinkerState,
+module Linker ( HValue, showLinkerState,
linkExpr, unload, extendLinkEnv,
linkPackages,
) where
import Packages
import DriverState ( v_Library_paths, v_Opt_l, v_Ld_inputs, getStaticOpts, v_ExplicitPackages )
+import DriverPhases ( isObjectFilename, isDynLibFilename )
import DriverUtil ( getFileSuffix )
#ifdef darwin_TARGET_OS
import DriverState ( v_Cmdline_frameworks, v_Framework_paths )
; lib_paths <- readIORef v_Library_paths
; cmdline_ld_inputs <- readIORef v_Ld_inputs
- ; let (cmdline_libs, cmdline_objs) = partition libish cmdline_ld_inputs
+ ; classified_ld_inputs <- mapM classifyLdInput cmdline_ld_inputs
-- (e) Link any MacOS frameworks
#ifdef darwin_TARGET_OS
; let framework_paths = []
#endif
-- Finally do (c),(d),(e)
- ; let cmdline_lib_specs = map Object cmdline_objs
- ++ map DLLPath cmdline_libs
+ ; let cmdline_lib_specs = [ l | Just l <- classified_ld_inputs ]
++ map DLL minus_ls
++ map Framework frameworks
; if null cmdline_lib_specs then return ()
else throwDyn (InstallationError "linking extra libraries/objects failed")
}}
-libish :: String -> Bool
-libish f = getFileSuffix f `elem` dynlib_suffixes
-
-#ifdef mingw32_TARGET_OS
-dynlib_suffixes = ["dll", "DLL"]
-#elif defined(darwin_TARGET_OS)
-dynlib_suffixes = ["dylib"]
-#else
-dynlib_suffixes = ["so"]
-#endif
+classifyLdInput :: FilePath -> IO (Maybe LibrarySpec)
+classifyLdInput f
+ | isObjectFilename f = return (Just (Object f))
+ | isDynLibFilename f = return (Just (DLLPath f))
+ | otherwise = do
+ hPutStrLn stderr ("Warning: ignoring unrecognised input `" ++ f ++ "'")
+ return Nothing
preloadLib :: DynFlags -> [String] -> [String] -> LibrarySpec -> IO ()
preloadLib dflags lib_paths framework_paths lib_spec
# if defined(mingw32_TARGET_OS) || defined(darwin_TARGET_OS)
= [ ]
# else
- = [ "base", "haskell98", "haskell-src", "readline" ]
+ = [ "base", "haskell98", "template-haskell", "readline" ]
# endif
showLS (Object nm) = "(static) " ++ nm
-- See comments with partOfGHCi
when (Packages.name pkg `notElem` partOfGHCi) $ do
loadFrameworks pkg
- mapM_ (load_dyn dirs) dlls
+ -- When a library A needs symbols from a library B, the order in
+ -- extra_libraries/extra_ld_opts is "-lA -lB", because that's the
+ -- way ld expects it for static linking. Dynamic linking is a
+ -- different story: When A has no dependency information for B,
+ -- dlopen-ing A with RTLD_NOW (see addDLL in Linker.c) will fail
+ -- when B has not been loaded before. In a nutshell: Reverse the
+ -- order of DLLs for dynamic linking.
+ -- This fixes a problem with the HOpenGL package (see "Compiling
+ -- HOpenGL under recent versions of GHC" on the HOpenGL list).
+ mapM_ (load_dyn dirs) (reverse dlls)
-- After loading all the DLLs, we can load the static objects.
+ -- Ordering isn't important here, because we do one final link
+ -- step to resolve everything.
mapM_ loadObj objs
maybePutStr dflags "linking ... "