summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Sandberg Ericsson <adam@sandbergericsson.se>2021-11-05 18:04:24 +0000
committerAdam Sandberg Ericsson <adam@sandbergericsson.se>2021-11-20 12:09:02 +0000
commit0f85ae30703d05319bf01ec1ca98d14d938f2db2 (patch)
treebcff4f3a503e17256fa3b6a2c84c06050120dbb0
parentb2933ea95273f11b05f7ff796a9646a2e912d7fc (diff)
downloadhaskell-0f85ae30703d05319bf01ec1ca98d14d938f2db2.tar.gz
Support loading dynamic haskell (package) libraries for TH/GHCi with a statically linked GHC api user #20628wip/adamse/20628-dynloader
-rw-r--r--compiler/GHC/Driver/Flags.hs1
-rw-r--r--compiler/GHC/Driver/Session.hs3
-rw-r--r--compiler/GHC/Linker/Loader.hs47
3 files changed, 35 insertions, 16 deletions
diff --git a/compiler/GHC/Driver/Flags.hs b/compiler/GHC/Driver/Flags.hs
index 192b983887..9a665c0a63 100644
--- a/compiler/GHC/Driver/Flags.hs
+++ b/compiler/GHC/Driver/Flags.hs
@@ -290,6 +290,7 @@ data GeneralFlag
| Opt_Hpc
| Opt_FamAppCache
| Opt_ExternalInterpreter
+ | Opt_PreferDynamicLoader
| Opt_OptimalApplicativeDo
| Opt_VersionMacros
| Opt_WholeArchiveHsLibs
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 5f4479939a..41ab6fa805 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -3379,7 +3379,8 @@ fFlagsDeps = [
flagSpec "show-loaded-modules" Opt_ShowLoadedModules,
flagSpec "whole-archive-hs-libs" Opt_WholeArchiveHsLibs,
flagSpec "keep-cafs" Opt_KeepCAFs,
- flagSpec "link-rts" Opt_LinkRts
+ flagSpec "link-rts" Opt_LinkRts,
+ flagSpec "prefer-dynamic-loader" Opt_PreferDynamicLoader
]
++ fHoleFlags
diff --git a/compiler/GHC/Linker/Loader.hs b/compiler/GHC/Linker/Loader.hs
index 80e303b046..661dd219d0 100644
--- a/compiler/GHC/Linker/Loader.hs
+++ b/compiler/GHC/Linker/Loader.hs
@@ -42,6 +42,7 @@ import GHC.Platform
import GHC.Platform.Ways
import GHC.Driver.Phases
+import GHC.Driver.Flags
import GHC.Driver.Env
import GHC.Driver.Session
import GHC.Driver.Ppr
@@ -333,6 +334,7 @@ loadCmdLineLibs' interp hsc_env pls =
let dflags@(DynFlags { ldInputs = cmdline_ld_inputs
, libraryPaths = lib_paths_base})
= hsc_dflags hsc_env
+ let prefer_dynamic_loader = gopt Opt_PreferDynamicLoader dflags
let logger = hsc_logger hsc_env
-- (c) Link libraries from the command-line
@@ -358,8 +360,10 @@ loadCmdLineLibs' interp hsc_env pls =
maybePutStrLn logger "Search directories (gcc):"
maybePutStr logger (unlines $ map (" "++) gcc_paths)
- libspecs
- <- mapM (locateLib interp hsc_env False lib_paths_env gcc_paths) minus_ls
+ libspecs <-
+ mapM
+ (locateLib interp hsc_env False prefer_dynamic_loader lib_paths_env gcc_paths)
+ minus_ls
-- (d) Link .o files from the command-line
classified_ld_inputs <- mapM (classifyLdInput logger platform)
@@ -1227,9 +1231,9 @@ unload_wkr interp keep_linkables pls@LoaderState{..} = do
-- of DLL handles that rts/Linker.c maintains, and that in turn is
-- used by lookupSymbol. So we must call addDLL for each library
-- just to get the DLL handle into the list.
-partOfGHCi :: [PackageName]
-partOfGHCi
- | isWindowsHost || isDarwinHost = []
+partOfGHCi :: Bool -> [PackageName]
+partOfGHCi prefer_dynamic_loader
+ | isWindowsHost || isDarwinHost || prefer_dynamic_loader = []
| otherwise = map (PackageName . mkFastString)
["base", "template-haskell", "editline"]
@@ -1294,8 +1298,12 @@ loadPackage interp hsc_env pkg
let logger = hsc_logger hsc_env
platform = targetPlatform dflags
is_dyn = interpreterDynamic interp
- dirs | is_dyn = map ST.unpack $ Packages.unitLibraryDynDirs pkg
- | otherwise = map ST.unpack $ Packages.unitLibraryDirs pkg
+ prefer_dynamic_loader = gopt Opt_PreferDynamicLoader dflags
+ dirs
+ | prefer_dynamic_loader || is_dyn
+ = map ST.unpack $ Packages.unitLibraryDynDirs pkg
+ | otherwise
+ = map ST.unpack $ Packages.unitLibraryDirs pkg
let hs_libs = map ST.unpack $ Packages.unitLibraries pkg
-- The FFI GHCi import lib isn't needed as
@@ -1322,10 +1330,16 @@ loadPackage interp hsc_env pkg
gcc_paths <- getGCCPaths logger dflags (platformOS platform)
dirs_env <- addEnvPaths "LIBRARY_PATH" dirs
- hs_classifieds
- <- mapM (locateLib interp hsc_env True dirs_env gcc_paths) hs_libs'
- extra_classifieds
- <- mapM (locateLib interp hsc_env False dirs_env gcc_paths) extra_libs
+ hs_classifieds <-
+ mapM
+ (locateLib interp hsc_env True prefer_dynamic_loader dirs_env gcc_paths)
+ hs_libs'
+
+ extra_classifieds <-
+ mapM
+ (locateLib interp hsc_env False prefer_dynamic_loader dirs_env gcc_paths)
+ extra_libs
+
let classifieds = hs_classifieds ++ extra_classifieds
-- Complication: all the .so's must be loaded before any of the .o's.
@@ -1346,7 +1360,7 @@ loadPackage interp hsc_env pkg
-- See comments with partOfGHCi
#if defined(CAN_LOAD_DLL)
- when (unitPackageName pkg `notElem` partOfGHCi) $ do
+ when (unitPackageName pkg `notElem` partOfGHCi prefer_dynamic_loader) $ do
loadFrameworks interp platform pkg
-- See Note [Crash early load_dyn and locateLib]
-- Crash early if can't load any of `known_dlls`
@@ -1460,7 +1474,7 @@ loadFrameworks interp platform pkg
Just err -> cmdLineErrorIO ("can't load framework: "
++ fw ++ " (" ++ err ++ ")" )
--- Try to find an object file for a given library in the given paths.
+-- | Try to find an object file for a given library in the given paths.
-- If it isn't present, we assume that addDLL in the RTS can find it,
-- which generally means that it should be a dynamic library in the
-- standard system search path.
@@ -1469,12 +1483,15 @@ loadFrameworks interp platform pkg
locateLib
:: Interp
-> HscEnv
+ -> Bool -- ^ are we looking for a haskell library
-> Bool
+ -- ^ if we are looking for a haskell library, do we want to look for
+ -- a dynamic library
-> [FilePath]
-> [FilePath]
-> String
-> IO LibrarySpec
-locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib
+locateLib interp hsc_env is_hs prefer_dynamic_loader lib_dirs gcc_dirs lib
| not is_hs
-- For non-Haskell libraries (e.g. gmp, iconv):
-- first look in library-dirs for a dynamic library (on User paths only)
@@ -1513,7 +1530,7 @@ locateLib interp hsc_env is_hs lib_dirs gcc_dirs lib
tryGcc `orElse`
assumeDll
- | loading_dynamic_hs_libs -- search for .so libraries first.
+ | prefer_dynamic_loader || loading_dynamic_hs_libs -- search for .so libraries first.
= findHSDll `orElse`
findDynObject `orElse`
assumeDll