Windows: print an error message in addDLL
authorSimon Marlow <marlowsd@gmail.com>
Wed, 3 Sep 2008 10:49:51 +0000 (10:49 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Wed, 3 Sep 2008 10:49:51 +0000 (10:49 +0000)
Also, look for libXXX.dll in addition to XXX.dll (see #1883, this
isn't really a proper fix, but it'll help in some cases).
And I tidied up the error message for a DLL load failure, though it's
still a bit of a mess because addDLL is supposed to return a (static)
string with the error message, but this isn't possible on Windows.

compiler/ghci/Linker.lhs
rts/Linker.c

index 459fbd9..5d01b9a 100644 (file)
@@ -456,21 +456,20 @@ preloadLib dflags lib_paths framework_paths lib_spec
   where
     preloadFailed :: String -> [String] -> LibrarySpec -> IO ()
     preloadFailed sys_errmsg paths spec
-       = do maybePutStr dflags
-              ("failed.\nDynamic linker error message was:\n   " 
-                    ++ sys_errmsg  ++ "\nWhilst trying to load:  " 
-                    ++ showLS spec ++ "\nDirectories to search are:\n"
-                    ++ unlines (map ("   "++) paths) )
-            give_up
+       = do maybePutStr dflags "failed.\n"
+            ghcError $
+             CmdLineError (
+                    "user specified .o/.so/.DLL could not be loaded ("
+                    ++ sys_errmsg ++ ")\nWhilst trying to load:  "
+                    ++ showLS spec ++ "\nAdditional directories searched:"
+                    ++ (if null paths then " (none)" else
+                        (concat (intersperse "\n" (map ("   "++) paths)))))
     
     -- Not interested in the paths in the static case.
     preload_static _paths name
        = do b <- doesFileExist name
             if not b then return False
                      else loadObj name >> return True
-    
-    give_up = ghcError $ 
-             CmdLineError "user specified .o/.so/.DLL could not be loaded."
 \end{code}
 
 
index a9c145b..26d671e 100644 (file)
@@ -1066,14 +1066,19 @@ addDLL( char *dll_name )
    sprintf(buf, "%s.DLL", dll_name);
    instance = LoadLibrary(buf);
    if (instance == NULL) {
-        sprintf(buf, "%s.DRV", dll_name);      // KAA: allow loading of drivers (like winspool.drv)
-        instance = LoadLibrary(buf);
-        if (instance == NULL) {
-               stgFree(buf);
-
-           /* LoadLibrary failed; return a ptr to the error msg. */
-           return "addDLL: unknown error";
-        }
+       if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
+       // KAA: allow loading of drivers (like winspool.drv)
+       sprintf(buf, "%s.DRV", dll_name);
+       instance = LoadLibrary(buf);
+       if (instance == NULL) {
+           if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
+           // #1883: allow loading of unix-style libfoo.dll DLLs
+           sprintf(buf, "lib%s.DLL", dll_name);
+           instance = LoadLibrary(buf);
+           if (instance == NULL) {
+               goto error;
+           }
+       }
    }
    stgFree(buf);
 
@@ -1089,6 +1094,13 @@ addDLL( char *dll_name )
 #  else
    barf("addDLL: not implemented on this platform");
 #  endif
+
+error:
+   stgFree(buf);
+   sysErrorBelch(dll_name);
+               
+   /* LoadLibrary failed; return a ptr to the error msg. */
+   return "addDLL: could not load DLL";
 }
 
 /* -----------------------------------------------------------------------------