X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Fmain%2FSysTools.lhs;h=fcd62defa769fd971b2edab662cbd434798a3e4d;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=48fcd4f0f90f1cabac6ff078f7348ffe87284a7e;hpb=948e7f388748078a8d9a324b284da7c4029f7060;p=ghc-hetmet.git
diff --git a/ghc/compiler/main/SysTools.lhs b/ghc/compiler/main/SysTools.lhs
index 48fcd4f..fcd62de 100644
--- a/ghc/compiler/main/SysTools.lhs
+++ b/ghc/compiler/main/SysTools.lhs
@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
--
--- (c) The University of Glasgow 2001
+-- (c) The University of Glasgow 2001-2003
--
-- Access to system tools: gcc, cp, rm etc
--
@@ -19,6 +19,7 @@ module SysTools (
setPgms,
setPgma,
setPgml,
+ setPgmDLL,
#ifdef ILX
setPgmI,
setPgmi,
@@ -28,6 +29,7 @@ module SysTools (
getTopDir, -- IO String -- The value of $libdir
getPackageConfigPath, -- IO String -- Where package.conf is
+ getUsageMsgPaths, -- IO (String,String)
-- Interface to system tools
runUnlit, runCpp, runCc, -- [Option] -> IO ()
@@ -47,15 +49,13 @@ module SysTools (
-- Temporary-file management
setTmpDir,
newTempName,
- cleanTempFiles, cleanTempFilesExcept, removeTmpFiles,
+ cleanTempFiles, cleanTempFilesExcept,
addFilesToClean,
-- System interface
- getProcessID, -- IO Int
system, -- String -> IO ExitCode
-- Misc
- showGhcUsage, -- IO () Shows usage message and exits
getSysMan, -- IO String Parallel system only
Option(..)
@@ -68,8 +68,8 @@ import DriverUtil
import DriverPhases ( isHaskellUserSrcFilename )
import Config
import Outputable
-import Panic ( progName, GhcException(..) )
-import Util ( global, notNull )
+import Panic ( GhcException(..) )
+import Util ( global, notNull, toArgs )
import CmdLineOpts ( dynFlag, verbosity )
import EXCEPTION ( throwDyn )
@@ -77,14 +77,14 @@ import DATA_IOREF ( IORef, readIORef, writeIORef )
import DATA_INT
import Monad ( when, unless )
-import System ( ExitCode(..), exitWith, getEnv, system )
+import System ( ExitCode(..), getEnv, system )
import IO ( try, catch,
- openFile, hPutChar, hPutStrLn, hPutStr, hClose, hFlush, IOMode(..),
+ openFile, hPutStrLn, hPutStr, hClose, hFlush, IOMode(..),
stderr )
import Directory ( doesFileExist, removeFile )
-import List ( intersperse, partition )
+import List ( partition )
-#include "../includes/config.h"
+#include "../includes/ghcconfig.h"
-- GHC <= 4.08 didn't have rawSystem, and runs into problems with long command
-- lines on mingw32, so we disallow it now.
@@ -105,7 +105,7 @@ import Foreign
import CString ( CString, peekCString )
#endif
-#if __GLASGOW_HASKELL__ < 601
+#if __GLASGOW_HASKELL__ < 603
import Foreign ( withMany, withArray0, nullPtr, Ptr )
import CForeign ( CString, withCString, throwErrnoIfMinus1 )
#else
@@ -189,22 +189,22 @@ All these pathnames are maintained IN THE NATIVE FORMAT OF THE HOST MACHINE.
GLOBAL_VAR(v_Pgm_L, error "pgm_L", String) -- unlit
GLOBAL_VAR(v_Pgm_P, error "pgm_P", (String,[Option])) -- cpp
GLOBAL_VAR(v_Pgm_F, error "pgm_F", String) -- pp
-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
+GLOBAL_VAR(v_Pgm_c, error "pgm_c", (String,[Option])) -- gcc
+GLOBAL_VAR(v_Pgm_m, error "pgm_m", (String,[Option])) -- asm code mangler
+GLOBAL_VAR(v_Pgm_s, error "pgm_s", (String,[Option])) -- asm code splitter
+GLOBAL_VAR(v_Pgm_a, error "pgm_a", (String,[Option])) -- 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
+GLOBAL_VAR(v_Pgm_l, error "pgm_l", (String,[Option])) -- ld
+GLOBAL_VAR(v_Pgm_MkDLL, error "pgm_dll", (String,[Option])) -- mkdll
GLOBAL_VAR(v_Pgm_T, error "pgm_T", String) -- touch
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_Path_usages, error "ghc_usage.txt", (String,String))
GLOBAL_VAR(v_TopDir, error "TopDir", String) -- -B
@@ -254,6 +254,10 @@ initSysTools minusB_args
| am_installed = installed "ghc-usage.txt"
| otherwise = inplace cGHC_DRIVER_DIR_REL "ghc-usage.txt"
+ ghci_usage_msg_path
+ | am_installed = installed "ghci-usage.txt"
+ | otherwise = inplace cGHC_DRIVER_DIR_REL "ghci-usage.txt"
+
-- For all systems, unlit, split, mangle are GHC utilities
-- architecture-specific stuff is done when building Config.hs
unlit_path
@@ -316,16 +320,20 @@ initSysTools minusB_args
-- pick up whatever happens to be lying around in the path,
-- possibly including those from a cygwin install on the target,
-- which is exactly what we're trying to avoid.
- ; let gcc_path | am_installed = installed_bin ("gcc -B\"" ++ installed "gcc-lib/\"")
- | otherwise = cGCC
+ ; let gcc_b_arg = Option ("-B" ++ installed "gcc-lib/")
+ (gcc_prog,gcc_args)
+ | am_installed = (installed_bin "gcc", [gcc_b_arg])
+ | otherwise = (cGCC, [])
-- The trailing "/" is absolutely essential; gcc seems
- -- to construct file names simply by concatenating to this
- -- -B path with no extra slash
- -- We use "/" rather than "\\" because otherwise "\\\" is mangled
- -- later on; although gcc_path is in NATIVE format, gcc can cope
+ -- to construct file names simply by concatenating to
+ -- this -B path with no extra slash We use "/" rather
+ -- than "\\" because otherwise "\\\" is mangled
+ -- later on; although gcc_args are in NATIVE format,
+ -- gcc can cope
-- (see comments with declarations of global variables)
--
- -- The quotes round the -B argument are in case TopDir has spaces in it
+ -- The quotes round the -B argument are in case TopDir
+ -- has spaces in it
perl_path | am_installed = installed_bin cGHC_PERL
| otherwise = cGHC_PERL
@@ -336,43 +344,49 @@ initSysTools minusB_args
-- On Win32 we don't want to rely on #!/bin/perl, so we prepend
-- a call to Perl to get the invocation of split and mangle
- ; let split_path = perl_path ++ " \"" ++ split_script ++ "\""
- mangle_path = perl_path ++ " \"" ++ mangle_script ++ "\""
-
- ; let mkdll_path
- | am_installed = pgmPath (installed "gcc-lib/") cMKDLL ++
- " --dlltool-name " ++ pgmPath (installed "gcc-lib/") "dlltool" ++
- " --driver-name " ++ gcc_path
- | otherwise = cMKDLL
+ ; let (split_prog, split_args) = (perl_path, [Option split_script])
+ (mangle_prog, mangle_args) = (perl_path, [Option mangle_script])
+
+ ; let (mkdll_prog, mkdll_args)
+ | am_installed =
+ (pgmPath (installed "gcc-lib/") cMKDLL,
+ [ Option "--dlltool-name",
+ Option (pgmPath (installed "gcc-lib/") "dlltool"),
+ Option "--driver-name",
+ Option gcc_prog, gcc_b_arg ])
+ | otherwise = (cMKDLL, [])
#else
-- UNIX-SPECIFIC STUFF
-- On Unix, the "standard" tools are assumed to be
-- in the same place whether we are running "in-place" or "installed"
-- That place is wherever the build-time configure script found them.
- ; let gcc_path = cGCC
+ ; let gcc_prog = cGCC
+ gcc_args = []
touch_path = "touch"
- mkdll_path = panic "Can't build DLLs on a non-Win32 system"
+ mkdll_prog = panic "Can't build DLLs on a non-Win32 system"
+ mkdll_args = []
-- On Unix, scripts are invoked using the '#!' method. Binary
-- installations of GHC on Unix place the correct line on the front
-- of the script at installation time, so we don't want to wire-in
-- our knowledge of $(PERL) on the host system here.
- ; let split_path = split_script
- mangle_path = mangle_script
+ ; let (split_prog, split_args) = (split_script, [])
+ (mangle_prog, mangle_args) = (mangle_script, [])
#endif
-- cpp is derived from gcc on all platforms
-- HACK, see setPgmP below. We keep 'words' here to remember to fix
-- Config.hs one day.
- ; let cpp_path = (gcc_path, (Option "-E"):(map Option (words cRAWCPP_FLAGS)))
+ ; let cpp_path = (gcc_prog, gcc_args ++
+ (Option "-E"):(map Option (words cRAWCPP_FLAGS)))
-- For all systems, copy and remove are provided by the host
-- system; architecture-specific stuff is done when building Config.hs
; let cp_path = cGHC_CP
-- Other things being equal, as and ld are simply gcc
- ; let as_path = gcc_path
- ld_path = gcc_path
+ ; let (as_prog,as_args) = (gcc_prog,gcc_args)
+ (ld_prog,ld_args) = (gcc_prog,gcc_args)
#ifdef ILX
-- ilx2il and ilasm are specified in Config.hs
@@ -382,7 +396,8 @@ initSysTools minusB_args
-- Initialise the global vars
; writeIORef v_Path_package_config pkgconfig_path
- ; writeIORef v_Path_usage ghc_usage_msg_path
+ ; writeIORef v_Path_usages (ghc_usage_msg_path,
+ ghci_usage_msg_path)
; writeIORef v_Pgm_sysman (top_dir ++ "/ghc/rts/parallel/SysMan")
-- Hans: this isn't right in general, but you can
@@ -391,16 +406,16 @@ initSysTools minusB_args
; writeIORef v_Pgm_L unlit_path
; writeIORef v_Pgm_P cpp_path
; writeIORef v_Pgm_F ""
- ; writeIORef v_Pgm_c gcc_path
- ; writeIORef v_Pgm_m mangle_path
- ; writeIORef v_Pgm_s split_path
- ; writeIORef v_Pgm_a as_path
+ ; writeIORef v_Pgm_c (gcc_prog,gcc_args)
+ ; writeIORef v_Pgm_m (mangle_prog,mangle_args)
+ ; writeIORef v_Pgm_s (split_prog,split_args)
+ ; writeIORef v_Pgm_a (as_prog,as_args)
#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_l (ld_prog,ld_args)
+ ; writeIORef v_Pgm_MkDLL (mkdll_prog,mkdll_args)
; writeIORef v_Pgm_T touch_path
; writeIORef v_Pgm_CP cp_path
@@ -425,11 +440,12 @@ setPgmL = writeIORef v_Pgm_L
-- Config.hs should really use Option.
setPgmP arg = let (pgm:args) = words arg in writeIORef v_Pgm_P (pgm,map Option args)
setPgmF = writeIORef v_Pgm_F
-setPgmc = writeIORef v_Pgm_c
-setPgmm = writeIORef v_Pgm_m
-setPgms = writeIORef v_Pgm_s
-setPgma = writeIORef v_Pgm_a
-setPgml = writeIORef v_Pgm_l
+setPgmc prog = writeIORef v_Pgm_c (prog,[])
+setPgmm prog = writeIORef v_Pgm_m (prog,[])
+setPgms prog = writeIORef v_Pgm_s (prog,[])
+setPgma prog = writeIORef v_Pgm_a (prog,[])
+setPgml prog = writeIORef v_Pgm_l (prog,[])
+setPgmDLL prog = writeIORef v_Pgm_MkDLL (prog,[])
#ifdef ILX
setPgmI = writeIORef v_Pgm_I
setPgmi = writeIORef v_Pgm_i
@@ -531,24 +547,24 @@ runPp args = do p <- readIORef v_Pgm_F
runSomething "Haskell pre-processor" p args
runCc :: [Option] -> IO ()
-runCc args = do p <- readIORef v_Pgm_c
- runSomething "C Compiler" p args
+runCc args = do (p,args0) <- readIORef v_Pgm_c
+ runSomething "C Compiler" p (args0++args)
runMangle :: [Option] -> IO ()
-runMangle args = do p <- readIORef v_Pgm_m
- runSomething "Mangler" p args
+runMangle args = do (p,args0) <- readIORef v_Pgm_m
+ runSomething "Mangler" p (args0++args)
runSplit :: [Option] -> IO ()
-runSplit args = do p <- readIORef v_Pgm_s
- runSomething "Splitter" p args
+runSplit args = do (p,args0) <- readIORef v_Pgm_s
+ runSomething "Splitter" p (args0++args)
runAs :: [Option] -> IO ()
-runAs args = do p <- readIORef v_Pgm_a
- runSomething "Assembler" p args
+runAs args = do (p,args0) <- readIORef v_Pgm_a
+ runSomething "Assembler" p (args0++args)
runLink :: [Option] -> IO ()
-runLink args = do p <- readIORef v_Pgm_l
- runSomething "Linker" p args
+runLink args = do (p,args0) <- readIORef v_Pgm_l
+ runSomething "Linker" p (args0++args)
#ifdef ILX
runIlx2il :: [Option] -> IO ()
@@ -561,8 +577,8 @@ runIlasm args = do p <- readIORef v_Pgm_i
#endif
runMkDLL :: [Option] -> IO ()
-runMkDLL args = do p <- readIORef v_Pgm_MkDLL
- runSomething "Make DLL" p args
+runMkDLL args = do (p,args0) <- readIORef v_Pgm_MkDLL
+ runSomething "Make DLL" p (args0++args)
touch :: String -> String -> IO ()
touch purpose arg = do p <- readIORef v_Pgm_T
@@ -586,23 +602,10 @@ getSysMan :: IO String -- How to invoke the system manager
getSysMan = readIORef v_Pgm_sysman
\end{code}
-%************************************************************************
-%* *
-\subsection{GHC Usage message}
-%* *
-%************************************************************************
-
-Show the usage message and exit
-
\begin{code}
-showGhcUsage = do { usage_path <- readIORef v_Path_usage
- ; usage <- readFile usage_path
- ; dump usage
- ; exitWith ExitSuccess }
- where
- dump "" = return ()
- dump ('$':'$':s) = hPutStr stderr progName >> dump s
- dump (c:s) = hPutChar stderr c >> dump s
+getUsageMsgPaths :: IO (FilePath,FilePath)
+ -- the filenames of the usage messages (ghc, ghci)
+getUsageMsgPaths = readIORef v_Path_usages
\end{code}
@@ -736,7 +739,7 @@ runSomething :: String -- For -v message
runSomething phase_name pgm args = do
let real_args = filter notNull (map showOpt args)
- traceCmd phase_name (concat (intersperse " " (pgm:real_args))) $ do
+ traceCmd phase_name (unwords (pgm:real_args)) $ do
exit_code <- rawSystem pgm real_args
if (exit_code /= ExitSuccess)
then throwDyn (PhaseFailed phase_name exit_code)
@@ -765,53 +768,14 @@ traceCmd phase_name cmd_line action
-- -----------------------------------------------------------------------------
-- rawSystem: run an external command
+--
+-- In GHC 6.2.1 there's a correct implementation of rawSystem in the
+-- library System.Cmd. If we are compiling with an earlier version of
+-- GHC than this, we'd better have a copy of the correct implementation
+-- right here.
-#if __GLASGOW_HASKELL__ < 601
-
--- This code is copied from System.Cmd on GHC 6.1.
-
-rawSystem :: FilePath -> [String] -> IO ExitCode
-
-#ifndef mingw32_TARGET_OS
-
-rawSystem cmd args =
- withCString cmd $ \pcmd ->
- withMany withCString (cmd:args) $ \cstrs ->
- withArray0 nullPtr cstrs $ \arr -> do
- status <- throwErrnoIfMinus1 "rawSystem" (c_rawSystem pcmd arr)
- case status of
- 0 -> return ExitSuccess
- n -> return (ExitFailure n)
-
-foreign import ccall "rawSystem" unsafe
- c_rawSystem :: CString -> Ptr CString -> IO Int
-
-#else
-
--- On Windows, the command line is passed to the operating system as
--- a single string. Command-line parsing is done by the executable
--- itself.
-rawSystem cmd args = do
- let cmdline = {-translate-} cmd ++ concat (map ((' ':) . translate) args)
- -- Urk, don't quote/escape the command name on Windows, because the
- -- compiler is exceedingly naughty and sometimes uses 'perl "..."'
- -- as the command name.
- withCString cmdline $ \pcmdline -> do
- status <- throwErrnoIfMinus1 "rawSystem" (c_rawSystem pcmdline)
- case status of
- 0 -> return ExitSuccess
- n -> return (ExitFailure n)
-
-translate :: String -> String
-translate str = '"' : foldr escape "\"" str
- where escape '"' str = '\\' : '"' : str
- escape '\\' str = '\\' : '\\' : str
- escape c str = c : str
-
-foreign import ccall "rawSystem" unsafe
- c_rawSystem :: CString -> IO Int
-
-#endif
+#if __GLASGOW_HASKELL__ < 603
+#include "../../libraries/base/System/RawSystem.hs-inc"
#endif
\end{code}
@@ -868,13 +832,6 @@ platformPath stuff = stuff
\begin{code}
slash :: String -> String -> String
-absPath, relPath :: [String] -> String
-
-relPath [] = ""
-relPath xs = foldr1 slash xs
-
-absPath xs = "" `slash` relPath xs
-
slash s1 s2 = s1 ++ ('/' : s2)
\end{code}