From: Simon Marlow Date: Thu, 2 Mar 2006 17:05:05 +0000 (+0000) Subject: Make -split-objs work with --make X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=ec968a32e9b02c230dfcbff9660c3e61900d8235 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'. --- diff --git a/ghc/compiler/Makefile b/ghc/compiler/Makefile index 0c877ce..1a9b428 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 d1b24b3..6e94531 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 039c18a..8e4ee26 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 diff --git a/mk/target.mk b/mk/target.mk index a6793c9..7a49c35 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -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