/usr/share/makepp/Mpp/Signature.pm is in makepp 2.0.98.5-1.
This file is owned by root:root, with mode 0o644.
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 | # $Id: Signature.pm,v 1.15 2012/11/02 20:32:07 pfeiffer Exp $
package Mpp::Signature;
=head1 NAME
Mpp::Signature -- Interface definition for various signature classes
=head1 USAGE
Derive a package from this package.
=head1 DESCRIPTION
Makepp is quite flexible in the algorithm it uses for deciding whether
a target is out of date with respect to its dependencies. Most of this
flexibility is due to various different implementations of the Mpp::Signature
class.
Each rule can have a different signature class associated with it,
if necessary. In the makefile, the signature class is specified by
using the :signature modifier, like this:
%.o : %.c
: signature special_build
$(CC) $(CFLAGS) -c $(FIRST_DEPENDENCY) -o $(TARGET)
This causes the signature class C<Mpp::Signature::special_build> to be used for
this particular rule.
Only one object from each different signature class is actually created; the
object has no data, and its only purpose is to contain a blessed reference to
the package that actually implements the functions. Each rule contains a
reference to the Mpp::Signature object that is appropriate for it. The object is
found by the name of the Mpp::Signature class. For example, the above rule uses
the object referenced by C<$Mpp::Signature::special_build::special_build>. (The
purpose of this naming scheme is to make it impossible to inherit accidentally a
singleton object, which would cause the wrong Mpp::Signature class to be used.)
=head2 signature
$signature = $sigobj->signature($objinfo);
This function returns a signature for the given object (usually a
Mpp::File class, but possibly some other kind of object). A signature is
simply an ASCII string that will change if the object is modified.
$sigobj is the dummy Mpp::Signature class object.
$objinfo is the a reference to B<makepp>'s internal description of that object
and how it is to be built. See L<makepp_extending> for details.
The default signature function simply calls $objinfo->signature, i.e., it uses
the default signature function for objects of that class. For files, this is
the file date concatenated with the file size.
=cut
our $signature = bless []; # Make the singleton object.
sub get {
my( $fullname, $mkfile_line ) = @_;
my( $name, $sep, $re ) = split /(\.\(?|\()/, $fullname, 2;
$name =~ tr/-/_/;
$name = 'c_compilation_md5' if $name eq 'C'; # Alias
my $sig = eval "use Mpp::Signature::$name; \$Mpp::Signature::${name}::$name";
if( defined $re ) {
die "$mkfile_line: Can't add suffixes to inexistent signature $name\n" unless $sig;
die "$mkfile_line: Signature $name doesn't support adding suffixes\n" unless UNIVERSAL::can( $sig, 'recognizes_file' );
my $class = ref( $sig ) . '::_'; # Make an unlikely-to-exist subclass name.
unless( keys %{$class.'::'} ) {
my $super = $sig;
@{$class.'::ISA'} = ref $sig;
*{$class.'::recognizes_file'} = sub {
($_[0][1] ? Mpp::File::absolute_filename $_[1] : $_[1]{NAME}) =~ $_[0][0] or
$super->recognizes_file( $_[1] );
};
}
if( $sep eq '.' ) {
my $orig = $re;
$re = quotemeta $re;
$re =~ s/\\,/|/g and $re = "(?:$re)";
$sig = ${$class."::$orig"} ||= bless [qr/\.$re$/], $class;
} else {
$re =~ s/\)$// or die "$mkfile_line: No final parenthesis in $fullname\n";
$sep eq '.(' && $re =~ /\|/ and $re = "(?:$re)";
$sig = ${$class."::$re"} ||=
bless $sep eq '.(' ? [qr/\.$re$/] : [qr/$re/, $re =~ /\//], $class;
}
}
$sig;
}
sub signature {
return $_[1]->signature;
}
# This is used to determine whether the signature is file content based, as
# opposed to timestamp based. This is used to determine whether the signature
# can be used in a build cache key, because we never want to use
# timestamp-based signatures for that.
sub is_content_based {
# A heuristic that works for all the current Mpp::Signature subclasses, but
# not necessarily for all possible subclasses.
return $_[0] =~ m|^[+/A-Za-z\d]{22}$|;
}
=head1 BUGS
A signature must not contain 22 consecutive characters that are alphanumeric
or '+' or '/', unless the signature is dependent only on file content and
expected to be alias-free.
Otherwise, aliases can cause corruption when you use build caches.
There probably ought to be a more robust way to determine whether a signature
was generated by a method that is prone to aliasing.
=cut
1;
|