#!/usr/bin/perl -w =pod This program is Copyright © 2007 Thiago Macieira =head1 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. =head1 Description pmake is a make-colourising and progress reporting tool. It's not very intelligent at all... It simply runs make with the -n (--dry-run) option to count the lines and then displays a percentage based on how much of that make has run already. That means it very often gets the percentages very, very wrong. You can get 120% or more, easily, in some builds. In other cases, make -n reports an error that make would not report. In that case, pmake will not work. pmake can be used with colorgcc if you apply to it a patch to make it send its output to stdout. If you fail to do that, pmake will report all compilation errors and warnings as "Executing:" commands. =item patch to apply to colorgcc: --- /usr/bin/colorgcc-4.1.2~ 2007-01-15 14:02:08.000000000 +0100 +++ /usr/bin/colorgcc-4.1.2 2007-01-21 17:43:03.000000000 +0100 @@ -232,6 +232,7 @@ $compiler_pid = open3('<&STDIN', \*GCCOUT, \*GCCOUT, $compiler, @ARGV); # Colorize the output from the compiler. +select STDERR; while() { if (m/^(.*?):([0-9]+):(.*)$/) # filename:lineno:message =cut use strict; my $MAKE = $ENV{"MAKE"} || "/usr/bin/make"; my ($RED, $GREEN, $YELLOW, $NORMAL, $BOLD) = ("") x 5; my $TOTAL; my $NR = 0; # Count the number of lines in the output open(FROM_CHILD, "-|", $MAKE, "-n", @ARGV); while () { next if (/^make/); # Don't count make's own lines $NR++; } close(FROM_CHILD); exit $? >> 8 if $?; $TOTAL = $NR; if (! -t STDOUT || $ENV{"TERM"} eq "dumb") { # Dumb terminal or output is not a terminal # Don't try to colourise, so we don't need to open a terminal # Just use a pipe pipe(FROM_CHILD, TO_PARENT) or die "Cannot execute make: $!"; my $pid = fork; die "Cannot execute make: $!" if not defined($pid); unless ($pid) { # Child close(FROM_CHILD); open(STDOUT, ">&TO_PARENT"); close(TO_PARENT); exec $MAKE, @ARGV; } close(TO_PARENT); } else { # Colour-capable terminal (we hope) # Colourise # We open a new terminal so that colorgcc colourises too $RED = "\e[31m"; $GREEN = "\e[32m"; $YELLOW = "\e[1;33m"; $NORMAL = "\e[0m"; $BOLD = "\e[1m"; use IO::Pty; my $pty = new IO::Pty; my $pid = fork; die "Cannot execute make: $!" if not defined($pid); unless ($pid) { # Child my $slave = $pty->slave(); $slave->set_raw(); # Dup the terminal to stdout open(STDOUT, ">&" . $slave->fileno()); close($slave); close($pty); exec $MAKE, @ARGV; } open(FROM_CHILD, "<&=" . $pty->fileno()); $pty->close_slave(); close($pty); } # Process make's output $NR = 0; while () { next if (/^make/); # Don't display make's own lines chomp; my $original = $_; # Display the progress percentage printf "[%3d%%] ", $NR++ * 100 / $TOTAL if $TOTAL; # Find out which program was run s,^ *[^ ]*/,,; if (/^(cc|gcc|c\+\+|g\+\+|g?as|moc|uic3?)/) { # A compiler was run my $target = ""; my $prog = $1; s/^[^ ]* //; if ($prog eq "moc" or $prog eq "uic" or $prog eq "uic3") { print "${YELLOW}Running $prog on "; } elsif ($prog eq "as" or $prog eq "gas") { print "${GREEN}Assembling "; } elsif (/(^| )-c( |$)/) { print "${GREEN}Compiling "; } else { print "${RED}Linking "; print "library " if (/(^| )-shared( |$)/); print "executable " unless (/(^| )-shared( |$)/); /(^| )-o +([^ ]+)( |$)/ and $target = $2; } if ($target eq "") { s/(^| )*-(o|x|include) +[^ ]+ */ /g; /(^| )([^- ][^ ]*)( |$)/; $target = $2; } print $BOLD, $target; } elsif (/^ar c[^ ]* ([^ ]*) /) { print "${RED}Creating static library $1"; } else { print "${BOLD}Executing: $NORMAL$original"; } print "$NORMAL\n"; } close(FROM_CHILD); wait(); exit $? >> 8;