Add the ability to :set -l{foo} in ghci, fix #1407.
authorarchblob <fcsernik@gmail.com>
Tue, 16 Sep 2014 12:56:09 +0000 (07:56 -0500)
committerAustin Seipp <austin@well-typed.com>
Tue, 16 Sep 2014 12:56:09 +0000 (07:56 -0500)
Summary:
The dynamic linking code was already there but it was not called
on flag changes in ghci.

Test Plan: validate

Reviewers: hvr, simonmar, austin

Reviewed By: austin

Subscribers: simonmar, ezyang, carter

Differential Revision: https://phabricator.haskell.org/D194

GHC Trac Issues: #1407

compiler/ghci/Linker.lhs
ghc/InteractiveUI.hs
testsuite/tests/ghci/linking/T1407.script [new file with mode: 0644]
testsuite/tests/ghci/linking/all.T

index 3169858..5b0251c 100644 (file)
@@ -17,6 +17,7 @@ module Linker ( getHValue, showLinkerState,
                 extendLinkEnv, deleteFromLinkEnv,
                 extendLoadedPkgs,
                 linkPackages,initDynLinker,linkModule,
+                linkCmdLineLibs,
 
                 -- Saving/restoring globals
                 PersistentLinkerState, saveLinkerGlobals, restoreLinkerGlobals
@@ -283,10 +284,21 @@ reallyInitDynLinker dflags =
           -- (b) Load packages from the command-line (Note [preload packages])
         ; pls <- linkPackages' dflags (preloadPackages (pkgState dflags)) pls0
 
-          -- (c) Link libraries from the command-line
-        ; let cmdline_ld_inputs = ldInputs dflags
+          -- steps (c), (d) and (e)
+        ; linkCmdLineLibs' dflags pls
+        }
+
+linkCmdLineLibs :: DynFlags -> IO ()
+linkCmdLineLibs dflags = do
+  initDynLinker dflags
+  modifyPLS_ $ \pls -> do
+    linkCmdLineLibs' dflags pls
+
+linkCmdLineLibs' :: DynFlags -> PersistentLinkerState -> IO PersistentLinkerState
+linkCmdLineLibs' dflags@(DynFlags { ldInputs     = cmdline_ld_inputs
+                                  , libraryPaths = lib_paths}) pls =
+  do  {   -- (c) Link libraries from the command-line
         ; let minus_ls = [ lib | Option ('-':'l':lib) <- cmdline_ld_inputs ]
-        ; let lib_paths = libraryPaths dflags
         ; libspecs <- mapM (locateLib dflags False lib_paths) minus_ls
 
           -- (d) Link .o files from the command-line
@@ -295,12 +307,11 @@ reallyInitDynLinker dflags =
 
           -- (e) Link any MacOS frameworks
         ; let platform = targetPlatform dflags
-        ; let framework_paths = if platformUsesFrameworks platform
-                                then frameworkPaths dflags
-                                else []
-        ; let frameworks = if platformUsesFrameworks platform
-                           then cmdlineFrameworks dflags
-                           else []
+        ; let (framework_paths, frameworks) =
+                if platformUsesFrameworks platform
+                 then (frameworkPaths dflags, cmdlineFrameworks dflags)
+                  else ([],[])
+
           -- Finally do (c),(d),(e)
         ; let cmdline_lib_specs = [ l | Just l <- classified_ld_inputs ]
                                ++ libspecs
index ea90280..0bcecd3 100644 (file)
@@ -2146,6 +2146,17 @@ newDynFlags interactive_only minus_opts = do
                      , pkgDatabase = pkgDatabase dflags2
                      , packageFlags = packageFlags dflags2 }
 
+        let ld0length   = length $ ldInputs dflags0
+            fmrk0length = length $ cmdlineFrameworks dflags0
+
+            newLdInputs     = drop ld0length (ldInputs dflags2)
+            newCLFrameworks = drop fmrk0length (cmdlineFrameworks dflags2)
+
+        when (not (null newLdInputs && null newCLFrameworks)) $
+          liftIO $ linkCmdLineLibs $
+            dflags2 { ldInputs = newLdInputs
+                    , cmdlineFrameworks = newCLFrameworks }
+
       return ()
 
 
diff --git a/testsuite/tests/ghci/linking/T1407.script b/testsuite/tests/ghci/linking/T1407.script
new file mode 100644 (file)
index 0000000..9716435
--- /dev/null
@@ -0,0 +1,4 @@
+:set -ldl
+import Foreign
+import Foreign.C.String
+foreign import ccall "dlerror" dle :: IO CString
index eba2b8a..6675a53 100644 (file)
@@ -47,3 +47,5 @@ test('T3333',
      unless(opsys('linux') or ghci_dynamic(), expect_broken(3333))],
      run_command,
      ['$MAKE -s --no-print-directory T3333'])
+
+test('T1407', normal, ghci_script, ['T1407.script'])