X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdriver%2Fghc.lprl;h=a6ff27cac6a743e97429f06395801a4e85ed2c50;hb=cdcdeff92e6fa701370f8df616081cbcf466f9b0;hp=f48a3110f00f7d4dbb77bc4566d42f6c633a21e4;hpb=d9eb68cf8382efdeb8f8e127044ef865a0dcc82a;p=ghc-hetmet.git diff --git a/ghc/driver/ghc.lprl b/ghc/driver/ghc.lprl index f48a311..a6ff27c 100644 --- a/ghc/driver/ghc.lprl +++ b/ghc/driver/ghc.lprl @@ -12,6 +12,8 @@ It is written in \tr{perl}. The first section includes a long %************************************************************************ \begin{code} +use 5; # require Perl version 5 or later. + ($Pgm = $0) =~ s|.*/||; $ShortUsage = "\nUsage: For basic information, try the `-help' option.\n"; $LongUsage = "\n" . < produce code for DLLs (when compiling/linking.) +# static = 0 => produce code for DLLs (when compiling & linking.) $Static = 1; -$Static = 0 if ($TargetPlatform =~ /-mingw32$/); +$Static = 0 if ($EnableWin32DLLs eq 'YES'); -# native code-gen or via C? +# Output language $HaveNativeCodeGen = $GhcWithNativeCodeGen; -$HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither -$HscOut = '-S=' - if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha)-/; +$HscLang = 'C'; # 'C' ==> .hc output; + # 'asm' ==> .s output; + # 'java' ==> .java output + # 'none' ==> no code output +$HscLang = 'asm' + if ($HaveNativeCodeGen ne 'YES') && $TargetPlatform =~ /^(alpha)-/; + # TEMP: disable x86 & Sparc if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/; $ProduceHi = '-hifile='; $HiOnStdout = 0; @@ -482,14 +482,15 @@ $CollectingGCstats = 0; $CollectGhcTimings = 0; $DEBUGging = ''; # -DDEBUG and all that it entails (um... not really) $PROFing = ''; # set to p or e if profiling -$PROFgroup = ''; # set to group if an explicit -Ggroup specified $PROFauto = ''; # set to relevant hsc flag if -auto or -auto-all $PROFcaf = ''; # set to relevant hsc flag if -caf-all +$PROFdict = ''; # set to relevant hsc flag if -auto-dicts $PROFignore_scc = ''; # set to relevant parser flag if explicit sccs ignored $UNPROFscc_auto = ''; # set to relevant hsc flag if forcing auto sccs without profiling $TICKYing = ''; # set to t if compiling for ticky-ticky profiling $PARing = ''; # set to p if compiling for PAR $GRANing = ''; # set to g if compiling for GRAN +$UNREGing = ($GhcWithRegisterised eq 'YES') ? '' : 'u'; $Specific_hi_file = ''; # set by -ohi ; "-" for stdout $Specific_dump_file = ''; # set by -odump ; "-" for stdout $Using_dump_file = 0; @@ -497,7 +498,8 @@ $Isuffix = ''; $Osuffix = ''; # default: use the normal suffix for that kind of output $HiSuffix = 'hi'; $HiSuffix_prelude = ''; -$Do_recomp_chkr = 0; # don't use the recompilatio checker unless asked +$CompilingPrelude=0; +$Do_recomp_chkr = 1; # Use the recompilation checker by default $Do_cc = -1; # a MAGIC indeterminate value; will be set to 1 or 0. $Do_as = 1; @@ -576,7 +578,6 @@ Now slurp through the arguments. if ( $Status == 0 && $Only_generate_deps ) { push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix; - push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag; # They're not (currently) needed, but we need to quote any -#include options foreach (@Cmd_opts) { s/-#include.*$/'$&'/g; @@ -586,6 +587,13 @@ if ( $Status == 0 && $Only_generate_deps ) { exit $Status; } +# ..or just to construct a (Haskell) DLL. +if ( $Status == 0 && $Only_generate_dll && $EnableWin32DLLs ) { + + &createWin32DLL(); + exit $Status; +} + # if there are several input files, # we don't allow \tr{-o } or \tr{-ohi } options... # (except if linking, of course) @@ -673,225 +681,127 @@ The (outwards-)let-floater should be the {\em last} Core-to-Core pass that's run. (Um, well, howzabout the simplifier just once more...) \end{description} -STG-TO-STG PASSES: -\begin{description} -\item[\tr{-fupdate-analysis}:] -It really really wants to be the last STG-to-STG pass that is run. -\end{description} - \begin{code} sub setupOptimiseFlags { + # this pass-ordering sequence was agreed by Simon and Andr\'e + # (WDP 94/07, 94/11). + @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_PedanticBottoms, -# $Oopt_MonadEtaExpansion, # no thanks - -# These two work fine, if you really want no simplification at all, -# for bizarre test reasons. But you get really terrible code if you use them, -# for example: let x = e in x -# with dozens of redundant thunks etc. So I'm leaving them out. -# -# '-fsimpl-uf-use-threshold0', -# '-fessential-unfoldings-only', - - # - # 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. - # - # Let's find out.. - #'-fclone-binds', - - $Oopt_MaxSimplifierIterations, - $Oopt_ShowSimplifierProgress, + = ( + '-fsimplify', + '[', + $Oopt_MaxSimplifierIterations, ']', + $Oopt_AddAutoSccs, -# '-ffull-laziness', # removed 95/04 WDP following Andr\'e's lead - $Oopt_FinalStgProfilingMassage ); @HsC_minusO_flags # NOTE: used for *both* -O and -O2 (some conditional bits) = ( + '-ffoldr-build-on', + '-fdo-eta-reduction', + '-fdo-lambda-eta-expansion', + '-fcase-of-case', + '-fcase-merge', + '-flet-to-case', + $Oopt_PedanticBottoms, # initial simplify: mk specialiser happy: minimum effort please + '-fsimplify', '[', - $Oopt_FB_Support, - '-fkeep-spec-pragma-ids', # required before specialisation - -# I don't understand why we want -fessential-unfoldings-only here -# If we have it, the following nasty thing happens: -# f = E -# g* = f -# ...g... -# where "*" means exported. -# In the essential-unfoldings pass we still substitute f for g -# but we don't substitute E for f first. So we get -# f = E -# g* = f -# ...f... -# The g=f will get reverse-substituted later, but it's untidy. --SLPJ -# -# SDM: Here's why it's necessary. -# -# If we unfold in the first pass before the specialiser is run -# we miss opportunities for specialisation because eg. wrappers -# have been inlined for specialisable functions. -# -# This shows up in PrelArr.lhs - the specialised instance for newArray -# calls the generic rangeSize, because rangeSize is strict and is -# replaced by its wrapper by the simplifier. + '-finline-phase0', # Don't inline anything till full laziness has bitten + # In particular, inlining wrappers inhibits floating + # e.g. ...(case f x of ...)... + # ==> ...(case (case x of I# x# -> fw x#) of ...)... + # ==> ...(case x of I# x# -> case fw x# of ...)... + # and now the redex (f x) isn't floatable any more - '-fessential-unfoldings-only', - '-fsimpl-uf-use-threshold0', + '-fno-rules', # Similarly, don't apply any rules until after full laziness + # Notably, list fusion can prevent floating. - # See remark re: cloning in defn of minusnotO - '-fclone-binds', + '-fno-case-of-case', # Don't do case-of-case transformations. + # This makes full laziness work better - '-fdo-case-elim', - '-fmax-simplifier-iterations1', - $Oopt_PedanticBottoms, + '-fmax-simplifier-iterations2', ']', - ($Oopt_DoSpecialise) ? ( - $Oopt_DoSpecialise, - ) : (), + # Specialisation is best done before full laziness + # so that overloaded functions have all their dictionary lambdas manifest + ($Oopt_DoSpecialise) ? ( $Oopt_DoSpecialise, ) : (), + '-ffloat-outwards', + '-ffloat-inwards', - '-fsimplify', # need dependency anal after specialiser ... - '[', # need tossing before calc-inlinings ... - $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', - $Oopt_PedanticBottoms, - $Oopt_MonadEtaExpansion, - $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', + '-fsimplify', + '[', + '-finline-phase1', + # Want to run with inline phase 1 after the specialiser to give + # maximum chance for fusion to work before we inline build/augment + # in phase 2. This made a difference in 'ansi' where an overloaded + # function wasn't inlined till too late. + $Oopt_MaxSimplifierIterations, ']', -# ($Oopt_FoldrBuildWW) ? ( -# '-ffoldr-build-ww-anal', -# '-ffoldr-build-worker-wrapper', -# '-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', -# $Oopt_PedanticBottoms, -# $Oopt_MonadEtaExpansion, -# $Oopt_MaxSimplifierIterations, -# $Oopt_ShowSimplifierProgress, -# ']', -# ) : (), + $Oopt_UsageSPInf, # infer usage information here in case we need it later. + # (add more of these where you need them --KSW 1999-04) - # this pass-ordering sequence was agreed by Simon and Andr\'e - # (WDP 94/07, 94/11). - '-ffull-laziness', - - ($Oopt_FoldrBuild) ? ( - '-ffoldr-build-on', # desugar list comprehensions for foldr/build - - '-fsimplify', - '[', - '-fignore-inline-pragma', # **** NB! - '-fdo-foldr-build', # NB - $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', # After full laziness - '-freuse-con', - $Oopt_PedanticBottoms, - $Oopt_MonadEtaExpansion, - $Oopt_MaxSimplifierIterations, - $Oopt_ShowSimplifierProgress, - ']', - ) : (), + '-fsimplify', + '[', + # Need inline-phase2 here so that build/augment get + # inlined. I found that spectral/hartel/genfft lost some useful + # strictness in the function sumcode' if augment is not inlined + # before strictness analysis runs + + '-finline-phase2', + '-fmax-simplifier-iterations2', + ']', - '-ffloat-inwards', '-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', - ($Oopt_FoldrBuildInline), - # you need to inline foldr and build - ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), - # but do reductions if you see them! - $Oopt_PedanticBottoms, - $Oopt_MonadEtaExpansion, - $Oopt_MaxSimplifierIterations, - $Oopt_ShowSimplifierProgress, + '-fmax-simplifier-iterations2', + # No -finline-phase: allow all Ids to be inlined now + # This gets foldr inlined before strictness analysis ']', '-fstrictness', + '-fcpr-analyse', + '-fworker-wrapper', '-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', # Aha! Only done after strictness analysis - $Oopt_PedanticBottoms, - $Oopt_MonadEtaExpansion, - $Oopt_MaxSimplifierIterations, - $Oopt_ShowSimplifierProgress, + $Oopt_MaxSimplifierIterations, + # No -finline-phase: allow all Ids to be inlined now ']', + '-ffloat-outwards', # nofib/spectral/hartel/wang doubles in speed if you + # do full laziness late in the day. It only happens + # after fusion and other stuff, so the early pass doesn't + # catch it. For the record, the redex is + # f_el22 (f_el21 r_midblock) + +# Leave out lambda lifting for now +# '-fsimplify', # Tidy up results of full laziness +# '[', +# '-fmax-simplifier-iterations2', +# ']', +# '-ffloat-outwards-full', + + # We want CSE to follow the final full-laziness pass, because it may + # succeed in commoning up things floated out by full laziness. + # + # CSE must immediately follow a simplification pass, because it relies + # on the no-shadowing invariant. See comments at the top of CSE.lhs + # So it must NOT follow float-inwards, which can give rise to shadowing, + # even if its input doesn't have shadows. Hence putting it between + # the two passes. + '-fcse', + + '-ffloat-inwards', # Case-liberation for -O2. This should be after @@ -899,38 +809,22 @@ 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_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-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ), + +# '-fliberate-case', # Final clean-up simplification: '-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', - '-fignore-inline-pragma', # **** NB! - $Oopt_FoldrBuildInline, - ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), - # but still do reductions if you see them! - $Oopt_PedanticBottoms, - $Oopt_MonadEtaExpansion, - $Oopt_MaxSimplifierIterations, - $Oopt_ShowSimplifierProgress, + $Oopt_MaxSimplifierIterations, + # No -finline-phase: allow all Ids to be inlined now ']', # '-fstatic-args', -#LATER: '-fcalc-inlinings2', -- pointless for 2.01 - # stg2stg passes - '-flambda-lift', +# '-flambda-lift', $Oopt_FinalStgProfilingMassage, $Oopt_StgStats, @@ -939,8 +833,7 @@ sub setupOptimiseFlags { # SPECIAL FLAGS for -O2 ($OptLevel == 2) ? ( - '-fupdate-analysis', # virtually useless; relegated to -O2 - '-fsemi-tagging', + # none at the present time ) : (), ); @@ -985,30 +878,24 @@ if ( $OptLevel <= 0 ) { %************************************************************************ Sort out @$BuildTag@, @$PROFing@, @$PARing@, -@$GRANing@, @$TICKYing@: +@$GRANing@, @$TICKYing@, @UNREGing@: \begin{code} sub setupBuildFlags { - # PROFILING stuff after argv mangling: if ( ! $PROFing ) { - # warn about any scc exprs found (in case scc used as identifier) - push(@HsP_flags, '-W'); - # add -auto sccs even if not profiling ! push(@HsC_flags, $UNPROFscc_auto) if $UNPROFscc_auto; } else { push(@HsC_flags, $PROFauto) if $PROFauto; push(@HsC_flags, $PROFcaf) if $PROFcaf; - #push(@HsC_flags, $PROFdict) if $PROFdict; + push(@HsC_flags, $PROFdict) if $PROFdict; $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 ( $BuildTag ne '' ) { # local($b) = $BuildDescr{$BuildTag}; @@ -1036,14 +923,21 @@ sub setupBuildFlags { exit(1); } + } elsif ( $SMPing eq 's') { + $BuildTag = '_s'; + } elsif ( $GRANing eq 'g' ) { if ($TICKYing eq 't') { print STDERR "$Pgm: Can't mix -gransim with -ticky.\n"; exit 1; } $BuildTag = '_mg'; } elsif ( $TICKYing eq 't' ) { $BuildTag = '_t'; - } + } elsif ( $UNREGing eq 'u' ) { + if ($GhcWithRegisterised eq 'YES') { + $BuildTag = '_u'; + } + } \end{code} After the sanity checks, add flags to the necessary parts of the driver pipeline: @@ -1052,9 +946,9 @@ After the sanity checks, add flags to the necessary parts of the driver pipeline if ( $BuildTag ne '' ) { # something other than normal sequential... local($Tag) = "${BuildTag}"; - $Tag =~ s/_//; # move the underscore to the back + $Tag =~ s/_//; # move the underscore to the back - $HscOut = '-C='; # must go via C + $HscLang = 'C'; # must go via C &processArgs(split(' ', $SetupOpts{$BuildTag})); # eval($EvaldSetupOpts{$BuildTag}); } @@ -1070,10 +964,16 @@ Decide what the consistency-checking options are in force for this run: # Funny place to put it, but why not. # if ( $HiSuffix_prelude eq '' ) { - local($Tag) = "${BuildTag}"; - $Tag =~ s/_//; - $Tag = "${Tag}_" if $Tag ne ''; - $HiSuffix_prelude="${Tag}hi"; + + if ($CompilingPrelude) { + $HiSuffix_prelude = "$HiSuffix" if $CompilingPrelude; + } else { + local($Tag) = "${BuildTag}"; + + $Tag =~ s/_//; + $Tag = "${Tag}_" if $Tag ne ''; + $HiSuffix_prelude="${Tag}hi"; + } } } # setupBuildFlags \end{code} @@ -1119,6 +1019,8 @@ sub setupMachOpts { unshift(@CcRegd_flags_hc, '-fno-defer-pop'); unshift(@CcRegd_flags_hc, '-fomit-frame-pointer'); unshift(@CcRegd_flags, "-DSTOLEN_X86_REGS=$StolenX86Regs"); + + unshift(@CcBoth_flags, ('-DDONT_WANT_WIN32_DLL_SUPPORT')) if ($Static); } elsif ($TargetPlatform =~ /^m68k-/) { # -fno-defer-pop : for the .hc files, we want all the pushing/ @@ -1182,8 +1084,8 @@ sub setupLinkOpts { unshift(@Ld_flags, ( '-u', "${uscore}PrelBase_Izh_static_info" ,'-u', "${uscore}PrelBase_Czh_static_info" - ,'-u', "${uscore}PrelBase_Fzh_static_info" - ,'-u', "${uscore}PrelBase_Dzh_static_info" + ,'-u', "${uscore}PrelFloat_Fzh_static_info" + ,'-u', "${uscore}PrelFloat_Dzh_static_info" ,'-u', "${uscore}PrelAddr_Azh_static_info" ,'-u', "${uscore}PrelAddr_Wzh_static_info" ,'-u', "${uscore}PrelAddr_I64zh_static_info" @@ -1191,18 +1093,23 @@ sub setupLinkOpts { ,'-u', "${uscore}PrelStable_StablePtr_static_info" ,'-u', "${uscore}PrelBase_Izh_con_info" ,'-u', "${uscore}PrelBase_Czh_con_info" - ,'-u', "${uscore}PrelBase_Fzh_con_info" - ,'-u', "${uscore}PrelBase_Dzh_con_info" + ,'-u', "${uscore}PrelFloat_Fzh_con_info" + ,'-u', "${uscore}PrelFloat_Dzh_con_info" ,'-u', "${uscore}PrelAddr_Azh_con_info" ,'-u', "${uscore}PrelAddr_Wzh_con_info" ,'-u', "${uscore}PrelAddr_I64zh_con_info" ,'-u', "${uscore}PrelAddr_W64zh_con_info" ,'-u', "${uscore}PrelStable_StablePtr_con_info" - ,'-u', "${uscore}PrelBase_False_static_closure" - ,'-u', "${uscore}PrelBase_True_static_closure" + ,'-u', "${uscore}PrelBase_False_closure" + ,'-u', "${uscore}PrelBase_True_closure" ,'-u', "${uscore}PrelPack_unpackCString_closure" ,'-u', "${uscore}PrelException_stackOverflow_closure" ,'-u', "${uscore}PrelException_heapOverflow_closure" + ,'-u', "${uscore}PrelException_NonTermination_closure" + ,'-u', "${uscore}PrelException_PutFullMVar_closure" + ,'-u', "${uscore}PrelException_BlockedOnDeadMVar_closure" + ,'-u', "${uscore}__init_Prelude" + ,'-u', "${uscore}__init_PrelMain" )); if (!$NoHaskellMain) { unshift (@Ld_flags,'-u', "${uscore}PrelMain_mainIO_closure"); @@ -1212,7 +1119,9 @@ sub setupLinkOpts { # unshift(@Ld_flags, ('-Xlinker -bbigtoc -Xlinker -bnoquiet')); unshift(@Ld_flags, ('-Xlinker -bbigtoc')); } - + if ($TargetPlatform =~ /^hppa/) { + unshift(@Ld_flags, ('-Xlinker +vnocompatwarnings')); + } } # end of setupLinkOpts @@ -1235,14 +1144,13 @@ sub setupIncPaths { push (@Include_dir, "$TopPwd/${CURRENT_DIR}/${GHC_INCLUDE_DIR}"); } else { push (@Include_dir, "$InstLibDirGhc/includes"); - push (@Include_dir, "$InstLibDirGhc/includes"); } } # end of setupIncPaths \end{code} \begin{code} sub setupSyslibs { - push(@SysLibrary, ( '-lHS', '-lHS_cbits' )); # basic I/O and prelude stuff + push(@SysLibrary, ( '-lHSstd', '-lHSstd_cbits' )); # basic I/O and prelude stuff local($f); foreach $f (@SysLibrary) { @@ -1258,7 +1166,10 @@ sub setupSyslibs { # to implement the itimers, since cygwin.dll does not # support it. Only reqd. for `ways' that use itimers. # - push(@SysLibrary, '-lwinmm') if $TargetPlatform eq 'i386-unknown-cygwin32'; + push(@SysLibrary, '-lwinmm') if ($TargetPlatform =~ /-(mingw32|cygwin32)$/); + # Note: currently only tested with mingw, may cause conflicts when linking + # with libcygwin.a + push(@SysLibrary, '-lwsock32') if ($TargetPlatform =~ /-(mingw32|cygwin32)$/); # Push the pvm libraries if ($BuildTag eq '_mp') { @@ -1342,8 +1253,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" - if $Verbose; +print STDERR "${ProjectName}, version ${ProjectVersion}\n" if $Verbose; \end{code} %************************************************************************ @@ -1359,149 +1269,15 @@ foreach $ifile (@Input_file) { &ProcessInputFile($ifile); } -if ( $Status > 0 ) { # don't link if there were errors... +# don't link if there were errors... +if ( $Status > 0 ) { print STDERR $ShortUsage; &tidy_up(); exit $Status; } -# append last minute flags linker and consistency flags -&setupBuildFlags(); -&setupSyslibs(); -&setupLinkOpts(); - -\end{code} - -Link if appropriate. -\begin{code} -if ($Do_lnkr) { - local($libdirs) = ''; - - # glue them together: - push(@UserLibrary_dir, @SysLibrary_dir); - - $libdirs = '-L' . join(' -L',@UserLibrary_dir) if $#UserLibrary_dir >= 0; - - # 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'; - - # - # Win32 DLLs - link with import libraries, not the real archives. - # - if ( $TargetPlatform =~ /-mingw32$/ && !$Static ) { - foreach $a ( @SysLibrary ) { - next if ($a eq '-lm'); - $a = "${a}_imp" if ($a =~ /^-l/); - } - push(@Link_file, ( $INSTALLING ) ? "$InstLibDirGhc/Main.o" - : "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/Main.o"); - push(@Link_file, ( $INSTALLING ) ? "$InstLibDirGhc/PrelMain.o" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/PrelMain.o"); - push(@Ld_flags, "-mno-cygwin"); - } - local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary"; - &run_something($to_do, 'Linker'); - - # finally, check the consistency info in the binary - local($executable) = $Files_to_tidy[0]; - @Files_to_tidy = (); # reset; we don't want to nuke it if it's inconsistent - - if ( $LinkChk ) { - # dynamically load consistency-chking code; then do it. - require('ghc-consist.prl') - || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-consist.prl!\n"); - - &chk_consistency_info ( $executable ); - } - - # if PVM parallel stuff, we do truly weird things. - # Essentially: (1) move the executable over to where PVM expects - # to find it. (2) create a script in place of the executable - # which will cause the program to be run, via SysMan. - if ( $PARing eq 'p' ) { - local($pvm_executable) = $executable; - local($pvm_executable_base); - - if ( $pvm_executable !~ /^\// ) { # a relative path name: make absolute - local($pwd) = `pwd`; - chop($pwd); - $pwd =~ s/^\/tmp_mnt//; - $pvm_executable = "$pwd/$pvm_executable"; - } - - $pvm_executable =~ s|/|=|g; # make /s into =s - $pvm_executable_base = $pvm_executable; - - $pvm_executable = $ENV{'PVM_ROOT'} . '/bin/' . $ENV{'PVM_ARCH'} - . "/$pvm_executable"; - - &run_something("$Rm -f $pvm_executable; $Cp -p $executable $pvm_executable && $Rm -f $executable", 'Moving binary to PVM land'); - - # OK, now create the magic script for "$executable" - open(EXEC, "> $executable") || &tidy_up_and_die(1,"$Pgm: couldn't open $executable to write!\n"); - print EXEC <"@. \begin{code} - local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin'; + local($going_interactive) = $HscLang eq 'none' || $ifile_root eq '_stdin'; # # Warning issued if -keep-hc-file-too is used without # -fvia-C (or the equivalent) # - if ( $HscOut ne '-C=' && $Keep_hc_file_too ) { + if ( $HscLang ne 'C' && $Keep_hc_file_too ) { 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 $hsc_out = ($Specific_output_file ne '') ? $Specific_output_file - : &odir_ify($ifile_root, ($HscOut eq '-C=') ? 'hc' : 's'); + : &odir_ify($ifile_root, $hsc_out_suffix); $ofile_target = $hsc_out; # reset } @@ -1715,13 +1497,17 @@ Now the Haskell compiler, C compiler, and assembler } if (-f $hsc_out_c_stub) { - &run_something("cp $hsc_out_c_stub $ofile_c_stub_target", 'Copy foreign export C stubs'); + &run_something("rm -f $ofile_c_stub_target && echo '#include \"${ofile_h_stub_target}\"' > $ofile_c_stub_target && cat $hsc_out_c_stub >> $ofile_c_stub_target", 'Copy foreign export C stubs'); local ($hsc_out_s_stub); local ($hsc_out_o_stub); ($ofile_s_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$/\.s/; - ($ofile_o_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$/\.o/; - &runGcc (0, $ofile_c_stub_target, $ofile_s_stub_target); - &runAs ($ofile_o_stub_target, $ofile_s_stub_target); + ($ofile_o_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$//; + + $ofile_o_stub_target = &osuf_ify($ofile_o_stub_target, "o"); + if ($do_cc) { + &runGcc (0, $ofile_c_stub_target, $ofile_s_stub_target); + &runAs ($ofile_o_stub_target, $ofile_s_stub_target); + } # # Bring the C stub protos into scope when compiling the .hc file. # @@ -1891,23 +1677,12 @@ sub runHscAndProcessInterfaces { # Tell the C compiler and assembler not to run $do_cc = 0; $do_as = 0; - # Update dependency info, touch both object file and - # interface file, so that the following invariant is - # maintained: - # - # a dependent module's interface file should after recompilation - # checking be newer than the interface files of its imports. - # - # That is, if module A's interface file changes, then module B - # (which import from A) needs to be checked. - # If A's change does not affect B, which causes the compiler to bail - # out early, we still need to touch the interface file of B. The reason - # for this is that B may export A's interface. + # Update dependency info, by touching the object file + # This records in the file system that the work of + # recompiling this module has been done # &run_something("touch $ofile_target", - "Touch $ofile_target, to propagate dependencies") if $HscOut ne '-N='; - &run_something("touch $hifile_target", - "Touch $hifile_target, to propagate dependencies") if $ProduceHi =~ /-nohifile=/ ; + "Touch $ofile_target, to propagate dependencies") if $HscLang ne 'none'; } else { @@ -1916,18 +1691,20 @@ sub runHscAndProcessInterfaces { # If non-interactive, heave in the consistency info at the end # NB: pretty hackish (depends on how $output is set) if ( ! $going_interactive ) { - if ( $HscOut eq '-C=' ) { - $to_do = "echo 'static char ghc_hsc_ID[] = \"\@(#)hsc $ifile\t$HsC_major_version.$HsC_minor_version,$HsC_consist_options\";' >> $hsc_out"; + if ( $HscLang eq 'C' ) { + $to_do = "echo 'static char ghc_hsc_ID[] = \"\@(#)hsc $ifile\t$HsC_major_version.$HsC_minor_version,$HsC_consist_options\";' >> $hsc_out"; - } elsif ( $HscOut eq '-S=' ) { + &run_something($to_do, 'Pin on Haskell consistency info'); + } elsif ( $HscLang eq 'asm' ) { local($consist) = "hsc.$ifile.$HsC_major_version.$HsC_minor_version.$HsC_consist_options"; $consist =~ s/,/./g; $consist =~ s/\//./g; $consist =~ s/-/_/g; $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly? $to_do = "echo '\n\t.text\n$consist:' >> $hsc_out"; + &run_something($to_do, 'Pin on Haskell consistency info'); } - &run_something($to_do, 'Pin on Haskell consistency info'); + # no consistency info for Java output files } @@ -1938,12 +1715,12 @@ sub runHscAndProcessInterfaces { } # if we're going to split up object files, # we inject split markers into the .hc file now - if ( $HscOut eq '-C=' && $SplitObjFiles ) { + if ( $HscLang eq 'C' && $SplitObjFiles ) { &inject_split_markers ( $hsc_out ); } # save a copy of the .hc file, even if we are carrying on... - if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) { + if ($HscLang eq 'C' && $do_cc && $Keep_hc_file_too) { &saveIntermediate($ifile_root , "hc" , $hsc_out); } @@ -1956,11 +1733,9 @@ sub runHscAndProcessInterfaces { sub runHsc { 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; - push(@HsC_flags, "-himap=$HiIncludeString"); + push(@HsC_flags, "\"-himap=$HiIncludeString\""); + push(@HsC_flags, "\"-himap-sep=${SplitMarker}\""); # here, we may produce .hc/.s and/or .hi files local($output) = ''; @@ -1974,7 +1749,8 @@ sub runHsc { # 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 -F=$hsc_out_c_stub -FH=$hsc_out_h_stub"; + $oflags = ( $HscLang eq 'none' ? "" : "-olang=$HscLang -ofile=$hsc_out" ) ; + $output = "$ProduceHi$hsc_hi $oflags -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 @@ -1987,7 +1763,7 @@ sub runHsc { # 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(@HsC_rts_flags, "-S$Tmp_prefix.stat"); push(@Files_to_tidy, "$Tmp_prefix.stat"); } @@ -2012,13 +1788,13 @@ sub runHsc { 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"; + print OPTS "$dump @HsC_flags $CoreLint $USPLint $StgLint $Verbose"; close(OPTS); - $to_do = "$HsC @HsP_flags ,$hscpp_hsc \@$Tmp_prefix.opts $output +RTS @HsC_rts_flags"; + $to_do = "$HsC $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"; + $to_do = "$HsC $hscpp_hsc $dump @HsC_flags $CoreLint $USPLint $StgLint $Verbose $output +RTS @HsC_rts_flags"; } &run_something($to_do, 'Haskell compiler'); @@ -2045,7 +1821,7 @@ sub makeHiMap { foreach $d ( @Import_dir ) { if ($HiIncludeString) { - $HiIncludeString = "$HiIncludeString:${d}%.${HiSuffix}"; + $HiIncludeString = "$HiIncludeString${SplitMarker}${d}%.${HiSuffix}"; } else { $HiIncludeString = "$d%.${HiSuffix}"; } @@ -2054,7 +1830,7 @@ sub makeHiMap { foreach $d ( @SysImport_dir ) { if ($HiIncludeString) { - $HiIncludeString = "$HiIncludeString:${d}%.${HiSuffix_prelude}"; + $HiIncludeString = "$HiIncludeString${SplitMarker}${d}%.${HiSuffix_prelude}"; } else { $HiIncludeString = "${d}%.${HiSuffix_prelude}"; } @@ -2065,6 +1841,212 @@ sub makeHiMap { \end{code} +Invoke the 'linker' - either the standard linker or the one used to build +a (Win32) DLL. + +\begin{code} +sub runLinker +{ + local($libdirs) = ''; + + # append last minute flags linker and consistency flags + &setupBuildFlags(); + &setupSyslibs(); + &setupLinkOpts(); + + # glue them together: + push(@UserLibrary_dir, @SysLibrary_dir); + + $libdirs = '-L' . join(' -L',@UserLibrary_dir) if $#UserLibrary_dir >= 0; + + # 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') || + ($TargetPlatform eq 'i386-unknown-mingw32')) ) { + $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'; + + &prepareWin32DllLink(1); + + local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $libdirs @UserLibrary @SysLibrary"; + &run_something($to_do, 'Linker'); + + # finally, check the consistency info in the binary + local($executable) = $Files_to_tidy[0]; + @Files_to_tidy = (); # reset; we don't want to nuke it if it's inconsistent + + if ( $LinkChk ) { + # dynamically load consistency-chking code; then do it. + require('ghc-consist.prl') + || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-consist.prl!\n"); + + &chk_consistency_info ( $executable ); + } + + # if PVM parallel stuff, we do truly weird things. + # Essentially: (1) move the executable over to where PVM expects + # to find it. (2) create a script in place of the executable + # which will cause the program to be run, via SysMan. + if ( $PARing eq 'p' ) { + local($pvm_executable) = $executable; + local($pvm_executable_base); + + if ( $pvm_executable !~ /^\// ) { # a relative path name: make absolute + local($pwd) = `pwd`; + chop($pwd); + $pwd =~ s/^\/tmp_mnt//; + $pvm_executable = "$pwd/$pvm_executable"; + } + + $pvm_executable =~ s|/|=|g; # make /s into =s + $pvm_executable_base = $pvm_executable; + + $pvm_executable = $ENV{'PVM_ROOT'} . '/bin/' . $ENV{'PVM_ARCH'} + . "/$pvm_executable"; + + &run_something("$Rm -f $pvm_executable; $Cp -p $executable $pvm_executable && $Rm -f $executable", 'Moving binary to PVM land'); + + # OK, now create the magic script for "$executable" + open(EXEC, "> $executable") || &tidy_up_and_die(1,"$Pgm: couldn't open $executable to write!\n"); + print EXEC <= 0; + + &prepareWin32DllLink(0); + + local ($bld_dll) = "dllwrap"; + + local ($output) = ($Specific_output_file ne '') ? "$Specific_output_file" : 'HSdll.dll'; + local ($output_dir); + local ($output_file); + local ($output_lib, $output_def); + + ($output_dir = $output) =~ s|(.*/)[^/]+$|$1|; + $output_dir = "" if ($output_dir eq $output); + ($output_file = $output) =~ s|.*/([^/]+)$|$1|; + + ($output_lib = $output_file) =~ s|(.+)\.[^\.]*$|${output_dir}lib$1_imp.a|; + ($output_def = $output_file) =~ s|(.+)\.[^\.]*$|${output_dir}$1.def|; + + push (@Dll_flags, "-mno-cygwin --target=i386-mingw32") if ($TargetPlatform =~ /^.*mingw32$/); + push (@Dll_flags, "--output-lib $output_lib"); + # If the "--def " option hasn't been supplied, assume everything + # is going to be exported via the DLL.." + if (!grep(/--def/, @Dll_flags)) { + push (@Dll_flags, "--export-all --output-def $output_def"); + } + + local($to_do) = "$bld_dll @Dll_flags -o $output @Link_file $libdirs @UserLibrary @SysLibrary"; + # Make sure the user sees this piece of magic. + print STDERR "$to_do\n" if (!$Verbose); + &run_something($to_do, 'DLL creator'); +} + +sub prepareWin32DllLink +{ + local($linking_main) = @_; + + # + # Win32 DLLs - link with import libraries, not the real archives. + # + if ( $TargetPlatform =~ /-mingw32$/ ) { + if (!$Static) { + # + # If the libraries have the form libHSfoo.a, we + # transform that into libHSfoo_imp.a - the import + # library of the DLL. + # + foreach $a ( @SysLibrary ) { + $a = "${a}_imp" if ($a =~ /^-lHS/); + } + foreach $a ( @UserLibrary ) { + $a = "${a}_imp" if ($a =~ /^-lHS/); + } + push(@Link_file, ( $INSTALLING ) ? "$InstLibDirGhc/Main.dll_o" + : "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/Main.dll_o") if $linking_main; + push(@Link_file, ( $INSTALLING ) ? "$InstLibDirGhc/PrelMain.dll_o" + : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std/PrelMain.dll_o") if $linking_main; + } + push(@Ld_flags, "-mno-cygwin"); + } +} +\end{code} + + %************************************************************************ %* * \section[Driver-misc-utils]{Miscellaneous utilities} @@ -2198,7 +2180,7 @@ sub runAs { # need to add the -I flags in case the file is going through cpp (.S files) local($includes) = '-I' . join(' -I', @Include_dir); - if ( ! $SplitObjFiles ) { + if ( ! $SplitObjFiles || $ifile_root =~ /_stub\.s$/ ) { local($to_do) = "$asmblr -o $as_out -c @As_flags $includes $cc_as"; push(@Files_to_tidy, $as_out ); &run_something($to_do, 'Unix assembler'); @@ -2290,12 +2272,24 @@ sub run_something { close(CCOUT) || &tidy_up_and_die(1,"$Pgm: failed closing `$Tmp_prefix.ccout'\n"); } + local($signal_num) = $? & 127; + local($dumped_core) = $? & 128; + + if ($signal_num != 0) { + print STDERR "$tidy_name received signal $signal_num"; + if ($dumped_core != 0) { + print STDERR " (core dumped)"; + } + print STDERR "\n"; + } + if ($return_val != 0) { if ($Using_dump_file) { print STDERR "Compilation Errors dumped in $Specific_dump_file\n"; } &tidy_up_and_die($return_val, ''); } + $Using_dump_file = 0; } \end{code} @@ -2512,104 +2506,152 @@ sub add_syslib { # Lifting this out of this sub brings it out of scope - why?? %Supported_syslibs = - ( exts, + ( lang, [ # where to slurp interface files from ( $INSTALLING - ? "$InstLibDirGhc/imports/exts" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/exts" + ? "$InstLibDirGhc/imports/lang" + : "$TopPwd/hslibs/lang:$TopPwd/hslibs/lang/monads" ) , # where to find the archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/exts" + : "$TopPwd/hslibs/lang" + ) + , # where to find the cbits archive to use when linking + ( $INSTALLING + ? "$InstLibDirGhc" + : "$TopPwd/hslibs/lang/cbits" ) - , '' # no cbits , '' # Syslib dependencies , '' # extra ghc opts , '' # extra cc opts , '' # extra ld opts ], - misc, + concurrent, [ # where to slurp interface files from ( $INSTALLING - ? "$InstLibDirGhc/imports/misc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc" + ? "$InstLibDirGhc/imports/concurrent" + : "$TopPwd/hslibs/concurrent" ) , # where to find the archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc" + : "$TopPwd/hslibs/concurrent" ) - , # where to find the cbits archive to use when linking + , '' # where to find the cbits archive to use when linking + , '' # Syslib dependencies + , '' # extra ghc opts + , '' # extra cc opts + , '' # extra ld opts + ], + + data, + [ # where to slurp interface files from + ( $INSTALLING + ? "$InstLibDirGhc/imports/data" + : "$TopPwd/hslibs/data:$TopPwd/hslibs/data/edison:$TopPwd/hslibs/data/edison/Assoc:$TopPwd/hslibs/data/edison/Coll:$TopPwd/hslibs/data/edison/Seq" + ) + , # where to find the archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc/cbits" + : "$TopPwd/hslibs/data" ) - , 'exts' # Syslib dependencies - , '' # extra ghc opts - , '' # extra cc opts - , ( $TargetPlatform =~ /-solaris2$/ ? '-lnsl -lsocket' : '') + , '' # where to find the cbits archive to use when linking + , 'lang' # Syslib dependencies + , '' # extra ghc opts + , '' # extra cc opts + , '' # extra ld opts ], - hbc, + + net, [ # where to slurp interface files from ( $INSTALLING - ? "$InstLibDirGhc/imports/hbc" - : "$TopPwd/CONTRIB/libraries/hbc/src" + ? "$InstLibDirGhc/imports/net" + : "$TopPwd/hslibs/net" ) , # where to find the archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/CONTRIB/libraries/src/hbc" + : "$TopPwd/hslibs/net" ) , # where to find the cbits archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/CONTRIB/libraries/hbc/cbits" + : "$TopPwd/hslibs/net/cbits" ) - , 'exts' # Syslib dependencies - , '' # extra ghc opts - , '' # extra cc opts - , '' + , 'lang text' # Syslib dependencies + , '' # extra ghc opts + , '' # extra cc opts + , ( $TargetPlatform =~ /-solaris2$/ ? '-lnsl -lsocket' : '') ], + posix, [ # where to slurp interface files from ( $INSTALLING ? "$InstLibDirGhc/imports/posix" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix" + : "$TopPwd/hslibs/posix" ) , # where to find the archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix" + : "$TopPwd/hslibs/posix" ) , # where to find the cbits archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix/cbits" + : "$TopPwd/hslibs/posix/cbits" ) - , 'misc' # Syslib dependencies + , 'lang' # Syslib dependencies , '' # extra ghc opts , '' # extra cc opts , '' # extra ld opts ], - concurrent, + + text, [ # where to slurp interface files from ( $INSTALLING - ? "$InstLibDirGhc/imports/concurrent" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent" + ? "$InstLibDirGhc/imports/text" + : "$TopPwd/hslibs/text:$TopPwd/hslibs/text/html:$TopPwd/hslibs/text/haxml/lib" ) , # where to find the archive to use when linking ( $INSTALLING ? "$InstLibDirGhc" - : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent" + : "$TopPwd/hslibs/text" ) - , '' # where to find the cbits archive to use when linking - , '' # Syslib dependencies + , # where to find the cbits archive to use when linking + ( $INSTALLING + ? "$InstLibDirGhc" + : "$TopPwd/hslibs/text/cbits" + ) + , 'lang data' # Syslib dependencies , '' # extra ghc opts , '' # extra cc opts , '' # extra ld opts ], + + util, + [ # where to slurp interface files from + ( $INSTALLING + ? "$InstLibDirGhc/imports/util" + : "$TopPwd/hslibs/util:$TopPwd/hslibs/util/check" + ) + , # where to find the archive to use when linking + ( $INSTALLING + ? "$InstLibDirGhc" + : "$TopPwd/hslibs/util" + ) + , # where to find the cbits archive to use when linking + ( $INSTALLING + ? "$InstLibDirGhc" + : "$TopPwd/hslibs/util/cbits" + ) + , 'lang concurrent posix' # Syslib dependencies + , '' # extra ghc opts + , '' # extra cc opts + , "$LibsReadline" # extra ld opts + ], + win32, [ # where to slurp interface files from ( $INSTALLING @@ -2622,10 +2664,29 @@ sub add_syslib { : "$TopPwd/hslibs/win32/src" ) , '' - , 'exts' # Syslib dependencies + , 'lang' # Syslib dependencies , '' # extra ghc opts , '' # extra cc opts , '-luser32 -lgdi32' # extra ld opts + ], + + com, + [ # where to slurp interface files from + ( $INSTALLING + ? "$InstLibDirGhc/imports/com" + : "$TopPwd/hdirect/lib" + ) + , # where to find the archive to use when linking + ( $INSTALLING + ? "$InstLibDirGhc" + : "$TopPwd/hdirect/lib" + ) + , '' + , 'lang' # Syslib dependencies + , '' # extra ghc opts + , '' # extra cc opts + , '-luser32 -lole32 -loleaut32 -ladvapi32' + # extra ld opts ] ); @@ -2640,8 +2701,8 @@ sub add_syslib { # 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", + # explicit *and* implicit ones (i.e., "-syslib lang -syslib misc" + # is not equal to "-syslib lang -syslib misc -syslib lang", # which it needs to be) # # Since our current collection of syslibs don't have any @@ -2653,12 +2714,13 @@ sub add_syslib { $Syslibs_added{$syslib} = 1; - local ($hi_dir, $lib_dir, $lib_cbits_dir, + local ($hi_dirs, $lib_dir, $lib_cbits_dir, $syslib_deps, $syslib_ghc_opts, $syslib_cc_opts, $syslib_ld_opts) = @{ $Supported_syslibs{$syslib} }; - - unshift(@SysImport_dir, $hi_dir); + foreach(split(':',$hi_dirs)) { + unshift(@SysImport_dir, $_); + } push(@SysLibrary_dir, $lib_dir); push(@SysLibrary_dir, $lib_cbits_dir) if ( $lib_cbits_dir ne ''); @@ -2697,7 +2759,7 @@ sub check_for_source_options { open(FILE,$file) || return(1); # No big loss while () { - if ( /^${comment_start} OPTIONS (.*)${comment_end}$/ ) { + if ( /^${comment_start} OPTIONS (.*)${comment_end}/ ) { # add the options found at the back of the command line. local(@entries) = split(/\s+/,$1); print STDERR "Found OPTIONS " . join(' ',@entries) . " in $file\n" if $Verbose; @@ -2739,7 +2801,7 @@ sub splitCmdLine { arg: while($_ = $args[0]) { shift(@args); # sigh, we have to deal with these -option arg specially here. - /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|odump|syslib)$/ && + /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|odump|syslib|package|package-name)$/ && do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; }; /^--?./ && do { push(@Cmd_opts, $_); next arg; }; @@ -2767,9 +2829,24 @@ sub saveIntermediate { local ($final,$suffix,$tmp)= @_ ; local ($to_do); + local ($new_suffix); + # $final -- root of where to park ${final}.${suffix} # $tmp -- temporary file where hsc put the intermediate file. + # HWL: use -odir for .hc and .s files, too + if ( $Specific_output_dir ne '' ) { + $final = "${Specific_output_dir}/${final}"; + } + # HWL: use the same suffix as for $Osuffix in generating intermediate file, + # replacing o with hc or s, respectively. + if ( $Osuffix ne '' ) { + ($new_suffix = $Osuffix) =~ s/o$/hc/ if $suffix eq "hc"; + ($new_suffix = $Osuffix) =~ s/o$/s/ if $suffix eq "s"; + $suffix = $new_suffix; + print stderr "HWL says: suffix for intermediate file is $suffix; ${final}.${suffix} overall\n" if $Verbose; + } + # Delete the old file $to_do = "$Rm ${final}.${suffix}"; &run_something($to_do, "Removing old .${suffix} file"); @@ -2803,7 +2880,7 @@ 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}\n"; exit $Status; }; #---------- verbosity and such ----------------------------------------- /^-v$/ && do { $Verbose = '-v'; $Time = 'time'; next arg; }; @@ -2815,11 +2892,15 @@ arg: while($_ = $Args[0]) { # change the global default: # we won't run cat; we'll run the real thing - /^-C$/ && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscOut = '-C='; + /^-C$/ && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscLang = 'C'; next arg; }; # stop after generating C - /^-noC$/ && do { $HscOut = '-N='; $ProduceHi = '-nohifile='; + /^-J$/ && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscLang = 'java'; + next arg; }; + # stop after generating Java + + /^-noC$/ && do { $HscLang = 'none'; $ProduceHi = '-nohifile='; $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; next arg; }; # leave out actual C generation (debugging) [also turns off interface gen] @@ -2846,6 +2927,8 @@ arg: while($_ = $Args[0]) { # stop after preprocessing C /^-M$/ && do { $Only_generate_deps = 1; $Do_as = 0; $Do_lnkr = 0; next arg; }; # only generate dependency information. + /^--mk-dll$/ && do { $Only_generate_dll = 1; $Do_as = 0; $Do_lnkr = 0; next arg; }; + # Build a Win32 DLL (where supported). /^-S$/ && do { $Do_as = 0; $Do_lnkr = 0; next arg; }; # stop after generating assembler @@ -2939,13 +3022,14 @@ arg: while($_ = $Args[0]) { /^-prof$/ && do { $PROFing = 'p'; next arg; }; # profiling -- details later! - /^-auto/ && do { - # generate auto SCCs on top level bindings - # -auto-all = all top level bindings - # -auto = only top level exported bindings - $PROFauto = ( /-all/ ) - ? '-fauto-sccs-on-all-toplevs' - : '-fauto-sccs-on-exported-toplevs'; + /^-auto-dicts$/ && do { + $PROFdicts = '-fauto-sccs-on-dicts'; + next arg; }; + /^-auto-all$/ && do { + $PROFauto = '-fauto-sccs-on-all-toplevs'; + next arg; }; + /^-auto$/ && do { + $PROFauto = '-fauto-sccs-on-exported-toplevs'; next arg; }; /^-caf-all/ && do { # generate individual CAF SCC annotations @@ -2957,9 +3041,6 @@ arg: while($_ = $Args[0]) { $PROFignore_scc = '-W'; next arg; }; - /^-G(.*)$/ && do { push(@HsC_flags, "-G=$1"); # set group for cost centres - next arg; }; - /^-unprof-scc-auto/ && do { # generate auto SCCs on top level bindings when not profiling. # Used to measure optimisation effects of presence of sccs. @@ -2974,6 +3055,7 @@ arg: while($_ = $Args[0]) { /^-gransim$/ && do { $GRANing = 'g'; &add_syslib('concurrent'); next arg; }; # GranSim /^-ticky$/ && do { $TICKYing = 't'; next arg; }; # ticky-ticky /^-parallel$/ && do { $PARing = 'p'; &add_syslib('concurrent'); next arg; }; # parallel Haskell + /^-smp$/ && do { $SMPing = 's'; &add_syslib('concurrent'); next arg; }; # parallel Haskell #-------------- "user ways" -------------------------------------------- @@ -2999,8 +3081,16 @@ arg: while($_ = $Args[0]) { print STDERR "WARNING: import paths cleared by `-i'\n"; next arg; }; - /^-i(.*)/ && do { local(@new_items) - = split( /:/, &grab_arg_arg(*Args,'-i', $1)); + /^-i(.*)/ && do { local(@new_items); + local($arg) = $1; + + # + if ( $arg =~ /;/ ) { + $SplitMarker=";"; + @new_items = split( /;/, &grab_arg_arg(*Args,'-i', $arg)); + } else { + @new_items = split( /:/, &grab_arg_arg(*Args,'-i', $arg)); + } unshift(@Import_dir, @new_items); next arg; }; @@ -3008,10 +3098,21 @@ arg: while($_ = $Args[0]) { /^-L(.*)/ && do { push(@UserLibrary_dir, &grab_arg_arg(*Args,'-L', $1)); next arg; }; /^-l(.*)/ && do { push(@UserLibrary,'-l'.&grab_arg_arg(*Args,'-l', $1)); next arg; }; + # DEPRECATED: use -package instead /^-syslib(.*)/ && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1); &add_syslib($syslib); next arg; }; + /^-package-name(.*)/ && do + { local($package) = &grab_arg_arg(*Args,'-package-name',$1); + push(@HsC_flags,"-inpackage=$package"); + next arg; + }; + + /^-package(.*)/ && do { local($package) = &grab_arg_arg(*Args,'-package',$1); + &add_syslib($package); + next arg; }; + #======================================================================= # various flags that we can harmlessly send to one program or another # (we will later "reclaim" some of the compiler ones now sent to gcc) @@ -3033,11 +3134,11 @@ 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; }; /^-optl(.*)$/ && do { push(@Ld_flags, $1); next arg; }; + /^-optdll(.*)$/ && do { push(@Dll_flags, $1); next arg; }; /^-optdep(.*)$/ && do { push(@MkDependHS_flags, $1); next arg; }; #---------- Haskell C pre-processor (hscpp) ---------------------------- @@ -3054,6 +3155,7 @@ arg: while($_ = $Args[0]) { /^-keep-s-files?-too$/ && do { $Keep_s_file_too = 1; next arg; }; /^-fignore-interface-pragmas$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fignore-asserts$/ && do { push(@HsC_flags, $_); next arg; }; /^-fno-implicit-prelude$/ && do { $NoImplicitPrelude= 1; push(@HsC_flags, $_); next arg; }; @@ -3068,6 +3170,7 @@ arg: while($_ = $Args[0]) { /^-fticky-ticky$/ && do { push(@HsC_flags,$_); next arg; }; /^-fgransim$/ && do { push(@HsC_flags,$_); next arg; }; /^-fparallel$/ && do { push(@HsC_flags,$_); next arg; }; + /^-fsmp$/ && do { push(@HsC_flags,$_); next arg; }; /^-split-objs$/ && do { if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|rs6000|sparc)-/ ) { @@ -3075,7 +3178,7 @@ arg: while($_ = $Args[0]) { print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n"; } else { $SplitObjFiles = 1; - $HscOut = '-C='; + $HscLang = 'C'; push(@HsC_flags, "-fglobalise-toplev-names"); push(@CcBoth_flags, '-DUSE_SPLIT_MARKERS'); @@ -3085,16 +3188,19 @@ arg: while($_ = $Args[0]) { } next arg; }; + /^-unreg$/ && do { $UNREGing = 'u'; next arg; }; + /^-funregisterised$/ && do { push(@HsC_flags, $_); next arg; }; /^-fno-asm-mangling$/ && do { $DoAsmMangling = 0; next arg; }; /^-fallow-overlapping-instances$/ && do { push(@HsC_flags, $_); next arg; }; /^-fallow-undecidable-instances$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fhistory-size.*$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fdicts-strict$/ && do { push(@HsC_flags, $_); next arg; }; /^-fglasgow-exts$/ && do { push(@HsC_flags, $_); - push(@HsP_flags, '-N'); - # -fglasgow-exts implies -syslib exts - &add_syslib('exts'); + # -fglasgow-exts implies -syslib lang + &add_syslib('lang'); next arg; }; @@ -3103,31 +3209,21 @@ arg: while($_ = $Args[0]) { /^-fno-speciali[sz]e$/ && do { $Oopt_DoSpecialise = ''; next arg; }; - /^-fcompiling-prelude$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fusagesp$/ + && do { $Oopt_UsageSPInf = '-fusagesp'; + push (@HsC_flags, '-fusagesp-on'); next arg; }; + + /^-fcompiling-prelude$/ && do { $CompilingPrelude=1; push(@HsC_flags, $_); next arg; }; # Now the foldr/build options, which are *on* by default (for -O). /^-ffoldr-build$/ && do { $Oopt_FoldrBuild = 1; - $Oopt_FB_Support = '-fdo-arity-expand'; #print "Yes F/B\n"; next arg; }; /^-fno-foldr-build$/ && do { $Oopt_FoldrBuild = 0; - $Oopt_FB_Support = ''; - next arg; }; - - /^-fno-foldr-build-rule$/ - && do { $Oopt_FoldrBuild = 0; - next arg; }; - - /^-fno-enable-tech$/ - && do { $Oopt_FB_Support = ''; - next arg; }; - - /^-fno-snapback-to-append$/ - && do { $Oopt_FoldrBuildInline .= ' -fdo-not-fold-back-append '; next arg; }; # --------------- Renamer ------------- @@ -3138,14 +3234,17 @@ arg: while($_ = $Args[0]) { # --------------- - /^-fasm-(.*)$/ && do { $HscOut = '-S='; next arg; }; # force using nativeGen - /^-fvia-[cC]$/ && do { $HscOut = '-C='; next arg; }; # force using C compiler + /^-fasm-(.*)$/ && do { $HscLang = 'asm'; next arg; }; # force using nativeGen + /^-fvia-[cC]$/ && do { $HscLang = 'C'; next arg; }; # force using C compiler # --------------- /^-funfolding-.*$/ && do { push(@HsC_flags, $_); next arg }; + /^-fliberate-case-.*$/ + && do { push(@HsC_flags, $_); next arg }; + /^-funfold-casms-in-hi-file$/ && do { push(@HsC_flags, $_); next arg }; @@ -3159,12 +3258,12 @@ arg: while($_ = $Args[0]) { /^-fno-pre-inlining$/ && do { push(@HsC_flags, $_); next arg }; - /^-fdo-monad-eta-expansion$/ - && do { $Oopt_MonadEtaExpansion = $_; next arg; }; - /^-fno-let-from-(case|app|strict-let)$/ # experimental, really (WDP 95/10) && do { push(@HsC_flags, $_); next arg; }; + /^-funbox-strict-fields$/ + && do { push(@HsC_flags, $_); next arg; }; + # --------------- Warnings etc. ------ /^-fwarn-(.*)$/ && do { push(@HsC_flags, $_); next arg; }; @@ -3207,6 +3306,9 @@ arg: while($_ = $Args[0]) { # -d(no-)core-lint is done this way so it is turn-off-able. /^-dcore-lint/ && do { $CoreLint = '-dcore-lint'; next arg; }; /^-dno-core-lint/ && do { $CoreLint = ''; next arg; }; + # Ditto for USP lint + /^-dusagesp-lint/ && do { $USPLint = '-dusagesp-lint'; next arg; }; + /^-dno-usagesp-lint/ && do { $USPLint = ''; next arg; }; # Ditto for STG lint /^-dstg-lint/ && do { $StgLint = '-dstg-lint'; next arg; }; /^-dno-stg-lint/ && do { $StgLint = ''; next arg; }; @@ -3243,7 +3345,7 @@ arg: while($_ = $Args[0]) { } elsif ($heap_size >= $Specific_heap_size) { $Specific_heap_size = $heap_size; } else { - print STDERR "$Pgm: ignoring heap-size-setting option ($_)...not the largest seen\n"; + print STDERR "$Pgm: ignoring heap-size-setting option ($_)...not the largest seen\n" if $Verbose; } next arg; }; @@ -3265,7 +3367,7 @@ arg: while($_ = $Args[0]) { } elsif ($stk_size >= $Specific_stk_size) { $Specific_stk_size = $stk_size; } else { - print STDERR "$Pgm: ignoring stack-size-setting option ($flag $stk_size)...not the largest seen\n"; + print STDERR "$Pgm: ignoring stack-size-setting option ($flag $stk_size)...not the largest seen\n" if $Verbose; } next arg; }; @@ -3305,7 +3407,7 @@ arg: while($_ = $Args[0]) { local($opt_lev) = ( /^-O2$/ ) ? 2 : 1; # max 'em $OptLevel = ( $opt_lev > $OptLevel ) ? $opt_lev : $OptLevel; - $HscOut = '-C=' if $OptLevel == 2; # force use of C compiler + $HscLang = 'C' if $OptLevel == 2; # force use of C compiler next arg; }; /^-Onot$/ && do { $OptLevel = 0; next arg; }; # # set it to