root/mpich2/branches/dev/kumudb/maint/clmake.in @ 4870

Revision 4870, 7.6 KB (checked in by kumudb, 5 months ago)

Merge from trunk to kumudb r4748:r4869

Line 
1#! @PERL@
2# -*- Mode: perl; -*-
3#
4# Set Defaults
5$debug = 0;
6$debugDir = 0;
7$gDebugOther = 0;
8
9$summaryOutput = 0;
10$terseOutput = 1;
11$rootSrcDir = "";
12# Define the known commands, along with known make noise (results of
13# echo)
14# We include /bin/rm and /bin/mv because some Makefile authors prefer
15# to get the full path for these routines
16@commands = ( "cc", "pgcc", "gcc", "icc", "acc",
17              "rm", "mv", "cp", "ar", "ranlib", "perl", "for",
18              "/bin/rm", "/bin/mv", "/bin/cp",
19              "if", "make", "gnumake",
20              "[A-Za-z0-9_\/\.-]*\/mpicc",
21              "[A-Za-z0-9_\/\.-]*\/mpif77",
22              "[A-Za-z0-9_\/\.-]*\/mpif90",
23              "[A-Za-z0-9_\/\.-]*\/mpicxx",
24              "cleaning", "sleep", "date", "g77", "f77", "f90", "f95", "pgCC",
25              "pgf77", "pgf90", "CC", "g95", "g\\+\\+", "c\\+\\+",
26              "acc\\+\\+", "xlc", "xlf", "xlC", "xlf90", "gfortran",
27              "ifort", "ifc", "test",
28              "true", "false", "/[A-Za-z0-9_\/\.-]*createshlib",
29              "/bin/sh\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--mode=\\w+",
30              "/bin/bash\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--mode=\\w+",
31              "/bin/sh\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--finish",
32              "/bin/bash\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--finish",
33              "libtool:\\s+compile:",
34              "libtool:\\s+link:",
35              "libtool:\\s+install:",
36              "libtool:\\s+finish:",
37              "[A-Za-z0-9_\/-]*\/icc",
38              "[A-Za-z0-9_\/-]*\/install-sh",
39              "/usr/bin/ar", "mkdir",
40              "/usr/ucb/ld",
41              "mpicc", "mpicxx",
42              "compiling ROMIO in",
43              "Make completed",
44              "echo", "cat",
45              "CC", "AR", "RANLIB", "LIBTOOL", "MV", "CP", # "terse" make versions
46              "\\(?cd",
47              "\\(\\s*cd",
48              "creating\s+lib.*",
49              "cd\\s+\&\&\\s+make",
50              "sed -e",
51              "PATH=\"\\\$PATH.*\\sldconfig\\s",
52              "building profiling interface in directory",
53              "/usr/bin/install",
54              "Copying Upshot",
55              "Cleaning directory",
56              "[*][*][*][*] Making .*\.\.\.\.",
57              "Making .*\.\.\.\.",        # mpe writes this
58              "Making upshot", "\\s*\$", );
59
60# OtherNoise is an array of patterns that describe blocks of
61# text that we'd like to skip.  The initial use it to handle
62# libtool install output.
63# The PG entries are work-arounds for bugs in the PG header files that have
64# small incompatibilities with the system header file /usr/include/unistd.h
65#
66@OtherNoise = ( 'Libraries have been installed in:<SEP>more information, such as the ld\(1\) and ld.so\(8\) manual pages.<SEP>20',
67                '^\s*-+\s*$<SEP><SEP>1',
68                '^In directory:<SEP><SEP>1',
69                '^creating\s<SEP><SEP>1',
70#               '^PGC-W-0114-More than one type.*/usr/include/unistd.h: 189<SEP>^PGC-W-0143-Useless typedef.*/usr/include/unistd.h: 189<SEP>2',
71#               '^PGC-W-0114-More than one type.*/usr/include/unistd.h: 243<SEP>^PGC-W-0143-Useless typedef.*/usr/include/unistd.h: 243<SEP>2',
72                '^PGC.*: compilation completed with warnings<SEP><SEP>1',
73# This next is a general version to handle all of these mistakes
74                '^PGC-W-0114-More than one type specified.*/usr/include<SEP>^PGC-W-0143-Useless typedef declaration \(no declarators present\).*/usr/include<SEP>2',
75                'copying python',
76                'LOOP WAS VECTORIZED',
77                );
78# In the past, we also needed
79# WARNING 84.*not used for resolving any symbol
80# Info: File not optimized
81
82
83$trimCompileLine = 1;
84
85# Create the variables that keep track of state
86# dirstack keeps the directory name that gnumake and similar make
87# implementations echo as a directory is entered or exited (this can generate
88# a great deal of output noise that can obscure important data.  However, when
89# a problem *does* occur, this directory information is valuable.
90# dirprinted is a parallel array that indicates whether the corresponding
91# directory entry has been printed.
92@dirstack = ();
93@dirprinted = ();
94
95# Process arguments to select options
96foreach $_ (@ARGV) {
97    if (/^--?debug/) { $debug = 1; }
98    elsif (/^--?showdir/) { $debugDir = 1; }
99    elsif (/^--?summary/) { $summaryOutput = 1; }
100    elsif (/^--?notrimcompileline/) { $trimCompileLine = 0; }
101    elsif (/^-/) {
102        print STDERR "Unrecognized argument $_\n";
103        print STDERR "clmake [ -debug ] [ -showdir ] [ -summary ]\n";
104        exit(1);
105    }
106    else { last; }
107    shift @ARGV;
108}
109# Read lines.  Categorize lines as commands and output.  This
110# script suppresses commands that generate no extra output.
111# The approach is to read a line and then read the next line.
112# While the line is a command and the next line is not, output the
113# line.
114#
115# We use eof() (see man perlfun) so that we can accept filenames on the
116# commandline.
117#
118$cmdline = "";
119T:
120while ($line = <>) {
121    if (eof()) { next; }
122
123    $line =~ s/\r//;    # remove returns from line (de DOSify)
124
125    # Read the next line, including handling any continuation lines
126    while ($line =~ /\\$/) {
127        print "Read continuation line (cmd) ... \n" if $debug;
128        $line .= <>;
129    }
130
131    # Check for noise
132    foreach my $pat (@OtherNoise) {
133        # maxlines is the maximum number of lines to match
134        my ($beginpat,$endpat,$maxlines) = split( '<SEP>', $pat );
135        print "Trying to match $beginpat\n" if $gDebugOther;
136        if ($line =~ /$beginpat/) {
137            $maxlines --;
138            print "Found match to $beginpat\n" if $gDebugOther;
139            # Found the beginning.  Look for the end (if one requested)
140            if ($endpat =~ /\S/) {
141                print "Trying to match endpat $endpat\n" if $gDebugOther;
142                while ($line = <>) {
143                    if (eof()) { last; }
144                    print "Trying to match to $line" if $gDebugOther;
145                    if ($line =~ /$endpat/) { last; }
146                    if ($maxlines-- <= 0) {
147                        print STDOUT "Failed to match $endpat; last line was $line";
148                        last;
149                    }
150                }
151            }
152            next T;
153        }
154    }
155   
156    # Is the line a command (including a directory change?)
157    # Check first for a directory change
158    if ($line =~ /^\s*make.* Entering directory \`([^\']*)\'/) {
159        my $dirname = $1;
160        $dirstack[$#dirstack+1] = $dirname;
161        $dirprinted[$#dirprinted+1] = 0;
162        print ">>entering $dirname\n" if $debugDir;
163        $cmdline = "";
164        next;
165    }
166    elsif ($line =~ /^\s*make.* Leaving directory \`([^\']*)\'/) {
167        # We should check that the directory names match
168        my $dirname = $1;
169        print ">>leaving $dirname\n" if $debugDir;
170        if ($dirname ne $dirstack[$#dirstack]) {
171            print STDERR "Warning: leaving directory $dirname but expected to leave directory " . $dirstack[$#dirstack] . "\n";
172        }
173        $#dirstack--;
174        $#dirprinted--;
175        $cmdline = "";
176        next;
177    }
178    else {
179        $is_command = 0;
180        foreach $cmdname (@commands) {
181            if ($line =~ /^\s*$cmdname[^\w]/) {
182                $is_command = 1;
183                $cmdline = $line;
184                last;
185            }
186        }
187        if ($is_command) {
188            if ($summaryOutput) {
189                # FIXME: Summarize the command
190                if ($terseOutput) {
191                    if ($rootSrcDir eq "") {
192                        if ($line =~ /\s(\/\S+\/src\/)/) {
193                            $rootSrcDir = $1;
194                            print "rootSrcDir = $rootSrcDir\n";
195                        }
196                    }
197                    else {
198                        $line =~ s/$rootSrcDir//g;
199                    }
200                    # Compiler options to remove
201                    $line =~ s/-I\S+\s+//g;
202                    $line =~ s/-W\S+\s+//g;
203                    $line =~ s/-D\S+\s+//g;
204                }
205                print $line;
206            }
207            next;
208        }
209    }
210
211    # If we got to this point, the line was not a recognized command or
212    # ignorable output.  Output the line, including the command if this
213    # is the first time.  We can then forget the command
214    if ($#dirstack >= 0 && $dirprinted[$#dirstack] == 0) {
215        print "In directory: ". $dirstack[$#dirstack] . "\n";
216        $dirprinted[$#dirstack] = 1;
217    }
218    if ($cmdline ne "") {
219        if ($trimCompileLine) {
220            # Simplify the command line before printing
221            $cmdline =~ s/-I\S*\s+//g;
222            $cmdline =~ s/-ansi//g;
223            $cmdline =~ s/-W\S*\s+//g;
224            $cmdline =~ s/-DHAVE_CONFIG_H//g;
225            $cmdline =~ s/-DGCC_WALL//g;
226        }
227        # We could print a newline here to separate commands
228        print $cmdline;
229        $cmdline = "";
230    }
231    print $line;
232}
233
234#
235# ToDo:
236# Handle lines containing just ----, e.g., patterns of the form
237# -*
Note: See TracBrowser for help on using the browser.