[project @ 1998-08-25 14:01:53 by sof]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 99b57fe..8691e7f 100644 (file)
@@ -99,7 +99,9 @@ INSTALLING
 
 HOSTPLATFORM TARGETPLATFORM
 
-PROJECTNAME PROJECTVERSION PROJECTPATCHLEVEL
+ProjectName ProjectVersion ProjectVersionInt ProjectPatchLevel 
+
+HscMajorVersion HscMinorVersion CcMajorVersion CcMinorVersion
 
 TOP_PWD
 
@@ -138,7 +140,6 @@ $InstLibDirGhc     = "${libdir}";
 #
 $InstLibExecDirGhc = "${libexecdir}";
 $InstDataDirGhc    = "${datadir}";
-$InstSysLibDir     = ( $INSTALLING ) ? "${InstLibDirGhc}/hslibs" : "$TopPwd/hslibs";
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
@@ -195,7 +196,6 @@ $HsCpp       = # but this is re-set to "cat" (after options) if -cpp not seen
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
-$genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
 $HsC    = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
@@ -222,14 +222,13 @@ These are the default values, which may be changed by user flags.
 
 \begin{code}
 sub setupOptFlags {
-   $Oopt_UnfoldingUseThreshold   = '-fsimpl-uf-use-threshold3';
    $Oopt_MaxSimplifierIterations  = '-fmax-simplifier-iterations4';
    $Oopt_PedanticBottoms         = '-fpedantic-bottoms'; # ON by default
    $Oopt_MonadEtaExpansion       = '';
    $Oopt_FinalStgProfilingMassage = '';
    $Oopt_StgStats                = '';
    $Oopt_SpecialiseUnboxed       = '';
-   $Oopt_DoSpecialise            = ''; # ToDo:LATER: '-fspecialise';
+   $Oopt_DoSpecialise            = '-fspecialise';
    $Oopt_FoldrBuild              = 0; # *Off* by default!
    $Oopt_FB_Support              = ''; # was '-fdo-arity-expand';
 #  $Oopt_FoldrBuildWW            = 0; # Off by default
@@ -267,7 +266,30 @@ $Lnkr              = ''; # "linker" is normally GCC
 $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-binds',
+                    '-fwarn-unused-imports');
+@MinusWallOpts           = (@MinusWOpts, 
+                    '-fwarn-unused-matches',
+                    '-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}
@@ -349,18 +371,14 @@ require special handling.
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
-# where to look for interface files (system hi's, i.e., prelude and hslibs)
+# where to look for interface files (system hi's, i.e., prelude and syslibs)
 @SysImport_dir = ( $INSTALLING )
-                   ? ( "$InstLibDirGhc/imports" )
-                   : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/required"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/ghc"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/glaExts"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent" );
+                   ? ( "$InstLibDirGhc/imports/std" )
+                   : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std" );
 
 # 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);
 $Haskell1Version = 4; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
@@ -371,8 +389,8 @@ $Haskell1Version = 4; # i.e., Haskell 1.4
                    ? $InstLibDirGhc
                    : ( "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR"
                      , "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/gmp"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/cbits"
+                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std"
+                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std/cbits"
                      )
                  );
 @SysLibrary = (); # will be built up as we go along
@@ -456,6 +474,7 @@ $HscOut = '-S='
 # TEMP: disable x86  if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
 $ProduceHi    = '-hifile=';
 $HiOnStdout   = 0;
+$HiWith       = '';
 $HiDiff_flag  = '';
 $Keep_HiDiffs = 0;
 
@@ -525,10 +544,10 @@ $LinkChk = 1;     # set to 0 if the link check should *not* be done
 
 # major & minor version numbers; major numbers must always agree;
 # minor disagreements yield a warning.
-$HsC_major_version = 33;
-$HsC_minor_version = 0;
-$Cc_major_version  = 36;
-$Cc_minor_version  = 1;
+$HsC_major_version = $HscMajorVersion;
+$HsC_minor_version = $HscMinorVersion;
+$Cc_major_version  = $CcMajorVersion;
+$Cc_minor_version  = $CcMinorVersion;
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
@@ -546,37 +565,6 @@ $Cc_consist_options  = '';    # we record, in this order:
 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.
