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
@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)
......
......@@ -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
......
......@@ -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
= SysTools.runAs dflags
(map SysTools.Option as_opts ++
[ SysTools.Option "-c"
, SysTools.Option "-o"
, SysTools.FileOption "" real_o
, SysTools.FileOption "" input_s
, 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
......
......@@ -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
......
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