%************************************************************************ %* * \section[Driver-recomp-chking]{Recompilation checker} %* * %************************************************************************ \begin{code} sub runRecompChkr { local($ifile, # originating input file $ifile_hs, # post-unlit, post-cpp, etc., input file $ifile_root, # input filename minus suffix $ofile_target,# the output file that we ultimately hope to produce $hifile_target# the .hi file ... (ditto) ) = @_; ($i_dev,$i_ino,$i_mode,$i_nlink,$i_uid,$i_gid,$i_rdev,$i_size, $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile); if ( ! -f $ofile_target ) { print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n"; return(1); } ($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 ) { print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n"; return(1); } ($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) { print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n"; return(1); } # OK, let's see what we used last time; if none of it has # changed, then we don't need to continue with this compilation. require('ghc-iface.prl') || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl (recomp)!\n"); &tidy_up_and_die(1,"$Pgm:recomp:why has $hifile_target already been read?\n") if $HiHasBeenRead{'old'} == 1; &readHiFile('old',$hifile_target); %ModUsed = (); %Used = (); foreach $ul ( split(/;\n/, $Stuff{'old:usages'}) ) { $ul =~ /^(\S+)\s+(\d+)\s+:: (.*)/ || die "$Pgm: bad old usages line!\n"; local($mod) = $1; local($modver) = $2; local(@thing) = split(/\s+/, $3); $ModUsed{$mod} = $modver; local($key, $n); while ( $#thing >= 0 ) { $key = "$mod:" . $thing[0]; $n = $thing[1]; $Used{$key} = $n; shift @thing; shift @thing; # toss two } } # see if we can avoid recompilation just by peering at the # module-version numbers: &makeHiMap() unless $HiMapDone; local($used_modules_have_changed) = 0; used_mod: foreach $um ( keys %ModUsed ) { if ( ! defined($HiMap{$um}) ) { print STDERR "$Pgm:recompile:interface for used module $um no longer exists\n"; foreach $hm ( keys %HiMap ) { print STDERR "$hm ==> ", $HiMap{$hm}, "\n"; } return 1; } else { if ( $HiHasBeenRead{$um} ) { print STDERR "$Pgm:very strange that $um.hi has already been read?!?\n" } else { &readHiFile($um, $HiMap{$um}); } } if ( $ModUsed{$um} != $ModuleVersion{$um} ) { print STDERR "used module version: $um: was: ",$ModUsed{$um}, "; is ", $ModuleVersion{$um}, "\n"; $used_modules_have_changed = 1; last used_mod; # no point continuing... } } return 0 if ! $used_modules_have_changed; # well, some module version has changed, but maybe no # entity of interest has... print STDERR "considering used entities...\n"; local($used_entities_have_changed) = 0; used_entity: foreach $ue ( keys %Used ) { $ue =~ /([A-Z][A-Za-z0-9_']*):(.+)/; local($ue_m) = $1; local($ue_n) = $2; die "$Pgm:interface for used-entity module $ue_m doesn't exist\n" if ! defined($HiMap{$ue_m}); &readHiFile($ue_m, $HiMap{$ue_m}) unless $HiHasBeenRead{$ue_m}; # we might not have read it before... if ( !defined($Version{$ue}) ) { print STDERR "No version info for $ue?!\n"; } elsif ( $Used{$ue} != $Version{$ue} ) { print STDERR "$Pgm:recompile: used entity changed: $ue: was version ",$Used{$ue},"; is ", $Version{$ue}, "\n"; $used_entities_have_changed = 1; last used_entity; # no point continuing... } } return 0 if ! $used_entities_have_changed; return(1); # OK, *recompile* } \end{code} \begin{code} # make "require"r happy... 1; \end{code}