-linkPackage pkg | name pkg `elem` ["rts", "gmp"] = return ()
-linkPackage pkg = do
- putStr ("Loading package " ++ name pkg ++ " ... ")
- let dirs = library_dirs pkg
- let objs = map (++".o") (hs_libraries pkg ++ extra_libraries pkg)
- mapM (linkOneObj dirs) objs
- putStr "resolving ... "
- resolveObjs
- putStrLn "done."
-
-linkOneObj dirs obj = do
- filename <- findFile dirs obj
- loadObj filename
-
-findFile [] obj = throwDyn (OtherError ("can't find " ++ obj))
-findFile (d:ds) obj = do
- let path = d ++ '/':obj
- b <- doesFileExist path
- if b then return path else findFile ds obj
+linkPackage pkg
+ | name pkg `elem` ["rts", "gmp"]
+ = return ()
+ | otherwise
+ = do putStr ("Loading package " ++ name pkg ++ " ... ")
+ -- For each obj, try obj.o and if that fails, obj.so.
+ -- Complication: all the .so's must be loaded before any of the .o's.
+ let dirs = library_dirs pkg
+ let objs = hs_libraries pkg ++ extra_libraries pkg
+ classifieds <- mapM (locateOneObj dirs) objs
+ let sos_first = filter isRight classifieds
+ ++ filter (not.isRight) classifieds
+ mapM loadClassified sos_first
+ putStr "linking ... "
+ resolveObjs
+ putStrLn "done."
+ where
+ isRight (Right _) = True
+ isRight (Left _) = False
+
+loadClassified :: LibrarySpec -> IO ()
+loadClassified (Left obj_absolute_filename)
+ = do loadObj obj_absolute_filename
+loadClassified (Right dll_unadorned)
+ = do maybe_errmsg <- addDLL dll_unadorned
+ if maybe_errmsg == nullPtr
+ then return ()
+ else do str <- peekCString maybe_errmsg
+ throwDyn (OtherError ("can't find .o or .so/.DLL for: "
+ ++ dll_unadorned ++ " (" ++ str ++ ")" ))
+
+locateOneObj :: [FilePath] -> String -> IO LibrarySpec
+locateOneObj [] obj
+ = return (Right obj) -- we assume
+locateOneObj (d:ds) obj
+ = do let path = d ++ '/':obj ++ ".o"
+ b <- doesFileExist path
+ if b then return (Left path) else locateOneObj ds obj