Faster depend written in Perl

Ian Burrell (iburrell@leland.stanford.edu)
Thu, 25 Jul 1996 18:25:34 -0700 (PDT)


I have an old 386/33 and running 'make depend' takes a long time. I
heard this was because gawk uses floating point instead of integer
arithmetic. To speed things up, I translated the depend.awk script
into Perl using the a2p program. I edited the result to clean up the
code. The resulting script runs much faster (up to an order of
magnitude on my machine without a coprocessor) either because of
integer arithmetic or Perl's faster I/O.

I modifed the Makefile and Rules.make to use this script by adding a
new variable, DEPEND that has the command to do depends. The depend
rules are changed to use this variable, which can be set to either the
awk or perl scripts. I tested the script with one 'make depend' with
my current configuration.

The patch including the script is appended.

- Ian

--
          -- Ian Burrell == iburrell@leland.stanford.edu **
           <URL:http://www-leland.stanford.edu/~iburrell/>
All theoretical chemistry is really physics; and all theoretical
chemists know it.  -- Richard P. Feynman

--- Makefile~ Sat Jul 20 18:24:49 1996 +++ Makefile Thu Jul 25 18:09:35 1996 @@ -39,6 +39,8 @@ STRIP =$(CROSS_COMPILE)strip MAKE =make AWK =gawk +DEPEND = $(AWK) -f $(TOPDIR)/scripts/depend.awk +#DEPEND = perl $(TOPDIR)/scripts/depend.pl all: do-it-all @@ -345,7 +347,7 @@ find . -type f -print | sort | xargs sum > .SUMS dep-files: archdep .hdepend include/linux/version.h - $(AWK) -f scripts/depend.awk init/*.c > .tmpdepend + $(DEPEND) init/*.c > .tmpdepend set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done mv .tmpdepend .depend @@ -385,5 +387,5 @@ .hdepend: dummy rm -f $@ - $(AWK) -f scripts/depend.awk `find $(HPATH) -name \*.h ! -name modversions.h -print` > .$@ + $(DEPEND) `find $(HPATH) -name \*.h ! -name modversions.h -print` > .$@ mv .$@ $@ --- Rules.make~ Fri Jun 7 06:28:45 1996 +++ Rules.make Thu Jul 25 17:54:12 1996 @@ -83,7 +83,7 @@ # fastdep: dummy if [ -n "$(wildcard *.[chS])" ]; then \ - $(AWK) -f $(TOPDIR)/scripts/depend.awk *.[chS] > .depend; fi + $(DEPEND) *.[chS] > .depend; fi ifdef ALL_SUB_DIRS set -e; for i in $(ALL_SUB_DIRS); do $(MAKE) -C $$i fastdep; done endif --- /dev/null Mon Dec 31 20:00:00 1979 +++ scripts/depend.pl Thu Jul 25 17:50:33 1996 @@ -0,0 +1,155 @@ +#!/usr/bin/perl + +# This is a rewrite of the depend.awk script in Perl. This is done to +# speed up the 'make depend' step on machines without floating point +# support, where gawk is very slow. The bulk of the translation was +# done by the a2p program with some editing done to clean up the Perl +# code. +# +# 1996/07/25 Ian Burrell <iburrell@leland.stanford.edu> + +# This is an awk script which does dependencies. We do NOT want it to +# recursively follow #include directives. +# +# The HPATH environment variable should be set to indicate where to look +# for include files. The -I in front of the path is optional. + +# Variables set by a2p, not needed in modified version. +#$[ = 1; # set array base to 1 +#$, = ' '; # set output field separator +#$\ = "\n"; # set output record separator + +$hasdep = 0; +$hasconfig = 0; +$needsconfig = 0; +$incomment = 0; +if (!($TOPDIR = $ENV{'TOPDIR'})) { + print STDERR "Environment variable TOPDIR is not set\n"; + exit 1; +} +@parray = split(' ', $ENV{'HPATH'}, 9999); +foreach $path (@parray) { + $path =~ s/^-I//; + $path =~ s@[/ ]*$@@; +} + +# eliminate comments + +while (<>) { + chop; # strip record separator + + # remove all comments fully contained on a single line + s@/\*.*\*/@@g; + if ($incomment) { + if ($_ =~ m@\*/@) { + $incomment = 0; + s@.*\*/@@g; + } + else { + next; + } + } + else { + # start of multi-line comment + if ($_ =~ m@/\*@) { + $incomment = 1; + s/\/\*.*//; + } + elsif ($_ =~ m@\*/@) { + $incomment = 0; + s@.*\*/@@; + } + } + + if (/^[ \t]*#[ \t]*if.*[^A-Za-z_]CONFIG_/) { + $needsconfig = 1; + if (!$hasconfig) { + print STDERR "$ARGV needs config but has not included config file\n"; + # only say it once per file.. + $hasconfig = 1; + } + } + + if (/^[ \t]*#[ \t]*include[ \t]*[<"][^ \t]*[>"]/) { + $found = 0; + if ($LASTFILE ne $ARGV) { + &endfile($LASTFILE); + $hasdep = 0; + $hasconfig = 0; + $needsconfig = 0; + $incomment = 0; + $cmd = ''; + $LASTFILE = $ARGV; + $depname = $ARGV; + $relpath = $ARGV; + $depname =~ s/\.c$/.o: /; + $depname =~ s/\.S$/.o: /; + if ($depname eq $ARGV) { #??? + $cmd = "\n\t\@touch " . $depname; + } + $depname =~ s/\.h$/.h: /; + if ($relpath =~ /^\./) { + $relpath =~ s@[^/]*$@@; + $relpath = $relpath . '/'; + $relapth =~ s@//@/@; + } + else { + $relpath = ''; + } + } + $fname = $_; + $fname =~ s/^#[ \t]*include[ \t]*[<\"]//; + $fname =~ s/[>\"].*//; + if ($fname eq 'linux/config.h') { + $hasconfig = 1; + } + $rfname = $relpath . $fname; + if (-e $rfname) { + $found = 1; + if (!$hasdep) { + print "$depname"; + } + $hasdep = 1; + print " \\\n $rfname"; + if ($fname =~ /^\./) { + $fnd = 0; + foreach $arg (@ARGV) { + if ($arg eq $rfname) { #??? + $fnd = 1; + } + } + if ($fnd == 0) { + push(@ARGV, $rfname); + } + } + } + else { + foreach $path (@parray) { + $fil = $path . '/' . $fname; + if ( -e $fil ) { + $shortp = $path; + $found = 1; + if (!$hasdep) { + print "$depname"; + } + $hasdep = 1; + print " \\\n $fil"; + } + } + } + } +} + +&endfile($ARGV); +exit 0; + +sub endfile { + local($f) = @_; + if ($hasconfig && !$needsconfig) { + print STDERR "$f doesn't need config\n"; + } + if ($hasdep) { + print "$cmd\n"; + } +} +