@@ -589,6 +577,10 @@ if (  $Status == 0 && $Only_generate_deps ) {
     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;
@@ -693,11 +685,12 @@ sub setupOptimiseFlags {
 
    @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...
@@ -712,10 +705,20 @@ sub setupOptimiseFlags {
 #        '-fsimpl-uf-use-threshold0',
 #        '-fessential-unfoldings-only',
 
-         $Oopt_UnfoldingUseThreshold,
+         #
+         # The presence of -fclone-binds is *temporary* to work around
+          # the fact that the desugarer in 3.0{2.3} does generate
+         # bindings with identical ids, and the type checker doesn't perform
+         # properly cloned type substitutions. Instead, we make sure that all 
+         # binders are cloned first time through the simplifier.
+          #
+         # Will be properly fixed in the `new compiler` I hear, at which point
+         # the cloning can be turned off here.
+          '-fclone-binds',
+
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
-         '\)',
+         ']',
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
        
@@ -728,7 +731,7 @@ sub setupOptimiseFlags {
 
        # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
 
@@ -748,9 +751,12 @@ sub setupOptimiseFlags {
 #        '-fessential-unfoldings-only',
 #        '-fsimpl-uf-use-threshold0',
 
+         # See remark re: cloning in defn of minusnotO
+         '-fclone-binds',
+
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
-         '\)',
+         ']',
 
        ($Oopt_DoSpecialise) ? (
          '-fspecialise-overloaded',
@@ -759,7 +765,7 @@ sub setupOptimiseFlags {
        ) : (),
 
        '-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',
@@ -771,10 +777,18 @@ sub setupOptimiseFlags {
          '-freuse-con',
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
-         '\)',
+         #
+         # The presence of -fclone-binds is *crucial* here as
+         # -ffull-laziness (which we're about to do next) floats
+         # bindings outwards, so we better make sure that this
+         # doesn't result in the floating out of bindings
+         # with identical uniques, i.e., -ffull-laziness needs
+         # to be preceeded by a simplifier pass with -fclone-binds
+         # set.
+          '-fclone-binds',
+         ']',
 
 #LATER:        '-fcalc-inlinings1', -- pointless for 2.01
 
@@ -782,7 +796,7 @@ sub setupOptimiseFlags {
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
-#                '\(', 
+#                '[', 
 #                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
@@ -794,10 +808,9 @@ sub setupOptimiseFlags {
 #                '-freuse-con',
 #                $Oopt_PedanticBottoms,
 #                $Oopt_MonadEtaExpansion,
-#                $Oopt_UnfoldingUseThreshold,
 #                $Oopt_MaxSimplifierIterations,
 #                $Oopt_ShowSimplifierProgress,
-#                '\)',
+#                ']',
 #       ) : (),
 
        # this pass-ordering sequence was agreed by Simon and Andr\'e
@@ -808,7 +821,7 @@ sub setupOptimiseFlags {
          '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
 
          '-fsimplify', 
-           '\(', 
+           '[', 
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
            $Oopt_FB_Support,
@@ -822,16 +835,15 @@ sub setupOptimiseFlags {
            '-freuse-con',
            $Oopt_PedanticBottoms,
            $Oopt_MonadEtaExpansion,
-           $Oopt_UnfoldingUseThreshold,
            $Oopt_MaxSimplifierIterations,
            $Oopt_ShowSimplifierProgress,
-           '\)',
+           ']',
        ) : (),
 
        '-ffloat-inwards',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -847,15 +859,14 @@ sub setupOptimiseFlags {
                        # but do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
-         '\)',
+         ']',
 
        '-fstrictness',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -868,10 +879,9 @@ sub setupOptimiseFlags {
          '-flet-to-case',              # Aha! Only done after strictness analysis
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
-         '\)',
+         ']',
 
        '-ffloat-inwards',
 
@@ -880,12 +890,12 @@ sub setupOptimiseFlags {
 
 #      ( ($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 $Oopt_ShowSimplifierProgress \\)" ),
+#      : "-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_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
 
 # Final clean-up simplification:
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -902,17 +912,15 @@ sub setupOptimiseFlags {
                        # but still do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
-         '\)',
+         ']',
 
       #        '-fstatic-args',
 
 #LATER:        '-fcalc-inlinings2', -- pointless for 2.01
 
       # stg2stg passes
-       '-fupdate-analysis',
        '-flambda-lift',
        $Oopt_FinalStgProfilingMassage,
        $Oopt_StgStats,
@@ -922,6 +930,7 @@ sub setupOptimiseFlags {
 
       # SPECIAL FLAGS for -O2
        ($OptLevel == 2) ? (
+         '-fupdate-analysis',  # virtually useless; relegated to -O2
          '-fsemi-tagging',
        ) : (),
       );
@@ -952,6 +961,8 @@ if ( $OptLevel <= 0 ) {
 } 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...
 }
 
@@ -986,6 +997,9 @@ sub setupBuildFlags {
 
       $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
+      # Ignore user sccs when auto annotating, but warn when doing so.
+      $PROFignore_scc = '-W' if $PROFauto; 
+
       push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S'));
 
       if ( $SplitObjFiles ) {
@@ -1173,6 +1187,23 @@ sub setupMachOpts {
 } # 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
@@ -1192,7 +1223,6 @@ sub setupLinkOpts {
           ,'-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-/) {
@@ -1314,8 +1344,8 @@ if ($#Input_file < 0 && $#Link_file < 0) {
     @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");
 }
 
@@ -1323,7 +1353,7 @@ if ($#Input_file < 0 && $#Link_file < 0) {
 
 Tell the world who we are, if they asked.
 \begin{code}
-print STDERR "${PROJECTNAME}, version ${PROJECTVERSION}, patchlevel ${PROJECTPATCHLEVEL}\n"
+print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"
     if $Verbose;
 \end{code}
 
@@ -1366,8 +1396,14 @@ if ($Do_lnkr) {
     # for a linker, use an explicitly given one, or the going C compiler ...
     local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd;
 
+    if ( ($Specific_output_file eq '') && 
+         ($TargetPlatform eq 'i386-unknown-cygwin32') ) {
+         $Specific_output_file = 'main.exe';
+         print STDERR "Output file not specified, defaulting to \"main.exe\"\n";
+    }
+
     local($output) = ($Specific_output_file ne '') ? "-o $Specific_output_file" : '';
-    @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out';
+    @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out'; 
 
     local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary";
     &run_something($to_do, 'Linker');
@@ -1414,7 +1450,7 @@ eval 'exec perl -S \$0 \${1+"\$@"}'
   if \$running_under_some_shell;
 # =!=!=!=!=!=!=!=!=!=!=!
 # This script is automatically generated: DO NOT EDIT!!!
-# Generated by Glasgow Haskell, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}
+# Generated by Glasgow Haskell, version ${ProjectVersion} ${ProjectPatchLevel}
 #
 \$pvm_executable      = '$pvm_executable';
 \$pvm_executable_base = '$pvm_executable_base';
@@ -1483,6 +1519,8 @@ sub ProcessInputFile {
                          # from input file (need to know for recomp
                          # checking purposes)
     local($hifile_target);# ditto (but .hi file)
+    local($ofile_c_stub_target); 
+    local($ofile_h_stub_target); 
 \end{code}
 
 Handle the weirdity of input from stdin.
@@ -1497,6 +1535,8 @@ Handle the weirdity of input from stdin.
                        ? $Specific_hi_file
                        : "$ifile_root.$HiSuffix"; # ToDo: odirify?
                        # NB: may change if $ifile_root isn't module name (??)
+       ($ofile_c_stub_target = $ifile) =~s/\.[^\.\/]+$/_stub.c/;
+       ($ofile_h_stub_target = $ifile) =~s/\.[^\.\/]+$/_stub.h/;
     } else {
        $ifile = "$Tmp_prefix.hs"; # we know that's where we put the input
        $ifile_root   = '_stdin';
@@ -1536,7 +1576,7 @@ Again, we'll do the post-recompilation-checker parts of this later.
     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;
@@ -1547,7 +1587,8 @@ Again, we'll do the post-recompilation-checker parts of this later.
 
     # 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).
@@ -1573,6 +1614,7 @@ Again, we'll do the post-recompilation-checker parts of this later.
     &setupOptimiseFlags();
     &setupMachOpts();
     &setupIncPaths();
+    &setupWarningFlags();
     &setupHeapStackSize();
 
     #
@@ -1585,7 +1627,9 @@ Again, we'll do the post-recompilation-checker parts of this later.
                          ? $Do_cc
                          : ( ($HscOut eq '-C=') ? 1 : 0 );
     local($do_as)      = $Do_as;
-    local($hsc_out)      = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
+    local($hsc_out)       = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
+    local($hsc_out_c_stub) = ( $HscOut eq '-C=' ) ? "${Tmp_prefix}_stb.c" : "";
+    local($hsc_out_h_stub) = ( $HscOut eq '-C=' ) ? "${Tmp_prefix}_stb.h" : "";
 
     if ($Only_preprocess_hc) { # stop after having run $Cc -E
        $do_as=0;
@@ -1597,9 +1641,13 @@ Again, we'll do the post-recompilation-checker parts of this later.
     } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        $hsc_out = $ifile;
+       $hsc_out_c_stub = '';
+       $hsc_out_h_stub = '';
     } elsif ($ifile =~ /\.c$/) {
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        $hsc_out = $ifile; $is_hc_file = 0;
+       $hsc_out_c_stub = '';
+       $hsc_out_h_stub = '';
     } elsif ($ifile =~ /\.s$/) {
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 0;
        $cc_as = $ifile;    
@@ -1656,7 +1704,16 @@ Now the Haskell compiler, C compiler, and assembler
 \begin{code}
    if ($do_hsc) {
        &runHscAndProcessInterfaces( $ifile, $hscpp_hsc, $ifile_root, 
-                                    $ofile_target, $hifile_target);
+                                    $ofile_target, $hifile_target,
+                                    $going_interactive);
+    }
+
+    if (-f $hsc_out_c_stub) {
+       &run_something("cp $hsc_out_c_stub $ofile_c_stub_target", 'Copy foreign export C stubs');
+    }
+
+    if (-f $hsc_out_h_stub) {
+       &run_something("cp $hsc_out_h_stub $ofile_h_stub_target", 'Copy foreign export header file');
     }
 
     if ($do_cc) {
@@ -1678,10 +1735,15 @@ Finally, decide what to queue up for linker input.
 
 #ToDo:    local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix";
 
-    if ( $ifile !~ /\.(lhs|hs|hc|c|s)$/ && $ifile !~ /_hc$/ ) {
-       print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n"
-           if $ifile !~ /\.a$/;
 
+    if ( $ifile !~ /\.(lhs|hs|hc|c|s|a)$/ && $ifile !~ /_hc$/ ) {
+        # There's sometimes confusion regarding .hi files; users
+       # supplying them on the command line.
+        if ( $ifile =~ /\.hi$/ ) {
+           print STDERR "$Pgm: warning: found `$ifile' on command line; interface files should not be supplied here - ignoring it.\n";
+        } else {
+          print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n";
+        }
        # oops; we tentatively pushed the wrong thing; fix & do the right thing
        pop(@Link_file); push(@Link_file, $ifile);
     }
@@ -1700,9 +1762,13 @@ Finally, decide what to queue up for linker input.
 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');
 }
@@ -1712,18 +1778,24 @@ sub runLit2pgm {
 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 @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$ProjectVersionInt $includes $lit2pgm_hscpp >> $hscpp_hsc";
+       push(@Files_to_tidy, $hscpp_hsc );
        &run_something($to_do, 'Haskellised C pre-processor');
     }
    
@@ -1738,7 +1810,9 @@ sub runHscpp {
 
 \begin{code}
 sub runHscAndProcessInterfaces {
-    local($ifile, $hscpp_hsc, $ifile_root, $ofile_target, $hifile_target) = @_;
+    local($ifile, $hscpp_hsc, $ifile_root, 
+          $ofile_target, $hifile_target,
+         $going_interactive) = @_;
 
        # $ifile                is the original input file
        # $hscpp_hsc            post-unlit, post-cpp, etc., input file
@@ -1756,7 +1830,7 @@ sub runHscAndProcessInterfaces {
      $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;
     }
@@ -1764,7 +1838,7 @@ sub runHscAndProcessInterfaces {
     ($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;
     }
@@ -1772,11 +1846,14 @@ sub runHscAndProcessInterfaces {
     ($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;
     }
 
+    # Tell the compiler which version we're using
+    push(@HsC_flags, "-fhi-version=${ProjectVersionInt}");
+
     # So if source_unchanged is still "1", we pass on the good news to the compiler
     # The -recomp flag can disable this, forcing recompilation
     if ($Do_recomp_chkr && $source_unchanged) {
@@ -1785,7 +1862,7 @@ sub runHscAndProcessInterfaces {
 
     # Run the compiler
 
-    &runHsc($ifile_root, $hsc_out, $hsc_hi, $going_interactive);
+    &runHsc($ifile_root, $hsc_out, $hsc_hi, $hsc_out_c_stub, $hsc_out_h_stub, $going_interactive);
 
    # See if it bailed out early, saying nothing needed doing.  
    # We work this out by seeing if it created an output .hi file
@@ -1858,29 +1935,28 @@ sub runHscAndProcessInterfaces {
 
 \begin{code}
 sub runHsc {
-    local($ifile_root, $hsc_out, $hsc_hi, $going_interactive) = @_;
+    local($ifile_root, $hsc_out, $hsc_hi, $hsc_out_c_stub, $hsc_out_h_stub, $going_interactive) = @_;
 
     # prepend comma to HsP flags (so hsc can tell them apart...)
     foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
     &makeHiMap() unless $HiMapDone;
-    #print STDERR "HiIncludes: $HiIncludeString\n";
     push(@HsC_flags, "-himap=$HiIncludeString");
 
     # 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:
+       # don't need .hi unless we're going to show it on stdout:
        $ProduceHi = '-nohifile=' if ! $HiOnStdout;
        $do_cc = 0; $do_as = 0; $Do_lnkr = 0; # and we won't go any further...
     }
 
     # 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 );
+    $output = "$ProduceHi$hsc_hi $HscOut$hsc_out -F=$hsc_out_c_stub -FH=$hsc_out_h_stub";
+    push(@Files_to_tidy, $hsc_hi, $hsc_out, $hsc_out_c_stub, $hsc_out_h_stub );
 
     # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
     if ( $CollectingGCstats ) {
@@ -1903,7 +1979,28 @@ sub runHsc {
     }
 
     local($to_do);
-    $to_do = "$HsC @HsP_flags ,$hscpp_hsc $dump @HsC_flags $CoreLint $StgLint $Verbose $output +RTS @HsC_rts_flags";
+    # Win32 only: If the command processor used by system()
+    # exec()s the application as an ordinary Win32 executable,
+    # we're in trouble here, since the command line is likely
+    # to be > 255 chars long. To work around this situation,
+    # $HsC also understands `at-files',  i.e., `@file' on the
+    # command line will cause $HsC to add the contents of `file'
+    # to the command line.
+    #
+    #  [ Note: support for `at-files' is not compiled in by default ]
+    $cmd_line_opts_via_at_file=0;
+    if ($cmd_line_opts_via_at_file) {
+
+      local($to_do_opts) = "$Tmp_prefix.opts";
+      open(OPTS, "> $Tmp_prefix.opts") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.opts\n");
+      print OPTS "$dump @HsC_flags $CoreLint $StgLint $Verbose";
+      close(OPTS);
+      $to_do = "$HsC @HsP_flags ,$hscpp_hsc \@$Tmp_prefix.opts $output +RTS @HsC_rts_flags";
+
+    } else {
+
+      $to_do = "$HsC @HsP_flags ,$hscpp_hsc $dump @HsC_flags $CoreLint $StgLint $Verbose $output +RTS @HsC_rts_flags";
+    }
     &run_something($to_do, 'Haskell compiler');
 
     # finish business w/ nofibbish time/bytes-alloc stats
@@ -2014,11 +2111,14 @@ sub runGcc {
 EOINCL
        # user may have asked for #includes to be injected...
        print TMP @CcInjects if $#CcInjects >= 0;
+    } else {
+       # Straight .c files may want to know that they're being used
+       # with a particular version of GHC, so we define __GLASGOW_HASKELL__ for their benefit.
+        print TMP "#define __GLASGOW_HASKELL__ ${ProjectVersionInt}\n";
     }
     # heave in the consistency info
     print TMP "static char ghc_cc_ID[] = \"\@(#)cc $ifile\t$Cc_major_version.$Cc_minor_version,$Cc_consist_options\";\n";
 
-    # and #include the real source
     print TMP "#include \"$hsc_out\"\n";
     close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
 
@@ -2030,7 +2130,7 @@ EOINCL
     if ( $Only_preprocess_hc ) { # HACK ALERT!
        $to_do =~ s/ -S\b//g;
     }
-    @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output );
+    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;
@@ -2110,7 +2210,7 @@ sub runAs {
 
     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...
@@ -2130,7 +2230,7 @@ sub runAs {
        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');
        }
@@ -2210,7 +2310,6 @@ sub run_something {
         if ($Using_dump_file) {
            print STDERR "Compilation Errors dumped in $Specific_dump_file\n";
        }
-
        &tidy_up_and_die($return_val, '');
     }
     $Using_dump_file = 0;
@@ -2249,7 +2348,9 @@ sub process_ghc_timings {
 
         $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;
@@ -2393,6 +2494,197 @@ sub add_Hsc_flags {
 }
 \end{code}
 
+To add another system library, you'll need to augment the
+Supported_syslibs variable with name and info on your addition
+to the syslib family. The info bit consist of the following:
+
+   - interface file directory
+       see the misc or posix entry for how to distinguish
+       between using installed and build tree directories.
+       
+   - directory location of archives
+       
+   - location of (way-independent) C support libs.
+       not all libraries need this - if you don't, just
+       give the empty string.
+   - list of syslibs you depend on.
+
+   - additional ghc command line flags that should be used.
+   - additional C compiler command line flags that should be used.
+   - link 
+
+
+\begin{code}
+
+# Hash to keep track of 
+%Syslibs_added = ();
+
+sub add_syslib {
+    local($syslib) = @_;
+
+    # Lifting this out of this sub brings it out of scope - why??
+    %Supported_syslibs =
+     ( exts,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/exts"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/exts"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/exts"
+         )
+       , '' # no cbits
+       , '' # Syslib dependencies
+       , '' # extra ghc opts
+       , '' # extra cc opts
+       , '' # extra ld opts
+       ],
+
+       misc,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/misc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc"
+         )
+       , # where to find the cbits archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc/cbits"
+         )
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , ( $TargetPlatform =~ /-solaris2$/  ? '-lnsl -lsocket' : '')
+       ],
+       hbc,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/hbc"
+              : "$TopPwd/CONTRIB/libraries/hbc/src"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/CONTRIB/libraries/src/hbc"
+         )
+       , # where to find the cbits archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/CONTRIB/libraries/hbc/cbits"
+         )
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , ''
+       ],
+       posix,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/posix"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix"
+         )
+       , # where to find the cbits archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix/cbits"
+         )
+       , 'misc' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , ''     # extra ld opts
+       ],
+       concurrent,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/concurrent"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent"
+         )
+       , '' # where to find the cbits archive to use when linking
+       , '' # Syslib dependencies
+       , '' # extra ghc opts
+       , '' # extra cc opts
+       , '' # extra ld opts
+       ],
+       win32,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/win32"
+              : "$TopPwd/hslibs/win32/src"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/hslibs/win32/src"
+         )
+       , ''
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , '-luser32 -lgdi32'     # extra ld opts
+       ]
+    );
+
+    # check if it's supported..
+    
+    if ( !exists $Supported_syslibs{$syslib} ) {
+       print STDERR "$Pgm: no such system library (-syslib): $syslib\n";
+       $Status++;
+       return;
+    }
+
+    # This check is here to avoid syslib loops from
+    # spoiling the party. A side-effect of it is that
+    # it disallows multiple mentions of a syslib on a command-line,
+    # explicit *and* implicit ones (i.e., "-syslib exts -syslib misc"
+    # is not equal to "-syslib exts -syslib misc -syslib exts",
+    # which it needs to be)
+    # 
+    # Since our current collection of syslibs don't have any
+    # loops, this test is disabled.
+    #
+    # ToDo: loop avoidance scheme when the need arises
+    #
+    #return if ( exists $Syslibs_added{$syslib} );
+       
+    $Syslibs_added{$syslib} = 1;
+
+    local ($hi_dir, $lib_dir, $lib_cbits_dir,
+          $syslib_deps, $syslib_ghc_opts,
+          $syslib_cc_opts, $syslib_ld_opts) = @{ $Supported_syslibs{$syslib} };
+
+
+    unshift(@SysImport_dir, $hi_dir);
+    push(@SysLibrary_dir, $lib_dir);
+    push(@SysLibrary_dir, $lib_cbits_dir) if ( $lib_cbits_dir ne '');
+
+    push(@SysLibrary, "-lHS$syslib");
+    push(@SysLibrary, "-lHS${syslib}_cbits") if ( $lib_cbits_dir ne '');
+    push(@SysLibrary, $syslib_ld_opts) if ($syslib_ld_opts ne '');   
+
+    # Add on any extra dependencies.
+    foreach $lib (split(' ',$syslib_deps)) {
+      &add_syslib($lib);
+    }
+}
+\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
@@ -2426,7 +2718,10 @@ sub check_for_source_options {
         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
@@ -2460,7 +2755,7 @@ arg: while($_ = $args[0]) {
        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, $_);
@@ -2520,13 +2815,13 @@ arg: while($_ = $Args[0]) {
     if (/^-\?$/ || /^--?help$/) { print $LongUsage; exit $Status; }
 
     #-----------version ----------------------------------------------------
-    /^--version$/   && do { print STDERR "${PROJECTNAME}, version ${PROJECTVERSION}, patchlevel ${PROJECTPATCHLEVEL}\n"; exit $Status; };
+    /^--version$/   && do { print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"; exit $Status; };
 
     #---------- verbosity and such -----------------------------------------
     /^-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:
@@ -2541,8 +2836,11 @@ arg: while($_ = $Args[0]) {
                            next arg; };
     # leave out actual C generation (debugging) [also turns off interface gen]
 
-    /^-hi$/        && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; };
+
+    /^-hi$/             && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; };
     # _do_ generate an interface; usually used as: -noC -hi
+    /^-hi-with-(.*)$/    && do { $HiOnStdout = 1; $HiWith .= " $1" ; $ProduceHi = '-hifile='; next arg; };
+    # limit ourselves to outputting a particular section.
 
     /^-nohi$/      && do { $ProduceHi = '-nohifile='; next arg; };
     # don't generate an interface (even if generating C)
@@ -2691,10 +2989,11 @@ arg: while($_ = $Args[0]) {
     #--------- ticky/concurrent/parallel -----------------------------------
     # we sort out the details a bit later on
 
-    /^-concurrent$/ && do { $CONCURing = 'c'; next arg; }; # concurrent Haskell
-    /^-gransim$/    && do { $GRANing   = 'g'; next arg; }; # GranSim
+    /^-concurrent$/ && do { $CONCURing = 'c'; &add_syslib('concurrent'); next arg; }; 
+                         # concurrent Haskell; implies -syslib conc
+    /^-gransim$/    && do { $GRANing   = 'g'; &add_syslib('concurrent'); next arg; }; # GranSim
     /^-ticky$/     && do { $TICKYing  = 't'; next arg; }; # ticky-ticky
-    /^-parallel$/   && do { $PARing    = 'p'; next arg; }; # parallel Haskell
+    /^-parallel$/   && do { $PARing    = 'p'; &add_syslib('concurrent'); next arg; }; # parallel Haskell
 
     #-------------- "user ways" --------------------------------------------
 
@@ -2730,27 +3029,7 @@ arg: while($_ = $Args[0]) {
     /^-l(.*)/      && do { push(@UserLibrary,'-l'.&grab_arg_arg(*Args,'-l', $1)); next arg; };
 
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
-                           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"));
-                           }
-
-                           push(@SysLibrary, "-lHS$syslib");
-                           push(@SysLibrary, "-lHS${syslib}_cbits")
-                             unless $syslib eq 'contrib'; #HACK! it has no cbits
-
+                           &add_syslib($syslib);
                            next arg; };
 
     #=======================================================================
@@ -2774,6 +3053,7 @@ arg: while($_ = $Args[0]) {
     /^-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; };
+    /^-optp(.*)$/   && do { push(@HsP_flags,        $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; };
@@ -2784,10 +3064,6 @@ arg: while($_ = $Args[0]) {
     /^-D(.*)/      && do { push(@HsCpp_flags, "'-D".&grab_arg_arg(*Args,'-D',$1)."'"); next arg; };
     /^-U(.*)/      && do { push(@HsCpp_flags, "'-U".&grab_arg_arg(*Args,'-U',$1)."'"); next arg; };
 
-    /^-genSPECS/   && do { $Cpp_flag_set = 1;
-                          $genSPECS_flag = $_;
-                           next arg; };
-
     #---------- post-Haskell "assembler"------------------------------------
     /^-ddump-raw-asm$/           && do { $Dump_raw_asm        = 1; next arg; };
     /^-ddump-asm-splitting-info$/ && do { $Dump_asm_splitting_info = 1; next arg; };
@@ -2818,9 +3094,6 @@ arg: while($_ = $Args[0]) {
     /^-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;
@@ -2837,11 +3110,14 @@ arg: while($_ = $Args[0]) {
                        }
                        next arg; };
 
+    /^-fallow-overlapping-instances$/ && do { push(@HsC_flags, $_); 
+                                             next arg; };
     /^-fglasgow-exts$/
                && do { push(@HsC_flags, $_);
                        push(@HsP_flags, '-N');
 
-#                      push(@HsC_flags, '-fshow-import-specs');
+                       # -fglasgow-exts implies -syslib exts
+                       &add_syslib('exts');
 
                        next arg; };
 
@@ -2893,9 +3169,11 @@ arg: while($_ = $Args[0]) {
 
     # ---------------
 
-    /^(-funfolding-use-threshold)(.*)$/
-                   && do { $Oopt_UnfoldingUseThreshold = $1 . &grab_arg_arg(*Args,$1, $2);
-                           next arg; };
+    /^-funfolding-.*$/
+                   && do { push(@HsC_flags, $_); next arg };
+
+    /^-funfold-casms-in-hi-file$/
+                   && do { push(@HsC_flags, $_); next arg };
 
     /^(-fmax-simplifier-iterations)(.*)$/
                    && do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2);
@@ -2930,15 +3208,27 @@ arg: while($_ = $Args[0]) {
     /^-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; };
+
+    # --------------- fun stuff ----------------
+
+    /^-freport-compile$/ && do { push(@HsC_flags, $_); next arg; };
+
     # --------------- platform specific flags (for gcc mostly) ----------------
 
     /^-mlong-calls$/ && do { # for GCC for HP-PA boxes,
@@ -3001,7 +3291,7 @@ arg: while($_ = $Args[0]) {
        }
        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]$/) {