Extend Windows runtime loader libsearch
authorTamar Christina <tamar@zhox.com>
Thu, 2 Mar 2017 20:14:34 +0000 (15:14 -0500)
committerBen Gamari <ben@smart-cactus.org>
Thu, 2 Mar 2017 21:05:05 +0000 (16:05 -0500)
This adds `.obj` extension to the list of valid
object file (we really shouldn't be using extensions
but instead trying to read the file and see if the header
makes sense.). Microsoft compilers use .obj instead of .o
for object files.

This also adds support to finding static archives when the
"lib" prefix is already in the filename. e.g. `-llibfoo` to
find `libfoo.a`. This is inline with binutils.

Test Plan: ./validate

Reviewers: simonmar, erikd, bgamari, hvr, austin

Reviewed By: bgamari

Subscribers: RyanGlScott, thomie, #ghc_windows_task_force

Differential Revision: https://phabricator.haskell.org/D3082

compiler/ghci/Linker.hs
rts/linker/LoadArchive.c

index ebd27b0..49f57e5 100644 (file)
@@ -1364,7 +1364,9 @@ locateLib hsc_env is_hs dirs lib
 
      obj_file     = lib <.> "o"
      dyn_obj_file = lib <.> "dyn_o"
-     arch_file = "lib" ++ lib ++ lib_tag <.> "a"
+     arch_files = [ "lib" ++ lib ++ lib_tag <.> "a"
+                  , lib <.> "a" -- native code has no lib_tag
+                  ]
      lib_tag = if is_hs && loading_profiled_hs_libs then "_p" else ""
 
      loading_profiled_hs_libs = interpreterProfiled dflags
@@ -1385,9 +1387,10 @@ locateLib hsc_env is_hs dirs lib
 
      findObject    = liftM (fmap Object)  $ findFile dirs obj_file
      findDynObject = liftM (fmap Object)  $ findFile dirs dyn_obj_file
-     findArchive   = let local  = liftM (fmap Archive) $ findFile dirs arch_file
-                         linked = liftM (fmap Archive) $ searchForLibUsingGcc dflags arch_file dirs
-                     in liftM2 (<|>) local linked
+     findArchive   = let local  name = liftM (fmap Archive) $ findFile dirs name
+                         linked name = liftM (fmap Archive) $ searchForLibUsingGcc dflags name dirs
+                         check name = apply [local name, linked name]
+                     in  apply (map check arch_files)
      findHSDll     = liftM (fmap DLLPath) $ findFile dirs hs_dyn_lib_file
      findDll       = liftM (fmap DLLPath) $ findFile dirs dyn_lib_file
      findSysDll    = fmap (fmap $ DLL . dropExtension . takeFileName) $ findSystemLibrary hsc_env so_name
index 7d9dc22..62922a7 100644 (file)
@@ -457,8 +457,11 @@ static HsInt loadArchive_ (pathchar *path)
 
         DEBUG_LOG("Found member file `%s'\n", fileName);
 
+        /* TODO: Stop relying on file extensions to determine input formats.
+                 Instead try to match file headers. See Trac #13103.  */
         isObject = (thisFileNameSize >= 2 && strncmp(fileName + thisFileNameSize - 2, ".o"  , 2) == 0)
-                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".p_o", 4) == 0);
+                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".p_o", 4) == 0)
+                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".obj", 4) == 0);
 
 #if defined(OBJFORMAT_PEi386)
         /*