From 212495a4473e58bcee198d0c02ac52fb388cab9e Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Thu, 3 Sep 2020 05:34:47 +0100 Subject: [PATCH] Dynamically load libm on Linux for each new session (haskell/ghcide#723) This fixes the issue on Linux where the binary was statically linked and Template Haskell (or the eval plugin on haskell-language-server) tried to evaluate some code. It would previously fail to load ghc-prim because it couldn't lookup symbols from libm which are usually dynamically linked in. --- session-loader/Development/IDE/Session.hs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/session-loader/Development/IDE/Session.hs b/session-loader/Development/IDE/Session.hs index 9dce581537..5cd887ae2c 100644 --- a/session-loader/Development/IDE/Session.hs +++ b/session-loader/Development/IDE/Session.hs @@ -56,6 +56,7 @@ import System.Info import System.IO import GHC +import GHCi import DynFlags import HscTypes import Linker @@ -179,6 +180,23 @@ loadSession dir = do -> IO ([NormalizedFilePath],(IdeResult HscEnvEq,[FilePath])) session args@(hieYaml, _cfp, _opts, _libDir) = do (hscEnv, new, old_deps) <- packageSetup args + + -- Whenever we spin up a session on Linux, dynamically load libm.so.6 + -- in. We need this in case the binary is statically linked, in which + -- case the interactive session will fail when trying to load + -- ghc-prim, which happens whenever Template Haskell is being + -- evaluated or haskell-language-server's eval plugin tries to run + -- some code. If the binary is dynamically linked, then this will have + -- no effect. + -- See https://github.com/haskell/haskell-language-server/issues/221 + when (os == "linux") $ do + initObjLinker hscEnv + res <- loadDLL hscEnv "libm.so.6" + case res of + Nothing -> pure () + Just err -> hPutStrLn stderr $ + "Error dynamically loading libm.so.6:\n" <> err + -- Make a map from unit-id to DynFlags, this is used when trying to -- resolve imports. (especially PackageImports) let uids = map (\ci -> (componentUnitId ci, componentDynFlags ci)) (new : old_deps)