Use dynamic linking only if the GHC package is compiled with -dynamic (#8376)
authorSimon Marlow <marlowsd@gmail.com>
Tue, 8 Oct 2013 15:58:24 +0000 (16:58 +0100)
committerSimon Marlow <marlowsd@gmail.com>
Fri, 11 Oct 2013 09:37:01 +0000 (10:37 +0100)
compiler/ghc.mk
compiler/ghci/Linker.lhs
compiler/main/DynFlags.hs
includes/Rts.h
includes/rts/prof/CCS.h
rts/RtsUtils.c
rts/ghc.mk

index 810b11a..a5a2034 100644 (file)
@@ -111,12 +111,6 @@ ifeq "$(UseLibFFIForAdjustors)" "YES"
 else
        @echo 'cLibFFI               = False'                               >> $@
 endif
-       @echo 'cDYNAMIC_GHC_PROGRAMS :: Bool'                               >> $@
-ifeq "$(DYNAMIC_GHC_PROGRAMS)" "YES"
-       @echo 'cDYNAMIC_GHC_PROGRAMS = True'                                >> $@
-else
-       @echo 'cDYNAMIC_GHC_PROGRAMS = False'                               >> $@
-endif
 # Note that GhcThreaded just reflects the Makefile variable setting.
 # In particular, the stage1 compiler is never actually compiled with
 # -threaded, but it will nevertheless have cGhcThreaded = True.
index edc0db1..62f7a70 100644 (file)
@@ -413,14 +413,14 @@ preloadLib dflags lib_paths framework_paths lib_spec
     preload_static _paths name
        = do b <- doesFileExist name
             if not b then return False
-                     else do if cDYNAMIC_GHC_PROGRAMS
+                     else do if dynamicGhc
                                  then dynLoadObjs dflags [name]
                                  else loadObj name
                              return True
     preload_static_archive _paths name
        = do b <- doesFileExist name
             if not b then return False
-                     else do if cDYNAMIC_GHC_PROGRAMS
+                     else do if dynamicGhc
                                  then panic "Loading archives not supported"
                                  else loadArchive name
                              return True
@@ -496,7 +496,7 @@ checkNonStdWay dflags srcspan =
     -- whereas we have __stginit_base_Prelude_.
       else if objectSuf dflags == normalObjectSuffix && not (null haskellWays)
       then failNonStd dflags srcspan
-      else return $ Just $ if cDYNAMIC_GHC_PROGRAMS
+      else return $ Just $ if dynamicGhc
                            then "dyn_o"
                            else "o"
     where haskellWays = filter (not . wayRTSOnly) (ways dflags)
@@ -509,7 +509,7 @@ failNonStd dflags srcspan = dieWith dflags srcspan $
   ptext (sLit "Dynamic linking required, but this is a non-standard build (eg. prof).") $$
   ptext (sLit "You need to build the program twice: once the") <+> ghciWay <+> ptext (sLit "way, and then") $$
   ptext (sLit "in the desired way using -osuf to set the object file suffix.")
-    where ghciWay = if cDYNAMIC_GHC_PROGRAMS
+    where ghciWay = if dynamicGhc
                     then ptext (sLit "dynamic")
                     else ptext (sLit "normal")
 
@@ -783,7 +783,7 @@ dynLinkObjs dflags pls objs = do
             unlinkeds                = concatMap linkableUnlinked new_objs
             wanted_objs              = map nameOfObject unlinkeds
 
-        if cDYNAMIC_GHC_PROGRAMS
+        if dynamicGhc
             then do dynLoadObjs dflags wanted_objs
                     return (pls1, Succeeded)
             else do mapM_ loadObj wanted_objs
@@ -970,7 +970,7 @@ unload_wkr _ linkables pls
       | linkableInSet lnk keep_linkables = return True
       -- We don't do any cleanup when linking objects with the dynamic linker.
       -- Doing so introduces extra complexity for not much benefit.
-      | cDYNAMIC_GHC_PROGRAMS = return False
+      | dynamicGhc = return False
       | otherwise
       = do mapM_ unloadObj [f | DotO f <- linkableUnlinked lnk]
                 -- The components of a BCO linkable may contain
@@ -1182,7 +1182,7 @@ locateLib dflags is_hs dirs lib
     --
   = findDll `orElse` findArchive `orElse` tryGcc `orElse` assumeDll
 
-  | not cDYNAMIC_GHC_PROGRAMS
+  | not dynamicGhc
     -- When the GHC package was not compiled as dynamic library
     -- (=DYNAMIC not set), we search for .o libraries or, if they
     -- don't exist, .a libraries.
index 0dcad39..522e761 100644 (file)
@@ -117,6 +117,7 @@ module DynFlags (
 -- Only in stage 2 can we be sure that the RTS
 -- exposes the appropriate runtime boolean
         rtsIsProfiled,
+        dynamicGhc,
 #endif
 
 #include "../includes/dist-derivedconstants/header/GHCConstantsHaskellExports.hs"
@@ -166,6 +167,7 @@ import FastString
 import Outputable
 #ifdef GHCI
 import Foreign.C        ( CInt(..) )
+import System.IO.Unsafe ( unsafeDupablePerformIO )
 #endif
 import {-# SOURCE #-} ErrUtils ( Severity(..), MsgDoc, mkLocMessage )
 
@@ -1444,7 +1446,7 @@ defaultWays settings = if pc_DYNAMIC_BY_DEFAULT (sPlatformConstants settings)
                        else []
 
 interpWays :: [Way]
-interpWays = if cDYNAMIC_GHC_PROGRAMS
+interpWays = if dynamicGhc
              then [WayDyn]
              else []
 
@@ -3069,7 +3071,21 @@ glasgowExtsFlags = [
 foreign import ccall unsafe "rts_isProfiled" rtsIsProfiledIO :: IO CInt
 
 rtsIsProfiled :: Bool
-rtsIsProfiled = unsafePerformIO rtsIsProfiledIO /= 0
+rtsIsProfiled = unsafeDupablePerformIO rtsIsProfiledIO /= 0
+#endif
+
+#ifdef GHCI
+-- Consult the RTS to find whether GHC itself has been built with
+-- dynamic linking.  This can't be statically known at compile-time,
+-- because we build both the static and dynamic versions together with
+-- -dynamic-too.
+foreign import ccall unsafe "rts_isDynamic" rtsIsDynamicIO :: IO CInt
+
+dynamicGhc :: Bool
+dynamicGhc = unsafeDupablePerformIO rtsIsDynamicIO /= 0
+#else
+dynamicGhc :: Bool
+dynamicGhc = False
 #endif
 
 setWarnSafe :: Bool -> DynP ()
@@ -3535,7 +3551,7 @@ compilerInfo dflags
        ("Support parallel --make",     "YES"),
        ("Dynamic by default",          if dYNAMIC_BY_DEFAULT dflags
                                        then "YES" else "NO"),
-       ("GHC Dynamic",                 if cDYNAMIC_GHC_PROGRAMS
+       ("GHC Dynamic",                 if dynamicGhc
                                        then "YES" else "NO"),
        ("Leading underscore",          cLeadingUnderscore),
        ("Debug on",                    show debugIsOn),
index 8655514..96dc6a5 100644 (file)
@@ -259,6 +259,16 @@ int stg_sig_install (int, int, void *);
 #endif
 
 /* -----------------------------------------------------------------------------
+   Ways
+   -------------------------------------------------------------------------- */
+
+// Returns non-zero if the RTS is a profiling version
+int rts_isProfiled(void);
+
+// Returns non-zero if the RTS is a dynamically-linked version
+int rts_isDynamic(void);
+
+/* -----------------------------------------------------------------------------
    RTS Exit codes
    -------------------------------------------------------------------------- */
 
index dbd0717..b121b03 100644 (file)
@@ -14,9 +14,6 @@
 #ifndef RTS_PROF_CCS_H
 #define RTS_PROF_CCS_H
 
-// Returns non-zero if the RTS is a profiling version
-int rts_isProfiled(void);
-
 /* -----------------------------------------------------------------------------
  * Data Structures 
  * ---------------------------------------------------------------------------*/  
index cb9002c..b06b6af 100644 (file)
@@ -304,6 +304,17 @@ int rts_isProfiled(void)
 #endif
 }
 
+// Provides a way for Haskell programs to tell whether they're
+// dynamically-linked or not.
+int rts_isDynamic(void)
+{
+#ifdef DYNAMIC
+    return 1;
+#else
+    return 0;
+#endif
+}
+
 // Used for detecting a non-empty FPU stack on x86 (see #4914)
 void checkFPUStack(void)
 {
index 401fe21..9f36811 100644 (file)
@@ -139,6 +139,7 @@ ifneq "$$(findstring dyn, $1)" ""
 ifeq "$$(HostOS_CPP)" "mingw32" 
 rts_dist_$1_CC_OPTS += -DCOMPILING_WINDOWS_DLL
 endif
+rts_dist_$1_CC_OPTS += -DDYNAMIC
 endif
 
 ifneq "$$(findstring thr, $1)" ""