diff options
author | Adam Sandberg Ericsson <adam@sandbergericsson.se> | 2021-11-21 15:20:40 +0000 |
---|---|---|
committer | Adam Sandberg Ericsson <adam@sandbergericsson.se> | 2021-11-21 15:20:40 +0000 |
commit | fbd45ea1111bc3896442598e9aa37a7e57fce14b (patch) | |
tree | 9f4011e6a99b51db1b5c4238ac34ca8d7772b9e0 | |
parent | 96c86456fdfd1c23ac4314efc39374bf73ede2f2 (diff) | |
download | haskell-wip/adamse/20628-dynloader-8.10.tar.gz |
Support loading dynamic haskell (package) libraries for TH/GHCi with a statically linked GHC api user #20628wip/adamse/20628-dynloader-8.10
(8.10 backport)
-rw-r--r-- | compiler/ghci/Linker.hs | 29 | ||||
-rw-r--r-- | compiler/main/DynFlags.hs | 4 |
2 files changed, 20 insertions, 13 deletions
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs index 7561c0cb08..be30f5c6b7 100644 --- a/compiler/ghci/Linker.hs +++ b/compiler/ghci/Linker.hs @@ -294,6 +294,7 @@ linkCmdLineLibs' 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 -- (c) Link libraries from the command-line let minus_ls_1 = [ lib | Option ('-':'l':lib) <- cmdline_ld_inputs ] @@ -319,7 +320,7 @@ linkCmdLineLibs' hsc_env pls = maybePutStr dflags (unlines $ map (" "++) gcc_paths) libspecs - <- mapM (locateLib hsc_env False lib_paths_env gcc_paths) minus_ls + <- mapM (locateLib 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 dflags) @@ -1194,9 +1195,9 @@ instance Outputable LibrarySpec where -- 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"] @@ -1262,8 +1263,12 @@ linkPackage hsc_env pkg let dflags = hsc_dflags hsc_env platform = targetPlatform dflags is_dyn = interpreterDynamic dflags - dirs | is_dyn = Packages.libraryDynDirs pkg - | otherwise = Packages.libraryDirs pkg + prefer_dynamic_loader = gopt Opt_PreferDynamicLoader dflags + dirs + | prefer_dynamic_loader || is_dyn + = Packages.libraryDynDirs pkg + | otherwise + = Packages.libraryDirs pkg let hs_libs = Packages.hsLibraries pkg -- The FFI GHCi import lib isn't needed as @@ -1290,9 +1295,9 @@ linkPackage hsc_env pkg dirs_env <- addEnvPaths "LIBRARY_PATH" dirs hs_classifieds - <- mapM (locateLib hsc_env True dirs_env gcc_paths) hs_libs' + <- mapM (locateLib hsc_env True prefer_dynamic_loader dirs_env gcc_paths) hs_libs' extra_classifieds - <- mapM (locateLib hsc_env False dirs_env gcc_paths) extra_libs + <- mapM (locateLib 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. @@ -1313,7 +1318,7 @@ linkPackage hsc_env pkg -- See comments with partOfGHCi #if defined(CAN_LOAD_DLL) - when (packageName pkg `notElem` partOfGHCi) $ do + when (packageName pkg `notElem` partOfGHCi prefer_dynamic_loader) $ do loadFrameworks hsc_env platform pkg -- See Note [Crash early load_dyn and locateLib] -- Crash early if can't load any of `known_dlls` @@ -1429,9 +1434,9 @@ loadFrameworks hsc_env platform pkg -- standard system search path. -- For GHCi we tend to prefer dynamic libraries over static ones as -- they are easier to load and manage, have less overhead. -locateLib :: HscEnv -> Bool -> [FilePath] -> [FilePath] -> String +locateLib :: HscEnv -> Bool -> Bool -> [FilePath] -> [FilePath] -> String -> IO LibrarySpec -locateLib hsc_env is_hs lib_dirs gcc_dirs lib +locateLib 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) @@ -1470,7 +1475,7 @@ locateLib 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 diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index d222b3b6de..aed8f0859f 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -647,6 +647,7 @@ data GeneralFlag | Opt_Hpc | Opt_FlatCache | Opt_ExternalInterpreter + | Opt_PreferDynamicLoader | Opt_OptimalApplicativeDo | Opt_VersionMacros | Opt_WholeArchiveHsLibs @@ -4321,7 +4322,8 @@ fFlagsDeps = [ flagSpec "hide-source-paths" Opt_HideSourcePaths, flagSpec "show-loaded-modules" Opt_ShowLoadedModules, flagSpec "whole-archive-hs-libs" Opt_WholeArchiveHsLibs, - flagSpec "keep-cafs" Opt_KeepCAFs + flagSpec "keep-cafs" Opt_KeepCAFs, + flagSpec "prefer-dynamic-loader" Opt_PreferDynamicLoader ] ++ fHoleFlags |