Skip to content

Commit 39ce701

Browse files
authored
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.
1 parent e48cdf3 commit 39ce701

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

ghcide/session-loader/Development/IDE/Session.hs

+18
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import System.Info
5656
import System.IO
5757

5858
import GHC
59+
import GHCi
5960
import DynFlags
6061
import HscTypes
6162
import Linker
@@ -179,6 +180,23 @@ loadSession dir = do
179180
-> IO ([NormalizedFilePath],(IdeResult HscEnvEq,[FilePath]))
180181
session args@(hieYaml, _cfp, _opts, _libDir) = do
181182
(hscEnv, new, old_deps) <- packageSetup args
183+
184+
-- Whenever we spin up a session on Linux, dynamically load libm.so.6
185+
-- in. We need this in case the binary is statically linked, in which
186+
-- case the interactive session will fail when trying to load
187+
-- ghc-prim, which happens whenever Template Haskell is being
188+
-- evaluated or haskell-language-server's eval plugin tries to run
189+
-- some code. If the binary is dynamically linked, then this will have
190+
-- no effect.
191+
-- See https://github.com/haskell/haskell-language-server/issues/221
192+
when (os == "linux") $ do
193+
initObjLinker hscEnv
194+
res <- loadDLL hscEnv "libm.so.6"
195+
case res of
196+
Nothing -> pure ()
197+
Just err -> hPutStrLn stderr $
198+
"Error dynamically loading libm.so.6:\n" <> err
199+
182200
-- Make a map from unit-id to DynFlags, this is used when trying to
183201
-- resolve imports. (especially PackageImports)
184202
let uids = map (\ci -> (componentUnitId ci, componentDynFlags ci)) (new : old_deps)

0 commit comments

Comments
 (0)