rendered paste body#!/usr/bin/perl -w
=pod
This program is Copyright © 2007 Thiago Macieira <thiago@kde.org>
=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(<GCCOUT>)
{
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 (<FROM_CHILD>)
{
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 (<FROM_CHILD>) {
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;