/usr/bin/makepplog is in makepp 2.0.98.5-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | #!/usr/bin/perl -w
# $Id: makepplog,v 1.55 2013/08/19 06:38:27 pfeiffer Exp $
package Mpp;
use strict;
# Shall we put a period after each message? Or once for all before the \n when printing?
my %log_msg =
(
AUTOLOAD => 'Autoloading for target %s',
BC_COPY => 'Copied %s from build cache file %s',
BC_EXPORT => 'Target %s exported to build cache file %s',
BC_FOUND => 'Found match for %s in build cache with key %s',
BC_LINK => 'Target %s hard-linked into build cache file %s and write-protected',
BC_NONE => 'No entry for %s in build cache with key %s',
BC_NO_KEY => 'Not checking build cache for %s because it has no key',
BUILD_ARCH => 'Rebuild %s because last build was on %s and this is on %s',
BUILD_CHANGED => 'Rebuild %s because %s changed',
BUILD_CMD => 'Rebuild %s because last build command (%s) differs from current command (%s)',
BUILD_DEP_ADD => 'Rebuild %s because of added dependencies %s',
BUILD_DEP_DEL => 'Rebuild %s because of removed dependencies %s',
BUILD_ENV => 'Rebuild %s because value of environment variable %s (%s) differs from previous value (%s)',
BUILD_ENV_ADD => 'Rebuild %s because environmental dependency on %s is new',
BUILD_ENV_DEL => 'Rebuild %s because environmental dependency on %s no longer exists',
BUILD_FINAL => 'Rebuild %s because --final-rule-only specified',
BUILD_INVALID => 'Rebuild %s because build info got invalidated',
BUILD_MARK_NEW => 'Rebuild %s because %s is marked new',
BUILD_NONE => 'Build %s because it doesn\'t exist',
BUILD_NOT => 'Not building %s because it\'s marked for dont-build',
BUILD_OLD => 'Rebuild %s because it\'s older than %s',
BUILD_PHONY => 'Rebuild %s because it is a phony target',
BUILD_RECURSIVE => 'Rebuild %s because command is recursive invocation of make',
CACHED_DEP => 'Building %s as a cached scanned dependency of %s',
DEL_STALE => 'Removing stale generated file or symlink %s',
DEBUG => 'Environment var $MAKEPP_DEBUG is %s (1 means extra verbose)',
DEPEND => ' Targets %s depend on %s',
ERROR => '%s has non-fatal error %s, %s',
EXPR => 'Expression %s returns value %s at %s',
IFEQ => 'if(n)eq comparing %s with %s at %s',
INCL => '%s includes %s',
INCL_WHO => 'something includes %s',
INFER_DEP => 'infer_objects adding %s to dependency list because of %s',
INFER_SEED => 'infer_objects called with seed objects %s',
LEX_REDIRECT => 'Lexical analysis of I/O redirect failed for rule %s',
LEX_RULE => 'Lexically analyzing rule for %s because %s',
LOAD => 'Loading makefile %s with default directory %s',
LOAD_AGAIN => 'Reloading makefile %s (because of %s) with default directory %s',
LOAD_AUTOMAKE => 'Internally rewriting %s to fix Automake junk (see with --dump-makefile)',
LOAD_CMAKE => 'Internally rewriting %s to fix CMake recursion (see with --dump-makefile)',
LOAD_DEFAULT => 'Loading default makefile for directory %s',
LOAD_END => 'Finished loading %s',
LOAD_INCL => 'Including %s from %s',
LOAD_REC => 'Makefile %s seems recursive, so makefiles for its dependencies will not be implicitly loaded',
LOG => 'Recursive make at %s will log to %s in its destination directory',
MAYBE_STALE => 'Ignoring possibly stale generated file %s',
NOT_FOUND => '%s not found in $PATH at %s',
NOT_IN_SANDBOX => 'Not updating build info for %s because it\'s not in my sandbox',
N_CACHE_HITS => '%d files imported from build cache',
N_FILES => '%d files updated, %d phony targets built and %d targets failed',
N_REP_HITS => '%d files imported from repositories',
OUT_OF_DATE => 'Discarding out-of-date or corrupt build info file %s',
PARSE => 'Parsing command %s from directory %s for rule %s',
PARSE_NONE => 'Parser none for %s for rule %s',
PARSE_SHELL => 'Parser shell %s command %s for rule %s',
PARSE_SKIP_WORD => 'Parser skip_word from %s to %s for rule %s',
PREBUILD => 'Pre-building %s from %s',
REMOVE => 'Removing target %s before running its rule, because %s',
REP_CHECK => 'Check repository file %s',
REP_EXISTING => '... using existing symbolic link',
REP_LINK => 'Linking %s from repository file %s',
REP_LOAD => 'Loading repository %s for %s',
REP_MANIFEST => ' Repository using %s',
REP_OUTDATED => 'Removing outdated repository link %s',
REP_SKIP => 'Skipping generated repository file %s',
RULE_ALL => 'Attempt to recover a rule for all files in %s',
RULE_ALT => 'Alternate rules (%s and %s) for target %s',
RULE_DISCARD_MAKE => ' Rule %s discarded because it invokes $(MAKE)',
RULE_EXTEND => 'Add target %s to rule for %s',
RULE_FAILED => '*** This failed from rule %s',
RULE_IGN_MAKE => ' Rule %s ignored because it invokes $(MAKE)',
RULE_IGN_PATTERN => ' Rule %s ignored because it is a pattern rule',
RULE_NEARER => ' Rule %s chosen because it is from a nearer makefile',
RULE_NEARER_KEPT => ' Rule %s kept because it is from a nearer makefile',
RULE_NEW => 'Recover rule for %s from previous build info',
RULE_SET => 'Rule to build %s from %s at %s',
RULE_SHORTER => ' Rule %s chosen because it has a shorter chain of inference',
SCAN => 'Scanning %s',
SCAN_CACHED => 'Using cached scanner info for %s',
SCAN_C_NOT => 'Not scanning %s due to $Mpp::Scanner::C::dont_scan_hook',
SCAN_INFO => ' Trying to retrieve scan info for %s',
SCAN_INFO_FROM => 'Using %s to retrieve scan info',
SCAN_INFO_NOT => 'Couldn\'t use %s to retrieve scan info because %s',
SCAN_NOT_SYS => 'Not scanning system file %s',
SCAN_NOT_UNWRITABLE => 'Not scanning unwritable file %s',
SCAN_UNCACHEABLE => 'Not caching scan info for %s because the parser for %s doesn\'t support it',
SHELL => 'Shell command %s at %s',
SYMLINK => 'After building, %s is a symbolic link',
SYMLINK_KEEP => 'Keeping symbolic link %s from previous build at %s',
SUCCESS => '%s successfully executed for %s',
TRY => 'Trying to build %s',
UP_TO_DATE => '%s is up to date',
USE => ' Using rule %s',
USE_FAIL => 'Module %s not found',
VAR => 'Variable %s returns value %s at %s',
VAR_EXPAND => 'Variable %s expands value %s at %s',
VERSION => 'Running %s with Perl %s on %s',
);
# This list contains a hashref for every logging version, which is the list
# index. Logging versions must be incremented in makepp's Mpp::log function
# every time one or more symbol's meaning changes incompatibly. Removing a
# symbol, e.g. when renaming it, only requires moving the element from
# %log_msg to $obsolete_msg[<current log version>]. But if a change to the
# same symbol (other than a superficial formulation change) occurs, the old
# text must be copied from %log_msg to $obsolete_msg[<log version before
# incrementing>], before changing it above.
my @obsolete_msg =
({ # V0
INCL => 'Including %s',
INCL_BY => '%s included by %s'
},
{ # V1
N_FILES => '%d files updated and %d targets failed',
SCAN_RULE => 'Scanning rule for %s because %s'
},
{ # V2
REMOVE => 'Removing target %s before running its rule'
});
our $datadir;
BEGIN {
$datadir = '/usr/share/makepp'; unshift @INC, $datadir;
}
use Mpp::Utils;
use Mpp::File;
use Mpp::Text ();
my( $cwd, $instdir, $keylist, $noindent, $rename, $tabulate, $uniq, $tmp );
my( @logfiles, $outfile );
my $follow = 0;
my $prefix = '';
my $showkey = '';
{
my $tmp;
Mpp::Text::getopts
['c', qr/current[-_]?working[-_]?dir(?:ectory)/, \$cwd, 0, 0],
['C', qr/current[-_]?working[-_]?dir(?:ectory)[-_]?and[-_]?up/, \$cwd, 1],
['d', qr/set[-_]?dir(?:ectory)/, \$tmp, 1, sub {
$CWD_INFO = file_info $tmp;
$cwd ||= 0;
}],
[qw(f follow), \$follow],
['i', qr/install(?:ation)?[-_]?dir(?:s|ectory|ectories)/, \$instdir],
['k', qr/key(?:s|list)/, \$keylist, 1],
[qw(K showkey), \$showkey],
['l', qr/log(?:[-_]?file)?/, \$tmp, 1, sub { push @logfiles, $tmp }],
['n', qr/no[-_]?indent/, \$noindent],
[qw(o output), \$outfile, 1],
[qw(p prefix), \$prefix, 0, 'makepplog: '],
[qw(t tabulate), \$tabulate],
['u', qr/uniq(?:ue)?/, \$uniq],
splice @Mpp::Text::common_opts;
}
$| = 1 if $follow > 1;
my %instdir;
sub instdir {
if( s!^((?:[a-z]:)?/.+)(?=/makepp_(?:builtin_rules|default_makefile)\.mk(:|$))!...! && $2 ) {
my $instdir = $1;
s<(:\d+\()((/?)[^\)]*)> {
my $ret = $1;
for( $3 ? "$2" : "$instdir/$2" ) {
my $finfo = file_info $_;
dereference $finfo;
$_ = absolute_filename $finfo;
Mpp::Rewrite::cwd $cwd if defined $cwd;
$ret .= $_;
}
$ret;
}e;
}
}
if( $instdir && defined $cwd ) {
$rename = sub { Mpp::Rewrite::cwd $cwd || &instdir };
} elsif( defined $cwd ) {
$rename = sub { Mpp::Rewrite::cwd $cwd };
} elsif( $instdir ) {
$rename = \&instdir;
}
find_logfiles @logfiles;
open STDOUT, '>', $outfile if $outfile;
if( defined $cwd and defined $keylist ? $keylist !~ /^!-c/ : 1 ) {
my $dir = $CWD_INFO;
printf "${prefix}Replacing `%s' by `.'\n", absolute_filename $dir;
for my $n ( 1..$cwd) {
$dir = $dir->{'..'};
printf "${prefix}Replacing `%s' by `%s'\n", absolute_filename( $dir ),
join '/', ('..') x $n;
}
}
my %want;
my( %incl, %cached_dep, %scan ); # Redundant message counters for --uniq
my $warned_corrupt;
FILE:
for my $logfile ( @logfiles ) {
open my $log, $logfile or die "$0: can't open `$_'--$!\n";
$_ = <$log>;
s/^(\d+)\01//; # Strip log version.
my $log_version = $1 || 0; # Anything obsoleted since that version may
# then have been in use. print;
if( @obsolete_msg ) { # 1st file
for my $version ( $log_version..$#obsolete_msg ) {
$log_msg{$_} = $obsolete_msg[$version]{$_} for keys %{$obsolete_msg[$version]};
}
@obsolete_msg = ();
for( $keylist ) {
last if !defined;
tr/a-z/A-Z/;
s/(?=[?*])/./g;
if( s/\{/(?:/g ) {
tr/,}/|)/ or die "makepplog: error: -k, --keylist contained '{', but no ',' or '}'\n";
} else {
/,/ and die "makepplog: error: -k, --keylist contained ',', but no '{...}'\n";
}
for my $re ( split ) {
if( $re =~ s/^[!^]// ) {
@want{keys %log_msg} = () unless %want;
delete @want{grep /^$re$/, keys %want};
} else {
@want{grep /^$re$/, keys %log_msg} = ();
}
}
}
@want{keys %log_msg} = () if !%want;
}
s!^'?(?:[a-z]:)?/.+(/makepp)\b'?!...\l$1!i if $instdir;
print;
my $indent = '';
my( %dir_name, %file_name, $incl, @incl, $cached_dep, @cached_dep );
RETRY:
while( <$log> ) {
if( $noindent ) {
s/^[\02\03]//s;
} elsif( s/^\03//s ) {
$indent .= ' ';
} elsif( s/^\02//s ) {
substr $indent, -2, 2, '';
}
if( /\01/ ) { # A key/finfos line?
until( /\01\r?\n/m ) {
if( defined( my $more = <$log> )) {
s/\n\Z/\\n/;
$_ .= $more;
} elsif( $follow ) {
sleep 1;
} else {
die "makepplog: error: record is incomplete, use -f, --follow while makepp runs\n";
}
}
# Extract the name definitions
while( s/([\da-f]+)\03([^\01-\03]+)(?:\03([^\01-\03]+)(?:\03([^\01-\03]*))?)?/$1/ ) {
#my( $key, $name, $dirkey, $dirname ) = ( $1, $2, $3, $4 ) -- expensive copy op
if( defined $3 ) { # With dirname
if( defined $4 ) { # Dirname not yet known
$dir_name{$3} = $4; # Save orig for concatenating
for( "$4" ) {
&$rename() if $rename;
$file_name{$3} = $_;
}
}
unless(defined $dir_name{$3}) {
$dir_name{$3} = '???';
warn "Corrupt log file (probably because of concurrent write access to $logfile)" unless $warned_corrupt++;
}
for( $dir_name{$3} eq '/' ? "/$2" : "$dir_name{$3}/$2" ) {
$dir_name{$1} = $_; # Might be a dir.
&$rename() if $rename;
$file_name{$1} = $_;
}
} else {
for( "$2" ) {
&$rename() if $rename;
$file_name{$1} = $_;
}
}
}
my( $key, @args ) = split /\01/;
pop @args; # Remove the newline we kept to work around
# the stupid end handling of split.
if( exists $want{$key} ) {
next if $uniq && $key =~ /^SCAN/ && $scan{$key}{$file_name{$args[0]}}++;
if( $log_version && $key eq 'INCL' ) {
# Merge adjacent INCL statements, which is currently hard to do in makepp.
next
if $uniq && $incl{$file_name{$args[0]}}{$file_name{$args[1]}}++;
if( !defined $incl ) {
INCL:
($incl, @incl) = @args;
next;
} elsif( $incl eq $args[0] ) {
push @incl, $args[1];
next;
}
}
if( defined $incl ) {
# If we get here the previous message was INCL, and this one is not, or is, but for a different file.
$showkey &&= 'INCL ';
printf "$prefix$showkey$indent$log_msg{INCL}\n",
"`$file_name{$incl}'",
'`' . (join $tabulate ? "',\n$prefix$showkey$indent `" : "', `", map $file_name{$_}, @incl) . "'";
no warnings 'deprecated'; # TODO: replace the goto
goto INCL if $key eq 'INCL'; # Next one follows right behind.
undef $incl;
}
if( $key eq 'CACHED_DEP' ) {
# Merge adjacent CACHED_DEP statements, which is currently hard to do in makepp.
next
if $uniq && $cached_dep{$file_name{$args[1]}}{$file_name{$args[0]}}++;
if( !defined $cached_dep ) {
CACHED_DEP:
($cached_dep[0], $cached_dep) = @args;
next;
} elsif( $cached_dep eq $args[1] ) {
push @cached_dep, $args[0];
next;
}
}
if( defined $cached_dep ) {
# If we get here the previous message was CACHED_DEP, and this one is not, or is, but for a different file.
$showkey &&= 'CACHED_DEP ';
printf "$prefix$showkey$indent$log_msg{CACHED_DEP}\n",
'`' . (join $tabulate ? "',\n$prefix$showkey$indent `" : "', `", map $file_name{$_}, @cached_dep) . "'",
"`$file_name{$cached_dep}'";
no warnings 'deprecated'; goto CACHED_DEP if $key eq 'CACHED_DEP'; # Next one follows right behind.
undef $cached_dep;
@cached_dep = ();
}
# Output the actual message.
$showkey &&= "$key ";
printf "$prefix$showkey$indent$log_msg{$key}\n",
$key =~ /^N_/ ?
@args :
map {
$_ eq '' ? '' :
'`' .
(join $tabulate ? "',\n$prefix$showkey$indent `" : "', `",
map exists $file_name{$_} ? $file_name{$_} : do { &$rename() if $rename; $_ }, split /\02/) .
"'";
} @args;
} elsif( !exists $log_msg{$key} ) {
print "$indent$_"; # In case a non structured line somehow contained ^A.
}
next FILE if $follow && $key eq 'N_FILES';
} else {
print "$indent$_";
}
}
if( $follow ) {
sleep 1;
goto RETRY;
}
}
__DATA__
[option ...]
Render and optionally filter what makepp logged about the last build.
Valid options are:
-A filename, --args-file=filename, --arguments-file=filename
Read the file and parse it as possibly quoted whitespace- and/or
newline-separated options.
-c, --current-working-directory, -C number, --current-working-directory-and-up=number
The first two options strip the current directory from the front of all
filenames it outputs.
-d, --set-directory
Virtually switch to the directory where the log file was originally
produced.
-f, --follow
As in tail command, process more lines of logfile as it grows.
-?, -h, --help
Print out a brief summary of the options.
-i, --install-dirs, --installation-directories
These options replace the invocation of makepp and the pathes to the
built in makefiles with .../ so as to keep odd pathes out of your sight.
-k list, --keys=list, --keylist=list
The list specifies one or more space separated Shell style patterns
(with [xyz], ?, *, {a,bc,def}).
-K, --showkey
This prefixes each output line with the internal name of the message
key, for later use with --keys.
-l filename, --log=filename, --log-file=filename
The filename is to where makepp wrote its log.
-n, --no-indent
Makepp puts indentation information into the log file to show you what
happened because of what else.
-o filename, --output=filename
Write the output to this file, rather than stdout.
-p, --prefix
Prefix every structured message with the string "makepplog: ".
-t, --tabulate
Put each list item on a new line, rather than outputting a line that can
easily become longer than a screenful.
-u, --uniq, --unique
Report each found include statement and each scan output only once.
-V, --version
Print out the version number.
|