[project @ 2001-08-17 12:56:55 by simonmar]
[ghc-hetmet.git] / ghc / compiler / main / SysTools.lhs
index adc8e0c..e3df000 100644 (file)
@@ -1,7 +1,9 @@
 -----------------------------------------------------------------------------
--- Access to system tools: gcc, cp, rm etc
+-- $Id: SysTools.lhs,v 1.54 2001/08/17 12:43:24 sewardj Exp $
+--
+-- (c) The University of Glasgow 2001
 --
--- (c) The University of Glasgow 2000
+-- Access to system tools: gcc, cp, rm etc
 --
 -----------------------------------------------------------------------------
 
@@ -13,14 +15,18 @@ module SysTools (
                                -- Command-line override
        setDryRun,
 
-       packageConfigPath,      -- IO String    
-                               -- Where package.conf is
+       getTopDir,              -- IO String    -- The value of $libdir
+       getPackageConfigPath,   -- IO String    -- Where package.conf is
 
        -- Interface to system tools
        runUnlit, runCpp, runCc, -- [Option] -> IO ()
        runMangle, runSplit,     -- [Option] -> IO ()
        runAs, runLink,          -- [Option] -> IO ()
        runMkDLL,
+#ifdef ILX
+        runIlx2il, runIlasm,     -- [String] -> IO ()
+#endif
+
 
        touch,                  -- String -> String -> IO ()
        copy,                   -- String -> String -> String -> IO ()
@@ -68,7 +74,21 @@ import qualified Posix
 #else
 import List            ( isPrefixOf )
 import MarshalArray
-import SystemExts       ( rawSystem )
+#endif
+
+-- This is a kludge for bootstrapping with 4.08.X.  Given that
+-- all distributed compilers >= 5.0 will be compiled with themselves.
+-- I don't think this kludge is a problem.  And we have to start
+-- building with >= 5.0 on Win32 anyway.
+#if __GLASGOW_HASKELL__ > 408
+-- use the line below when we can be sure of compiling with GHC >=
+-- 5.02, and remove the implementation of rawSystem at the end of this
+-- file
+import PrelIOBase -- this can be removed when SystemExts is used
+import CError     ( throwErrnoIfMinus1 ) -- as can this
+-- import SystemExts       ( rawSystem )
+#else
+import System          ( system )
 #endif
 
 #include "HsVersions.h"
@@ -154,6 +174,10 @@ GLOBAL_VAR(v_Pgm_c,        error "pgm_c",   String)        -- gcc
 GLOBAL_VAR(v_Pgm_m,    error "pgm_m",   String)        -- asm code mangler
 GLOBAL_VAR(v_Pgm_s,    error "pgm_s",   String)        -- asm code splitter
 GLOBAL_VAR(v_Pgm_a,    error "pgm_a",   String)        -- as
+#ifdef ILX
+GLOBAL_VAR(v_Pgm_I,     error "pgm_I",   String)        -- ilx2il
+GLOBAL_VAR(v_Pgm_i,     error "pgm_i",   String)        -- ilasm
+#endif
 GLOBAL_VAR(v_Pgm_l,    error "pgm_l",   String)        -- ld
 GLOBAL_VAR(v_Pgm_MkDLL, error "pgm_dll", String)       -- mkdll
 
@@ -163,8 +187,14 @@ GLOBAL_VAR(v_Pgm_CP,   error "pgm_CP",      String)        -- cp
 GLOBAL_VAR(v_Path_package_config, error "path_package_config", String)
 GLOBAL_VAR(v_Path_usage,         error "ghc_usage.txt",       String)
 
+GLOBAL_VAR(v_TopDir,   error "TopDir", String)         -- -B<dir>
+
 -- Parallel system only
 GLOBAL_VAR(v_Pgm_sysman, error "pgm_sysman", String)   -- system manager
+
+-- ways to get at some of these variables from outside this module
+getPackageConfigPath = readIORef v_Path_package_config
+getTopDir           = readIORef v_TopDir
 \end{code}
 
 
@@ -177,15 +207,15 @@ GLOBAL_VAR(v_Pgm_sysman, error "pgm_sysman", String)      -- system manager
 \begin{code}
 initSysTools :: [String]       -- Command-line arguments starting "-B"
 
-            -> IO String       -- Set all the mutable variables above, holding 
+            -> IO ()           -- Set all the mutable variables above, holding 
                                --      (a) the system programs
                                --      (b) the package-config file
                                --      (c) the GHC usage message
-                               -- Return TopDir
 
 
 initSysTools minusB_args
-  = do  { (am_installed, top_dir) <- getTopDir minusB_args
+  = do  { (am_installed, top_dir) <- findTopDir minusB_args
+       ; writeIORef v_TopDir top_dir
                -- top_dir
                --      for "installed" this is the root of GHC's support files
                --      for "in-place" it is the root of the build tree
@@ -299,6 +329,11 @@ initSysTools minusB_args
        ; let   as_path  = gcc_path
                ld_path  = gcc_path
 
+#ifdef ILX
+       -- ilx2il and ilasm are specified in Config.hs
+       ; let    ilx2il_path = cILX2IL
+               ilasm_path  = cILASM
+#endif
                                       
        -- Initialise the global vars
        ; writeIORef v_Path_package_config pkgconfig_path
@@ -314,18 +349,22 @@ initSysTools minusB_args
        ; writeIORef v_Pgm_m               mangle_path
        ; writeIORef v_Pgm_s               split_path
        ; writeIORef v_Pgm_a               as_path
+#ifdef ILX
+       ; writeIORef v_Pgm_I               ilx2il_path
+       ; writeIORef v_Pgm_i               ilasm_path
+#endif
        ; writeIORef v_Pgm_l               ld_path
        ; writeIORef v_Pgm_MkDLL           mkdll_path
        ; writeIORef v_Pgm_T               touch_path
        ; writeIORef v_Pgm_CP              cp_path
 
-       ; return top_dir
+       ; return ()
        }
 \end{code}
 
 setPgm is called when a command-line option like
        -pgmLld
-is used to override a particular program with a new onw
+is used to override a particular program with a new one
 
 \begin{code}
 setPgm :: String -> IO ()
@@ -338,6 +377,10 @@ setPgm ('m' : pgm) = writeIORef v_Pgm_m pgm
 setPgm ('s' : pgm) = writeIORef v_Pgm_s pgm
 setPgm ('a' : pgm) = writeIORef v_Pgm_a pgm
 setPgm ('l' : pgm) = writeIORef v_Pgm_l pgm
+#ifdef ILX
+setPgm ('I' : pgm) = writeIORef v_Pgm_I pgm
+setPgm ('i' : pgm) = writeIORef v_Pgm_i pgm
+#endif
 setPgm pgm        = unknownFlagErr ("-pgm" ++ pgm)
 \end{code}
 
@@ -362,11 +405,11 @@ setPgm pgm           = unknownFlagErr ("-pgm" ++ pgm)
 --
 -- This is very gruesome indeed
 
-getTopDir :: [String]
+findTopDir :: [String]
          -> IO (Bool,          -- True <=> am installed, False <=> in-place
                 String)        -- TopDir (in Unix format '/' separated)
 
-getTopDir minusbs
+findTopDir minusbs
   = do { top_dir <- get_proto
         -- Discover whether we're running in a build tree or in an installation,
        -- by looking for the package configuration file.
@@ -459,6 +502,16 @@ runLink :: [Option] -> IO ()
 runLink args = do p <- readIORef v_Pgm_l
                  runSomething "Linker" p args
 
+#ifdef ILX
+runIlx2il :: [Option] -> IO ()
+runIlx2il args = do p <- readIORef v_Pgm_I
+                   runSomething "Ilx2Il" p args
+
+runIlasm :: [Option] -> IO ()
+runIlasm args = do p <- readIORef v_Pgm_i
+                  runSomething "Ilasm" p args
+#endif
+
 runMkDLL :: [Option] -> IO ()
 runMkDLL args = do p <- readIORef v_Pgm_MkDLL
                   runSomething "Make DLL" p args
@@ -502,8 +555,6 @@ showGhcUsage = do { usage_path <- readIORef v_Path_usage
      dump ""         = return ()
      dump ('$':'$':s) = hPutStr stderr progName >> dump s
      dump (c:s)              = hPutChar stderr c >> dump s
-
-packageConfigPath = readIORef v_Path_package_config
 \end{code}
 
 
@@ -753,4 +804,21 @@ foreign import "_getpid" getProcessID :: IO Int -- relies on Int == Int32 on Win
 getProcessID :: IO Int
 getProcessID = Posix.getProcessID
 #endif
+
+rawSystem :: String -> IO ExitCode
+#if __GLASGOW_HASKELL__ > 408
+rawSystem "" = ioException (IOError Nothing InvalidArgument "rawSystem" "null command" Nothing)
+rawSystem cmd =
+  withCString cmd $ \s -> do
+    status <- throwErrnoIfMinus1 "rawSystem" (primRawSystem s)
+    case status of
+        0  -> return ExitSuccess
+        n  -> return (ExitFailure n)
+
+foreign import ccall "rawSystemCmd" unsafe primRawSystem :: CString -> IO Int
+#else
+rawSystem = System.system
+#endif
+
+
 \end{code}