mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-12 04:47:17 +04:00
timestamp.pl decides whether a subdir has work to do. It scans the stamp file and the source directories, keeps the newest, and reports that the work is done when the newest one is the stamp. The scan reads the mtime through the core stat of perl, which truncates it to whole seconds, and the comparison is strict with the stamp scanned first. Two files that share a second therefore count as a tie, and a tie says that the work is done. include/subdir.mk touches tmp/.build at the start of a build and the stamp of a subdir at the end, so the two land in the same second once a build takes less than a second between them. The target install stamp is the last one of a build, roughly 0.4 s before the build ends, so it is the one that ties first: the next build then skips target/install and ships the images of the previous build. Around one build in five was affected once the build became fast enough. Read the mtime through Time::HiRes, which reports the fraction as well. Two touches around a fork no longer share a timestamp. Keep the core stat where the module is missing, which restores the old behaviour rather than failing. Signed-off-by: John Crispin <john@phrozen.org>
78 lines
1.8 KiB
Perl
Executable File
78 lines
1.8 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
#
|
|
# Copyright (C) 2006 OpenWrt.org
|
|
#
|
|
# This is free software, licensed under the GNU General Public License v2.
|
|
# See /LICENSE for more information.
|
|
#
|
|
|
|
use strict;
|
|
|
|
# The comparisons below are strict and the stamp file is scanned first, so a
|
|
# file that shares a timestamp with the stamp counts as older and the caller
|
|
# skips the work. Perl truncates the mtime of core stat to whole seconds, which
|
|
# makes that tie reachable whenever two touches fall in the same second. Ask
|
|
# Time::HiRes for the fractional mtime, and keep core stat where the module is
|
|
# missing.
|
|
BEGIN { eval { require Time::HiRes; Time::HiRes->import('stat') } }
|
|
|
|
sub get_ts($$) {
|
|
my $path = shift;
|
|
my $options = shift;
|
|
my $ts = 0;
|
|
my $fn = "";
|
|
$path .= "/" if( -d $path);
|
|
open FIND, "find $path -type f -and -not -path \\*/.svn\\* -and -not -path \\*CVS\\* $options 2>/dev/null |";
|
|
while (<FIND>) {
|
|
chomp;
|
|
my $file = $_;
|
|
next if -l $file;
|
|
my $mt = (stat $file)[9];
|
|
if ($mt > $ts) {
|
|
$ts = $mt;
|
|
$fn = $file;
|
|
}
|
|
}
|
|
close FIND;
|
|
return ($ts, $fn);
|
|
}
|
|
|
|
(@ARGV > 0) or push @ARGV, ".";
|
|
my $ts = 0;
|
|
my $n = ".";
|
|
my %options;
|
|
while (@ARGV > 0) {
|
|
my $path = shift @ARGV;
|
|
if ($path =~ /^-x/) {
|
|
my $str = shift @ARGV;
|
|
$options{"findopts"} .= " -and -not -path '".$str."'"
|
|
} elsif ($path =~ /^-f/) {
|
|
$options{"findopts"} .= " -follow";
|
|
} elsif ($path =~ /^-n/) {
|
|
my $arg = $ARGV[0];
|
|
$options{$path} = $arg;
|
|
} elsif ($path =~ /^-/) {
|
|
$options{$path} = 1;
|
|
} else {
|
|
my ($tmp, $fname) = get_ts($path, $options{"findopts"});
|
|
if ($tmp > $ts) {
|
|
if ($options{'-F'}) {
|
|
$n = $fname;
|
|
} else {
|
|
$n = $path;
|
|
}
|
|
$ts = $tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($options{"-n"}) {
|
|
exit ($n eq $options{"-n"} ? 0 : 1);
|
|
} elsif ($options{"-p"}) {
|
|
print "$n\n";
|
|
} elsif ($options{"-t"}) {
|
|
print "$ts\n";
|
|
} else {
|
|
print "$n\t$ts\n";
|
|
}
|