summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@well-typed.com>2022-05-23 09:35:35 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-07-16 23:50:36 -0400
commit2cd75550cad93b84a4ef831c5dc8f40071c3a903 (patch)
treebe7a75f496df76c4d25da1f0f1f2c69e602683b7
parentf17912e4db9a104b30b956ae61d17329d0a5f601 (diff)
downloadhaskell-2cd75550cad93b84a4ef831c5dc8f40071c3a903.tar.gz
Loader: Implement gnu-style -l:$path syntax
Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic.
-rw-r--r--compiler/GHC/Linker/Loader.hs42
1 files changed, 31 insertions, 11 deletions
diff --git a/compiler/GHC/Linker/Loader.hs b/compiler/GHC/Linker/Loader.hs
index ed633fedb4..6c2829c432 100644
--- a/compiler/GHC/Linker/Loader.hs
+++ b/compiler/GHC/Linker/Loader.hs
@@ -1544,7 +1544,7 @@ locateLib
-> [FilePath]
-> String
-> IO LibrarySpec
-locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib
+locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib0
| not is_hs
-- For non-Haskell libraries (e.g. gmp, iconv):
-- first look in library-dirs for a dynamic library (on User paths only)
@@ -1602,22 +1602,35 @@ locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib
gcc = False
user = True
+ -- Emulate ld's behavior of treating $LIB in `-l:$LIB` as a literal file
+ -- name
+ (lib, verbatim) = case lib0 of
+ ':' : rest -> (rest, True)
+ other -> (other, False)
+
obj_file
| is_hs && loading_profiled_hs_libs = lib <.> "p_o"
| otherwise = lib <.> "o"
dyn_obj_file = lib <.> "dyn_o"
- arch_files = [ "lib" ++ lib ++ lib_tag <.> "a"
- , lib <.> "a" -- native code has no lib_tag
- , "lib" ++ lib, lib
- ]
+ arch_files
+ | verbatim = [lib]
+ | otherwise = [ "lib" ++ lib ++ lib_tag <.> "a"
+ , lib <.> "a" -- native code has no lib_tag
+ , "lib" ++ lib
+ , lib
+ ]
lib_tag = if is_hs && loading_profiled_hs_libs then "_p" else ""
loading_profiled_hs_libs = interpreterProfiled interp
loading_dynamic_hs_libs = interpreterDynamic interp
- import_libs = [ lib <.> "lib" , "lib" ++ lib <.> "lib"
- , "lib" ++ lib <.> "dll.a", lib <.> "dll.a"
- ]
+ import_libs
+ | verbatim = [lib]
+ | otherwise = [ lib <.> "lib"
+ , "lib" ++ lib <.> "lib"
+ , "lib" ++ lib <.> "dll.a"
+ , lib <.> "dll.a"
+ ]
hs_dyn_lib_name = lib ++ dynLibSuffix (ghcNameVersion dflags)
hs_dyn_lib_file = platformHsSOName platform hs_dyn_lib_name
@@ -1625,9 +1638,16 @@ locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib
#if defined(CAN_LOAD_DLL)
so_name = platformSOName platform lib
lib_so_name = "lib" ++ so_name
- dyn_lib_file = case (arch, os) of
- (ArchX86_64, OSSolaris2) -> "64" </> so_name
- _ -> so_name
+ dyn_lib_file
+ | verbatim && any (`isExtensionOf` lib) [".so", ".dylib", ".dll"]
+ = lib
+
+ | ArchX86_64 <- arch
+ , OSSolaris2 <- os
+ = "64" </> so_name
+
+ | otherwise
+ = so_name
#endif
findObject = liftM (fmap $ Objects . (:[])) $ findFile dirs obj_file