Make -split-objs work with --make
authorSimon Marlow <simonmar@microsoft.com>
Thu, 2 Mar 2006 17:05:05 +0000 (17:05 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Thu, 2 Mar 2006 17:05:05 +0000 (17:05 +0000)
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'.

ghc/compiler/Makefile
ghc/compiler/main/DriverPhases.hs
ghc/compiler/main/DriverPipeline.hs
mk/target.mk

index 0c877ce..1a9b428 100644 (file)
@@ -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)
index d1b24b3..6e94531 100644 (file)
@@ -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
index 039c18a..8e4ee26 100644 (file)
@@ -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
index a6793c9..7a49c35 100644 (file)
@@ -322,34 +322,6 @@ endif
 
 # Extra stuff for compiling Haskell files with $(SplitObjs):
 
-HC_SPLIT_PRE = \
-    $(RM) $@; if [ ! -d $(basename $@)_split ]; then mkdir $(basename $@)_split; else \
-    $(FIND) $(basename $@)_split -name '*.$(way_)o' -print | xargs $(RM) __rm_food; fi
-ifeq "$(GhcWithInterpreter)" "YES"
-ifeq "$(LdIsGNULd)" "YES"
-# If ld is GNU ld, we can use a linker script to pass the names of the
-# input files.  This avoids problems with limits on the length of the
-# ld command line, which we run into for large Haskell modules.
-HC_SPLIT_POST = \
-  ( cd $(basename $@)_split; \
-    $(RM) ld.script; \
-    touch ld.script; \
-    echo "INPUT(" *.$(way_)o ")" >>ld.script; \
-    $(LD) -r $(LD_X) -o ../$(notdir $@) ld.script; \
-  )
-else
-HC_SPLIT_POST = \
-  ( cd $(basename $@)_split; \
-    $(LD) -r $(LD_X) -o ../$(notdir $@) *.$(way_)o; \
-  )
-endif # LdIsGNULd == YES
-else
-HC_SPLIT_POST = touch $@
-endif # GhcWithInterpreter == YES
-
-SRC_HC_PRE_OPTS  += $(HC_SPLIT_PRE);
-SRC_HC_POST_OPTS += $(HC_SPLIT_POST);
-
 #
 # If (Haskell) object files are split, cleaning up 
 # consist of descending into the directories where