Commit ec968a32 authored by Simon Marlow's avatar Simon Marlow
Browse files

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'.
parent 1187e57f
...@@ -216,6 +216,8 @@ $(CONFIG_HS) : $(FPTOOLS_TOP)/mk/config.mk Makefile ...@@ -216,6 +216,8 @@ $(CONFIG_HS) : $(FPTOOLS_TOP)/mk/config.mk Makefile
@echo "cRAWCPP_FLAGS = \"$(RAWCPP_FLAGS)\"" >> $(CONFIG_HS) @echo "cRAWCPP_FLAGS = \"$(RAWCPP_FLAGS)\"" >> $(CONFIG_HS)
@echo "cGCC = \"$(WhatGccIsCalled)\"" >> $(CONFIG_HS) @echo "cGCC = \"$(WhatGccIsCalled)\"" >> $(CONFIG_HS)
@echo "cMKDLL = \"$(BLD_DLL)\"" >> $(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 "cPROJECT_DIR = \"$(PROJECT_DIR)\"" >> $(CONFIG_HS)
@echo "cGHC_DRIVER_DIR_REL = \"$(GHC_DRIVER_DIR_REL)\"" >> $(CONFIG_HS) @echo "cGHC_DRIVER_DIR_REL = \"$(GHC_DRIVER_DIR_REL)\"" >> $(CONFIG_HS)
@echo "cGHC_TOUCHY_PGM = \"$(GHC_TOUCHY_PGM)\"" >> $(CONFIG_HS) @echo "cGHC_TOUCHY_PGM = \"$(GHC_TOUCHY_PGM)\"" >> $(CONFIG_HS)
......
...@@ -150,6 +150,7 @@ startPhase "C" = Cc ...@@ -150,6 +150,7 @@ startPhase "C" = Cc
startPhase "cc" = Cc startPhase "cc" = Cc
startPhase "cxx" = Cc startPhase "cxx" = Cc
startPhase "raw_s" = Mangle startPhase "raw_s" = Mangle
startPhase "split_s" = SplitMangle
startPhase "s" = As startPhase "s" = As
startPhase "S" = As startPhase "S" = As
startPhase "o" = StopLn startPhase "o" = StopLn
......
...@@ -65,6 +65,7 @@ import Directory ...@@ -65,6 +65,7 @@ import Directory
import System import System
import IO import IO
import Monad import Monad
import Data.List ( isSuffixOf )
import Maybe import Maybe
...@@ -297,7 +298,7 @@ link BatchCompile dflags batch_attempt_linking hpt ...@@ -297,7 +298,7 @@ link BatchCompile dflags batch_attempt_linking hpt
pkg_deps = concatMap (dep_pkgs . mi_deps . hm_iface) home_mod_infos pkg_deps = concatMap (dep_pkgs . mi_deps . hm_iface) home_mod_infos
-- the linkables to link -- 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)) 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 ...@@ -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 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 (split_s_prefix, n) <- readIORef v_Split_info
let real_odir let split_s n = split_s_prefix ++ "__" ++ show n `joinFileExt` "s"
| Just d <- objectDir dflags = d split_obj n = split_odir `joinFileName`
| otherwise = basename ++ "_split" filenameOf base_o ++ "__" ++ show n
`joinFileExt` osuf
let assemble_file n let assemble_file n
= do let input_s = split_s_prefix ++ "__" ++ show n ++ ".s" = SysTools.runAs dflags
let output_o = replaceFilenameDirectory (map SysTools.Option as_opts ++
(basename ++ "__" ++ show n ++ ".o") [ SysTools.Option "-c"
real_odir , SysTools.Option "-o"
let osuf = objectSuf dflags , SysTools.FileOption "" (split_obj n)
let real_o = replaceFilenameSuffix output_o osuf , SysTools.FileOption "" (split_s n)
SysTools.runAs dflags ])
(map SysTools.Option as_opts ++
[ SysTools.Option "-c"
, SysTools.Option "-o"
, SysTools.FileOption "" real_o
, SysTools.FileOption "" input_s
])
mapM_ assemble_file [1..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) return (StopLn, dflags, maybe_loc, output_fn)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- MoveBinary sort-of-phase -- MoveBinary sort-of-phase
-- After having produced a binary, move it somewhere else and generate a -- After having produced a binary, move it somewhere else and generate a
......
...@@ -322,34 +322,6 @@ endif ...@@ -322,34 +322,6 @@ endif
# Extra stuff for compiling Haskell files with $(SplitObjs): # 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 # If (Haskell) object files are split, cleaning up
# consist of descending into the directories where # consist of descending into the directories where
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment