The phase at which to STOP processing is determined by a command-line
option:
+ -E stop after generating preprocessed, de-litted Haskell (used in conjunction with -cpp)
-C stop after generating C (.hc output)
- -E stop after generating preprocessed C (.i output)
-S stop after generating assembler (.s output)
-c stop after generating object files (.o output)
-M Output the Makefile rules recording the
dependencies of a list of Haskell files.
- (ghc driver just calls upon the help of a
- compatible mkdependHS script to do the
- actual processing)
+ (ghc driver script calls upon the help of a
+ compatible mkdependHS script to do the actual
+ processing)
The User's Guide has more information about GHC's *many* options.
$Oopt_FB_Support = ''; # was '-fdo-arity-expand';
# $Oopt_FoldrBuildWW = 0; # Off by default
$Oopt_FoldrBuildInline = ''; # was '-fdo-inline-foldr-build';
+ $Oopt_ShowSimplifierProgress = '';
} # end of setupOptFlags
# Assign defaults to these right away.
$Nm = ($TargetPlatform =~ /^alpha-/) ? 'nm -B' : 'nm';
\end{code}
+Warning packages that are controlled by -W and -Wall. The 'standard'
+warnings that you get all the time are
+
+ -fwarn-overlapping-patterns
+ -fwarn-missing-methods
+ -fwarn-duplicate-exports
+
+these are turned off by -Wnot.
+
+\begin{code}
+@StandardWarnings = ('-fwarn-overlapping-patterns',
+ '-fwarn-missing-methods',
+ '-fwarn-duplicate-exports');
+@MinusWOpts = (@StandardWarnings,
+ '-fwarn-incomplete-patterns',
+ '-fwarn-unused-names');
+@MinusWallOpts = (@MinusWOpts,
+ '-fwarn-name-shadowing');
+\end{code}
+
What options \tr{-user-setup-a} turn into (user-defined ``packages''
+
of options). Note that a particular user-setup implies a particular
Prelude ({\em including} its interface file(s)).
\begin{code}
'_1s', "$WAY_1s_HC_OPTS",
'_du', "$WAY_B_HC_OPTS" );
-# per-build code fragments which are eval'd
-#%EvaldSetupOpts = ('', '', # this one must *not* be set!
-
-# # profiled sequential
-# '_p', 'push(@HsC_flags, \'-fscc-profiling\');
-# push(@CcBoth_flags, \'-DPROFILING\');',
-
-# #and maybe ...
-# #push(@CcBoth_flags, '-DPROFILING_DETAIL_COUNTS');
-
-# # ticky-ticky sequential
-# '_t', 'push(@HsC_flags, \'-fticky-ticky\');
-# push(@CcBoth_flags, \'-DTICKY_TICKY\');',
-
-##OLD: # unregisterized (ToDo????)
-## '_u', '',
-
-# # concurrent
-# '_mc', '$StkChkByPageFaultOK = 0;
-# push(@HsC_flags, \'-fconcurrent\');
-# push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');',
-
-# # profiled concurrent
-# '_mr', '$StkChkByPageFaultOK = 0;
-# push(@HsC_flags, \'-fconcurrent\', \'-fscc-profiling\');
-# push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPROFILING\');',
-
-# # ticky-ticky concurrent
-# '_mt', '$StkChkByPageFaultOK = 0;
-# push(@HsC_flags, \'-fconcurrent\', \'-fticky-ticky\');
-# push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DTICKY_TICKY\');',
-
-# # parallel
-# '_mp', '$StkChkByPageFaultOK = 0;
-# push(@HsC_flags, \'-fconcurrent\');
-# push(@HsCpp_flags,\'-D__PARALLEL_HASKELL__\', \'-DPAR\');
-# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPAR\');',
-
-# # GranSim
-# '_mg', '$StkChkByPageFaultOK = 0;
-# push(@HsC_flags, \'-fconcurrent\', \'-fgransim\');
-# push(@HsCpp_flags,\'-D__GRANSIM__\', \'-DGRAN\');
-# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DGRAN\');',
-
-# '_2s', 'push (@CcBoth_flags, \'-DGC2s\');',
-# '_1s', 'push (@CcBoth_flags, \'-DGC1s\');',
-# '_du', 'push (@CcBoth_flags, \'-DGCdu\');',
-
-# '_a', '', # these user-way guys should not be set!
-# '_b', '',
-# '_c', '',
-# '_d', '',
-# '_e', '',
-# '_f', '',
-# '_g', '',
-# '_h', '',
-# '_i', '',
-# '_j', '',
-# '_k', '',
-# '_l', '',
-# '_m', '',
-# '_n', '',
-# '_o', '',
-# '_A', '',
-# '_B', '' );
-
\end{code}
Import/include directories (\tr{-I} options) are sufficiently weird to
# We need to look in ghc/ and glaExts/ when searching for implicitly needed .hi files, but
# we should really *not* look there for explicitly imported modules.
-$GhcVersionInfo = int ($PROJECTVERSION * 100);
+$GhcVersionInfo = int($PROJECTVERSION * 100 + .5); # i.e., round (X.Y * 100)
$Haskell1Version = 4; # i.e., Haskell 1.4
@Cpp_define = ();
= ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS"
: "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS";
# Fill in later
-@MkDependHS_flags = ( );
+@MkDependHS_flags = ();
# do_link flag should not be reset while rescanning the cmd-line.
$Do_lnkr = 1;
\begin{code}
$Cpp_flag_set = 0; # (hack)
$Only_preprocess_C = 0; # pretty hackish
-$Only_generate_deps = 0; #
+$Only_preprocess_hc = 0; # ditto
+$Only_generate_deps = 0; # "
$PostprocessCcOutput = 0;
# native code-gen or via C?
$HscOut = '-S='
if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc)-/;
# TEMP: disable x86 if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
-$ProduceHi = '-hifile=';
-$HiOnStdout = 0;
-$HiDiff_flag = '';
+$ProduceHi = '-hifile=';
+$HiOnStdout = 0;
+$HiDiff_flag = '';
+$Keep_HiDiffs = 0;
$CollectingGCstats = 0;
$CollectGhcTimings = 0;
Now slurp through the arguments.
\begin{code}
-#---------- user defined prelude ---------------------------------------
-
-if (grep(/^-user-prelude$/, @ARGV)) {
-
- # If ARGV contains -user-prelude we are compiling a piece of
- # prelude for the user, probably with additional specialise pragmas
-
- # We strip out the -O -f and -user-prelude flags provided on
- # the command line and add the ones used to compile the prelude
- # ToDo: get these options from a common definition in mkworld
-
- # We also enable any options forced through with -user-prelude-force
-
- # Hey, Check out this grep statement ;-) (PS)
-
- @ARGV = grep((!/^-O/ && !/^-f/ && !/^-user-prelude$/) || s/^-user-prelude-force//,
- @ARGV);
-
- unshift(@ARGV,
- '-fcompiling-ghc-internals=???', # ToDo!!!!
- '-O',
- '-fshow-pragma-name-errs',
- '-fshow-import-specs',
- '-fglasgow-exts',
- '-genSPECS',
- '-DUSE_FOLDR_BUILD',
- '-dcore-lint');
-
- print STDERR "ghc: -user-prelude options:\n", "@ARGV", "\n";
-}
-
&initDriverGlobals();
&splitCmdLine(@ARGV);
# Run through the cmd-line first time.
push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
+ push (@MkDependHS_flags, "-D__HASKELL1__=$Haskell1Version");
+ # They're not (currently) needed, but we need to quote any -#include options
+ foreach (@Cmd_opts) {
+ s/-#include.*$/'$&'/g;
+ };
local($to_do) = "$MkDependHS @MkDependHS_flags -- @Cmd_opts -- @Input_file" ;
&run_something($to_do, 'Haskell dependencies');
exit $Status;
@HsC_minusNoO_flags
= ( '-fsimplify',
- '\(',
+ '[',
$Oopt_FB_Support,
'-ffloat-lets-exposing-whnf',
'-ffloat-primops-ok',
'-fcase-of-case',
+ '-fdo-case-elim',
# '-fdo-lambda-eta-expansion', # too complicated
'-freuse-con',
# '-flet-to-case', # no strictness analysis, so...
$Oopt_UnfoldingUseThreshold,
$Oopt_MaxSimplifierIterations,
- '\)',
+ $Oopt_ShowSimplifierProgress,
+ ']',
$Oopt_AddAutoSccs,
# '-ffull-laziness', # removed 95/04 WDP following Andr\'e's lead
# initial simplify: mk specialiser happy: minimum effort please
'-fsimplify',
- '\(',
+ '[',
$Oopt_FB_Support,
'-fkeep-spec-pragma-ids', # required before specialisation
'-fmax-simplifier-iterations1',
$Oopt_PedanticBottoms,
- '\)',
+ ']',
($Oopt_DoSpecialise) ? (
'-fspecialise-overloaded',
) : (),
'-fsimplify', # need dependency anal after specialiser ...
- '\(', # need tossing before calc-inlinings ...
+ '[', # need tossing before calc-inlinings ...
$Oopt_FB_Support,
'-ffloat-lets-exposing-whnf',
'-ffloat-primops-ok',
$Oopt_MonadEtaExpansion,
$Oopt_UnfoldingUseThreshold,
$Oopt_MaxSimplifierIterations,
- '\)',
+ $Oopt_ShowSimplifierProgress,
+ ']',
#LATER: '-fcalc-inlinings1', -- pointless for 2.01
# '-ffoldr-build-ww-anal',
# '-ffoldr-build-worker-wrapper',
# '-fsimplify',
-# '\(',
+# '[',
# $Oopt_FB_Support,
# '-ffloat-lets-exposing-whnf',
# '-ffloat-primops-ok',
# $Oopt_MonadEtaExpansion,
# $Oopt_UnfoldingUseThreshold,
# $Oopt_MaxSimplifierIterations,
-# '\)',
+# $Oopt_ShowSimplifierProgress,
+# ']',
# ) : (),
# this pass-ordering sequence was agreed by Simon and Andr\'e
'-ffoldr-build-on', # desugar list comprehensions for foldr/build
'-fsimplify',
- '\(',
+ '[',
'-fignore-inline-pragma', # **** NB!
'-fdo-foldr-build', # NB
$Oopt_FB_Support,
$Oopt_MonadEtaExpansion,
$Oopt_UnfoldingUseThreshold,
$Oopt_MaxSimplifierIterations,
- '\)',
+ $Oopt_ShowSimplifierProgress,
+ ']',
) : (),
'-ffloat-inwards',
'-fsimplify',
- '\(',
+ '[',
$Oopt_FB_Support,
'-ffloat-lets-exposing-whnf',
'-ffloat-primops-ok',
$Oopt_MonadEtaExpansion,
$Oopt_UnfoldingUseThreshold,
$Oopt_MaxSimplifierIterations,
- '\)',
+ $Oopt_ShowSimplifierProgress,
+ ']',
'-fstrictness',
'-fsimplify',
- '\(',
+ '[',
$Oopt_FB_Support,
'-ffloat-lets-exposing-whnf',
'-ffloat-primops-ok',
$Oopt_MonadEtaExpansion,
$Oopt_UnfoldingUseThreshold,
$Oopt_MaxSimplifierIterations,
- '\)',
+ $Oopt_ShowSimplifierProgress,
+ ']',
'-ffloat-inwards',
# ( ($OptLevel != 2)
# ? ''
-# : "-fliberate-case -fsimplify \\( $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations \\)" ),
+# : "-fliberate-case -fsimplify [ $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
# Final clean-up simplification:
'-fsimplify',
- '\(',
+ '[',
$Oopt_FB_Support,
'-ffloat-lets-exposing-whnf',
'-ffloat-primops-ok',
$Oopt_MonadEtaExpansion,
$Oopt_UnfoldingUseThreshold,
$Oopt_MaxSimplifierIterations,
- '\)',
+ $Oopt_ShowSimplifierProgress,
+ ']',
# '-fstatic-args',
} else { # -Ofile, then...
&add_Hsc_flags( @HsC_minusO3_flags );
+ push(@HsC_flags, $Oopt_FinalStgProfilingMassage) if $Oopt_FinalStgProfilingMassage;
+
push(@CcBoth_flags, ($MinusO2ForC) ? '-O2' : '-O'); # possibly to be elaborated...
}
} # end of setupMachOpts
\end{code}
+%************************************************************************
+%* *
+\subsection{Set up for warnings}
+%* *
+%************************************************************************
+
+Several warnings are turned on by default. These are supposed to be
+the 'I'm pretty sure you've made a mistake here' kind of warnings.
+The rest are turned on by the -W and -Wall options, or individually
+via their -fwarn and -fno-warn flags.
+
+\begin{code}
+sub setupWarningFlags {
+&add_Hsc_flags( @StandardWarnings );
+}
+\end{code}
+
Same unshifting magic, but for special linker flags.
The configure script determines whether the object file symbol tables
,'-u', "${uscore}PrelBase_CZh_static_info"
,'-u', "${uscore}PrelBase_False_inregs_info"
,'-u', "${uscore}PrelBase_True_inregs_info"
- ,'-u', "${uscore}STBase_SZh_static_info"
,'-u', "${uscore}DEBUG_REGS"
));
if ($TargetPlatform =~ /^powerpc-|^rs6000-/) {
@Input_file = ( '-' );
open(INF, "> $Tmp_prefix.hs") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.hs\n");
- print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n";
- while (<>) { print INF $_; }
+ print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n" if -t;
+ while (<STDIN>) { print INF $_; }
close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
}
local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
# OK, let's strip off some literate junk..
- if ($ifile =~ /\.lhs$/) {
+ if ($do_lit2pgm) {
&runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
} else {
$lit2pgm_hscpp = $ifile;
# Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
&check_for_source_options($lit2pgm_hscpp,$ifile);
- # options found in the source file take a back seat, i.e., we scan
+
+ # Options found in the source file take a back seat, i.e., we scan
# them first. Only process the command line again if source file
# contained anything of interest *or* there's more than one
# input file (we have to reset the options).
&setupOptimiseFlags();
&setupMachOpts();
&setupIncPaths();
+ &setupWarningFlags();
&setupHeapStackSize();
#
local($do_as) = $Do_as;
local($hsc_out) = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
- if ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
+ if ($Only_preprocess_hc) { # stop after having run $Cc -E
+ $do_as=0;
+ }
+ if ($Only_preprocess_C) { # stop after having run $hscpp
+ $do_hsc=0; $do_cc = 0; $do_as=0;
+ } elsif ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
;
} elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
$do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
# hack to avoid running hscpp
$HsCpp = $Cat if ! $Cpp_flag_set;
- &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc)
- if $do_hscpp;
+ &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) if $do_hscpp;
+
\end{code}
We now think about whether to run hsc/cc or not (when hsc produces .s
To get the output file name right: for each phase that we are {\em
not} going to run, set its input (i.e., the output of its preceding
phase) to @"$ifile_root.<suffix>"@.
+
\begin{code}
local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
# -fvia-C (or the equivalent)
#
if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
- print STDERR "Warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
+ print STDERR "$Pgm: warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
}
if (! $do_cc && ! $do_as) { # stopping after hsc
if (! $do_as) { # stopping after gcc (or hsc)
$cc_as = ($Specific_output_file ne '')
? $Specific_output_file
- : &odir_ify($ifile_root, ( $Only_preprocess_C ) ? 'i' : 's');
+ : &odir_ify($ifile_root, ( $Only_preprocess_hc ) ? 'i' : 's');
$ofile_target = $cc_as; # reset
}
if ($do_cc) {
&runGcc ($is_hc_file, $hsc_out, $cc_as_o);
- &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root);
+ &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root) if ! $Only_preprocess_hc;
}
&split_asm_file($cc_as) if $do_as && $SplitObjFiles;
sub runLit2pgm {
local($in_lit2pgm, $lit2pgm_hscpp) = @_;
- local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && ".
- "$Unlit @Unlit_flags $in_lit2pgm - >> $lit2pgm_hscpp";
- @Files_to_tidy = ( $lit2pgm_hscpp );
+ local($to_do) = "";
+
+ # Only add #line pragma if we're going to need it.
+ $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && " if ($Cpp_flag_set);
+ $to_do .= "$Unlit @Unlit_flags $in_lit2pgm - >> $lit2pgm_hscpp";
+
+ push(@Files_to_tidy, $lit2pgm_hscpp );
&run_something($to_do, 'literate pre-processor');
}
sub runHscpp {
local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_;
- local($to_do);
+ local($to_do) = "";
+
+ # Strictly speaking, echoing of the following line pragma is only required
+ # on non-delit'ed input, as we've already added it during de-lit. However,
+ # hscpp will then add a {-# LINE 1 "$lit2pgm_hsc" -} to the top of the file,
+ # which is not very informative (but harmless). Hence, we uniformly have
+ # {-# LINE 1 "$in_lit2pgm" #-} as the first line to all cpp'ed hsc input.
+ #
+ $to_do = "echo '{-# LINE 1 \"$in_lit2pgm\" -}' > $hscpp_hsc && ";
if ($HsCpp eq $Cat) {
- $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
- "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
- @Files_to_tidy = ( $hscpp_hsc );
+ $to_do .= "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
+ push(@Files_to_tidy, $hscpp_hsc );
&run_something($to_do, 'Ineffective C pre-processor');
} else {
local($includes) = '-I' . join(' -I',@Include_dir);
- $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
- "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc";
- @Files_to_tidy = ( $hscpp_hsc );
+ $to_do .= "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc";
+ push(@Files_to_tidy, $hscpp_hsc );
&run_something($to_do, 'Haskellised C pre-processor');
}
+
+ if ( $Only_preprocess_C ) {
+ $to_do = "$Cat $hscpp_hsc";
+ &run_something($to_do, '');
+ }
+
}
\end{code}
$i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
# The informational messages below are now conditional on -v being set -- SOF
- if ( ! -f $ofile_target ) {
+ if ( $ofile_target ne "_stdin.s" && ! -f $ofile_target ) {
print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n" if $Verbose;
$source_unchanged = 0;
}
($o_dev,$o_ino,$o_mode,$o_nlink,$o_uid,$o_gid,$o_rdev,$o_size,
$o_atime,$o_mtime,$o_ctime,$o_blksize,$o_blocks) = stat(_); # stat info from -f test
- if ( ! -f $hifile_target ) {
+ if ( $hifile_target ne "_stdout" && ! -f $hifile_target ) {
print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n" if $Verbose;
$source_unchanged = 0;
}
($hi_dev,$hi_ino,$hi_mode,$hi_nlink,$hi_uid,$hi_gid,$hi_rdev,$hi_size,
$hi_atime,$hi_mtime,$hi_ctime,$hi_blksize,$hi_blocks) = stat(_); # stat info from -f test
- if ($i_mtime > $o_mtime) {
+ if ( $ofile_target ne "_stdin.s" && $i_mtime > $o_mtime) {
print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n" if $Verbose;
$source_unchanged = 0;
}
# here, we may produce .hc/.s and/or .hi files
local($output) = '';
- @Files_to_tidy = ();
+ #@Files_to_tidy = ();
if ( $going_interactive ) {
# don't need .hi unless going to show it on stdout:
# set up for producing output/.hi; note that flag twiddling
# may mean that nothing will actually be produced:
$output = "$ProduceHi$hsc_hi $HscOut$hsc_out";
- @Files_to_tidy = ( $hsc_hi, $hsc_out );
+ push(@Files_to_tidy, $hsc_hi, $hsc_out );
# if we're compiling foo.hs, we want the GC stats to end up in foo.stat
if ( $CollectingGCstats ) {
if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
# emit nofibbish time/bytes-alloc stats to stderr;
# see later .stat file post-processing
+ print STDERR "warning: both -Rgc-stats and -Rghc-timing used, -Rghc-timing wins." if $CollectingGCstats;
push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
push(@Files_to_tidy, "$Tmp_prefix.stat");
}
print TMP "#include \"$hsc_out\"\n";
close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
- local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout 2>&1 && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )";
+ # Don't redirect stderr into intermediate file if slamming output onto stdout (e.g., with -E)
+ local($fuse_stderr) = "2>&1" if ! $Only_preprocess_hc;
+ local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout $fuse_stderr && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )";
# note: __GLASGOW_HASKELL__ is pointedly *not* #defined at the C level.
- if ( $Only_preprocess_C ) { # HACK ALERT!
+
+ if ( $Only_preprocess_hc ) { # HACK ALERT!
$to_do =~ s/ -S\b//g;
}
- @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output );
- $PostprocessCcOutput = 1; # hack, dear hack...
+ push(@Files_to_tidy, $cc_help, $cc_help_s, $s_output );
+ $PostprocessCcOutput = 1 if ! $Only_preprocess_hc; # hack, dear hack...
&run_something($to_do, 'C compiler');
$PostprocessCcOutput = 0;
+ if ( $Only_preprocess_hc ) {
+ system("$Cat $Tmp_prefix.ccout");
+ }
unlink($cc_help, $cc_help_s);
}
\end{code}
if ( ! $SplitObjFiles ) {
local($to_do) = "$asmblr -o $as_out -c @As_flags $cc_as";
- @Files_to_tidy = ( $as_out );
+ push(@Files_to_tidy, $as_out );
&run_something($to_do, 'Unix assembler');
} else { # more complicated split-ification...
for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
local($split_out) = &odir_ify("${ifile_root}__${f}",'o');
local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
- @Files_to_tidy = ( $split_out );
+ push(@Files_to_tidy, $split_out );
&run_something($to_do, 'Unix assembler');
}
local($SysSpecificTiming) = 'ghc';
open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n";
- local($tot_live) = 0; # for calculating avg residency
+ local($max_live) = 0;
+ local($tot_live) = 0; # for calculating residency stuff
+ local($tot_samples) = 0;
while (<STATS>) {
- $tot_live += $1 if /^\s*\d+\s+\d+\s+\d+\.\d+\%\s+(\d+)\s+\d+\.\d+\%/;
-
- $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/;
+ if (! /Minor/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+\%/ ) {
+ $max_live = $1 if $max_live < $1;
+ $tot_live += $1;
+ $tot_samples += 1;
+ }
+ $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/;
if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) {
$MaxResidency = $1; $ResidencySamples = $2;
}
- $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
+ $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
- if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
+ # The presence of -? in the following pattern is only there to
+ # accommodate 0.29 && <= 2.05 RTS'
+ if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*-?(\d+\.\d\d)s elapsed\)/ ) {
$InitTime = $1; $InitElapsed = $2;
} elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
$MutTime = $1; $MutElapsed = $2;
}
}
close(STATS) || die "Failed when closing $StatsFile\n";
- if ( defined($ResidencySamples) && $ResidencySamples > 0 ) {
- $AvgResidency = int ($tot_live / $ResidencySamples) ;
+ if ( $tot_samples > 0 ) {
+ $ResidencySamples = $tot_samples;
+ $MaxResidency = $max_live;
+ $AvgResidency = int ($tot_live / $tot_samples) ;
}
# warn about what we didn't find
sub grab_arg_arg {
local(*Args, $option, $rest_of_arg) = @_;
- if ($rest_of_arg) {
+ if ($rest_of_arg ne '') {
return($rest_of_arg);
} elsif ($#Args >= 0) {
local($temp) = $Args[0]; shift(@Args);
}
\end{code}
+\begin{code}
+sub add_syslib {
+ local($syslib) = @_;
+
+ unshift(@SysImport_dir,
+ ${INSTALLING} ? "$InstSysLibDir/$syslib/imports"
+ : "$TopPwd/hslibs/$syslib/src");
+
+ push(@SysLibrary_dir,
+ ${INSTALLING} ? ("$InstSysLibDir")
+ : ("$TopPwd/hslibs/$syslib",
+ "$TopPwd/hslibs/$syslib/cbits"));
+
+ push(@SysLibrary, "-lHS$syslib");
+ push(@SysLibrary, "-lHS${syslib}_cbits")
+ unless $syslib eq 'contrib'; #HACK! it has no cbits
+}
+\end{code}
+
Source files may have {-# OPTIONS ... #-} pragmas at the top, containing
command line options we want to append to collection of commands specified
directly. @check_for_source_options@ looks at the top of a de-lit'ified Haskell
elsif ( /^$/ ) { # ignore empty lines
;
}
- elsif ( /^#line.+$/ ) { # ignore comment lines
+ elsif ( /^#line.+$/ ) { # ignore comment lines (unused..ToDo: rm )
+ ;
+ }
+ elsif ( /^{-# LINE.+$/ ) { # ignore line pragmas
;
}
else { # stop looking, something non-empty / not
arg: while($_ = $args[0]) {
shift(@args);
# sigh, we have to deal with these -option arg specially here.
- /^-(tmpdir|odir|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ &&
+ /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ &&
do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; };
/^--?./ && do { push(@Cmd_opts, $_); next arg; };
- if (/\.[oa]$/) {
+ if (/\.([^_]+_)?[oa]$/) {
push(@Link_file, $_);
} else {
push(@Input_file, $_);
/^-v$/ && do { $Verbose = '-v'; $Time = 'time'; next arg; };
#---------- what phases are to be run ----------------------------------
- /^-recomp/ && do { $Do_recomp_chkr = 1; next arg; };
+ /^-(no-)?recomp/ && do { $Do_recomp_chkr = ($1 eq '') ? 1 : 0; next arg; };
/^-cpp$/ && do { $Cpp_flag_set = 1; next arg; };
# change the global default:
/^-nohi$/ && do { $ProduceHi = '-nohifile='; next arg; };
# don't generate an interface (even if generating C)
- /^-hi-diffs$/ && do { $HiDiff_flag = 'normal'; next arg; };
- /^-hi-diffs-with-usages$/ && do { $HiDiff_flag = 'usages'; next arg; };
- /^-no-hi-diffs$/ && do { $HiDiff_flag = ''; next arg; };
+ /^-hi-diffs$/ && do { $HiDiff_flag = 'normal'; next arg; };
+ /^-hi-diffs-with-usages$/ && do { $HiDiff_flag = 'usages'; next arg; };
+ /^-no-hi-diffs$/ && do { $HiDiff_flag = ''; next arg; };
+ /^-keep-hi-diffs$/ && do { $Keep_HiDiffs = 1; next arg; };
+
# show/disable diffs if the interface file changes
/^-E$/ && do { push(@CcBoth_flags, '-E');
print STDERR "$Pgm: no such system library (-syslib): $syslib\n",
$Status++ unless $syslib =~ /^(hbc|ghc|posix|contrib)$/;
- unshift(@SysImport_dir,
- ${INSTALLING}
- ? "$InstSysLibDir/$syslib/imports"
- : "$TopPwd/hslibs/$syslib/src");
-
- if ( ${INSTALLING} ) {
- push(@SysLibrary_dir,
- ("$InstSysLibDir"));
- } else {
- push(@SysLibrary_dir,
- ("$TopPwd/hslibs/$syslib"
- ,"$TopPwd/hslibs/$syslib/cbits"));
+ #
+ # The posix library is a `special' in that it relies on
+ # the ghc system library (packed strings). Wielding our
+ # sledgehammer, the problem is solved by silently including
+ # the ghc system library as well.
+ # (ToDo: `nub' -syslib list)
+ #
+ &add_syslib($syslib);
+ if ( $syslib eq 'posix' ) {
+ &add_syslib('ghc');
+ } elsif ( $syslib eq 'ghc' &&
+ $TargetName =~ /-solaris2$/ ) {
+ # needed for Berkeley socket/nwork stuff.
+ push(@SysLibrary, '-lnsl');
}
-
- push(@SysLibrary, "-lHS$syslib");
- push(@SysLibrary, "-lHS${syslib}_cbits")
- unless $syslib eq 'contrib'; #HACK! it has no cbits
-
next arg; };
#=======================================================================
/^-optP(.*)$/ && do { push(@HsCpp_flags, $1); next arg; };
/^-optCrts(.*)$/&& do { push(@HsC_rts_flags, $1); next arg; };
/^-optC(.*)$/ && do { push(@HsC_flags, $1); next arg; };
- /^-optcpp(.*)$/ && do { push(@Cpp_define, $1); next arg; };
+ /^-optcpp(.*)$/ && do { push(@Cpp_define, $1); $Only_preprocess_hc = ($1 eq "-E"); next arg; };
/^-optc(.*)$/ && do { push(@CcBoth_flags, $1); next arg; };
/^-opta(.*)$/ && do { push(@As_flags, $1); next arg; };
/^-optl(.*)$/ && do { push(@Ld_flags, $1); next arg; };
/^-fticky-ticky$/ && do { push(@HsC_flags,$_); next arg; };
/^-fgransim$/ && do { push(@HsC_flags,$_); next arg; };
- /^-user-prelude-force/ && do { # ignore if not -user-prelude
- next arg; };
-
/^-split-objs/ && do {
if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|rs6000|sparc)-/ ) {
$SplitObjFiles = 0;
# ---------------
/^-fasm-(.*)$/ && do { $HscOut = '-S='; next arg; }; # force using nativeGen
- /^-fvia-C$/ && do { $HscOut = '-C='; next arg; }; # force using C compiler
+ /^-fvia-[cC]$/ && do { $HscOut = '-C='; next arg; }; # force using C compiler
# ---------------
/^(-fmax-simplifier-iterations)(.*)$/
&& do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2);
next arg; };
+ /^(-fshow-simplifier-progress)/
+ && do { $Oopt_ShowSimplifierProgress = $1;
+ next arg; };
/^-fno-pedantic-bottoms$/
&& do { $Oopt_PedanticBottoms = ''; next arg; };
# --------------- Warnings etc. ------
- /^-f(show-import-specs)/
+ /^-fshow-import-specs/
&& do { push(@HsC_flags, $_); next arg; };
- # for now, just -fwarn-name-shadowing
- /^-fwarn-(.*)$/ && do { push(@HsC_flags, $_); next arg; };
+ /^-fsignatures-required/
+ && do { push(@HsC_flags, $_); next arg; };
- /^-fno-warn-(.*)$/ && do { push(@HsC_flags, "-fno-warn-$1"); next arg; };
+ /^-fwarn-(.*)$/ && do { push(@HsC_flags, $_); next arg; };
/^-fno-(.*)$/ && do { push(@HsC_antiflags, "-f$1");
&squashHscFlag("-f$1");
next arg; };
+ /^-W$/ && do { push(@HsC_flags, @MinusWOpts); next arg; };
+ /^-Wall$/ && do { push(@HsC_flags, @MinusWallOpts); next arg; };
+ /^(-Wnot|w)$/ && do { foreach (@Hsc_flags) {
+ /^-fwarn-(.*)$/ && do { $_=''; };
+ };
+ push(@HsC_antiflags, @StandardWarnings);
+ next arg; };
+
# --------------- platform specific flags (for gcc mostly) ----------------
/^-mlong-calls$/ && do { # for GCC for HP-PA boxes,
}
next arg; };
- /^-(K|Rmax-(stk|stack)size)(.*)/ && do {
+ /^(-K|Rmax-(stk|stack)size)(.*)/ && do {
local($flag) = $1;
local($stk_size) = &grab_arg_arg(*Args,'-Rmax-stksize', $3);
if ($stk_size =~ /(\d+)[Kk]$/) {