summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-03-02 17:05:05 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-03-02 17:05:05 +0000
commitec968a32e9b02c230dfcbff9660c3e61900d8235 (patch)
tree426b4bfe1fc37c9905f59ab0c5e62097358eabfe /ghc
parent1187e57fab2b5904a808ac973e5d04b91f880920 (diff)
downloadhaskell-ec968a32e9b02c230dfcbff9660c3e61900d8235.tar.gz
Make -split-objs work with --make
This turned out to be a lot easier than I thought. Just moving a few bits of -split-objs support from the build system into the compiler was enough. The only thing that Cabal needs to do in order to support -split-objs now is to pass the names of the split objects rather than the monolithic ones to 'ar'.
Diffstat (limited to 'ghc')
-rw-r--r--ghc/compiler/Makefile2
-rw-r--r--ghc/compiler/main/DriverPhases.hs1
-rw-r--r--ghc/compiler/main/DriverPipeline.hs69
3 files changed, 53 insertions, 19 deletions
diff --git a/ghc/compiler/Makefile b/ghc/compiler/Makefile
index 0c877ce431..1a9b428483 100644
--- a/ghc/compiler/Makefile
+++ b/ghc/compiler/Makefile
@@ -216,6 +216,8 @@ $(CONFIG_HS) : $(FPTOOLS_TOP)/mk/config.mk Makefile
@echo "cRAWCPP_FLAGS = \"$(RAWCPP_FLAGS)\"" >> $(CONFIG_HS)
@echo "cGCC = \"$(WhatGccIsCalled)\"" >> $(CONFIG_HS)
@echo "cMKDLL = \"$(BLD_DLL)\"" >> $(CONFIG_HS)
+ @echo "cLdIsGNULd = \"$(LdIsGNULd)\"" >> $(CONFIG_HS)
+ @echo "cLD_X = \"$(LD_X)\"" >> $(CONFIG_HS)
@echo "cPROJECT_DIR = \"$(PROJECT_DIR)\"" >> $(CONFIG_HS)
@echo "cGHC_DRIVER_DIR_REL = \"$(GHC_DRIVER_DIR_REL)\"" >> $(CONFIG_HS)
@echo "cGHC_TOUCHY_PGM = \"$(GHC_TOUCHY_PGM)\"" >> $(CONFIG_HS)
diff --git a/ghc/compiler/main/DriverPhases.hs b/ghc/compiler/main/DriverPhases.hs
index d1b24b34d4..6e945314cb 100644
--- a/ghc/compiler/main/DriverPhases.hs
+++ b/ghc/compiler/main/DriverPhases.hs
@@ -150,6 +150,7 @@ startPhase "C" = Cc
startPhase "cc" = Cc
startPhase "cxx" = Cc
startPhase "raw_s" = Mangle
+startPhase "split_s" = SplitMangle
startPhase "s" = As
startPhase "S" = As
startPhase "o" = StopLn
diff --git a/ghc/compiler/main/DriverPipeline.hs b/ghc/compiler/main/DriverPipeline.hs
index 039c18a056..8e4ee26a46 100644
--- a/ghc/compiler/main/DriverPipeline.hs
+++ b/ghc/compiler/main/DriverPipeline.hs
@@ -65,6 +65,7 @@ import Directory
import System
import IO
import Monad
+import Data.List ( isSuffixOf )
import Maybe
@@ -297,7 +298,7 @@ link BatchCompile dflags batch_attempt_linking hpt
pkg_deps = concatMap (dep_pkgs . mi_deps . hm_iface) home_mod_infos
-- the linkables to link
- linkables = map (fromJust.hm_linkable) home_mod_infos
+ linkables = map (expectJust "link".hm_linkable) home_mod_infos
debugTraceMsg dflags 3 (text "link: linkables are ..." $$ vcat (map ppr linkables))
@@ -985,34 +986,64 @@ runPhase As stop dflags _basename _suff input_fn get_output_fn maybe_loc
runPhase SplitAs stop dflags basename _suff _input_fn get_output_fn maybe_loc
- = do let as_opts = getOpts dflags opt_a
+ = do
+ output_fn <- get_output_fn StopLn maybe_loc
+
+ let (base_o, _) = splitFilename output_fn
+ split_odir = base_o ++ "_split"
+ osuf = objectSuf dflags
+
+ createDirectoryHierarchy split_odir
+
+ -- remove M_split/ *.o, because we're going to archive M_split/ *.o
+ -- later and we don't want to pick up any old objects.
+ fs <- getDirectoryContents split_odir
+ mapM_ removeFile $ map (split_odir `joinFileName`)
+ $ filter (osuf `isSuffixOf`) fs
+
+ let as_opts = getOpts dflags opt_a
(split_s_prefix, n) <- readIORef v_Split_info
- let real_odir
- | Just d <- objectDir dflags = d
- | otherwise = basename ++ "_split"
+ let split_s n = split_s_prefix ++ "__" ++ show n `joinFileExt` "s"
+ split_obj n = split_odir `joinFileName`
+ filenameOf base_o ++ "__" ++ show n
+ `joinFileExt` osuf
let assemble_file n
- = do let input_s = split_s_prefix ++ "__" ++ show n ++ ".s"
- let output_o = replaceFilenameDirectory
- (basename ++ "__" ++ show n ++ ".o")
- real_odir
- let osuf = objectSuf dflags
- let real_o = replaceFilenameSuffix output_o osuf
- SysTools.runAs dflags
- (map SysTools.Option as_opts ++
- [ SysTools.Option "-c"
- , SysTools.Option "-o"
- , SysTools.FileOption "" real_o
- , SysTools.FileOption "" input_s
- ])
+ = SysTools.runAs dflags
+ (map SysTools.Option as_opts ++
+ [ SysTools.Option "-c"
+ , SysTools.Option "-o"
+ , SysTools.FileOption "" (split_obj n)
+ , SysTools.FileOption "" (split_s n)
+ ])
mapM_ assemble_file [1..n]
- output_fn <- get_output_fn StopLn maybe_loc
+ -- and join the split objects into a single object file:
+ let ld_r args = SysTools.runLink dflags ([
+ SysTools.Option "-nostdlib",
+ SysTools.Option "-nodefaultlibs",
+ SysTools.Option "-Wl,-r",
+ SysTools.Option ld_x_flag,
+ SysTools.Option "-o",
+ SysTools.FileOption "" output_fn ] ++ args)
+ ld_x_flag | null cLD_X = ""
+ | otherwise = "-Wl,-x"
+
+ if cLdIsGNULd == "YES"
+ then do
+ let script = split_odir `joinFileName` "ld.script"
+ writeFile script $
+ "INPUT(" ++ unwords (map split_obj [1..n]) ++ ")"
+ ld_r [SysTools.FileOption "" script]
+ else do
+ ld_r (map (SysTools.FileOption "" . split_obj) [1..n])
+
return (StopLn, dflags, maybe_loc, output_fn)
+
-----------------------------------------------------------------------------
-- MoveBinary sort-of-phase
-- After having produced a binary, move it somewhere else and generate a