1N/Apackage ExtUtils::Manifest;
1N/A
1N/Arequire Exporter;
1N/Ause Config;
1N/Ause File::Find;
1N/Ause File::Copy 'copy';
1N/Ause File::Spec;
1N/Ause Carp;
1N/Ause strict;
1N/A
1N/Ause vars qw($VERSION @ISA @EXPORT_OK
1N/A $Is_MacOS $Is_VMS
1N/A $Debug $Verbose $Quiet $MANIFEST $DEFAULT_MSKIP);
1N/A
1N/A$VERSION = 1.42;
1N/A@ISA=('Exporter');
1N/A@EXPORT_OK = qw(mkmanifest
1N/A manicheck filecheck fullcheck skipcheck
1N/A manifind maniread manicopy maniadd
1N/A );
1N/A
1N/A$Is_MacOS = $^O eq 'MacOS';
1N/A$Is_VMS = $^O eq 'VMS';
1N/Arequire VMS::Filespec if $Is_VMS;
1N/A
1N/A$Debug = $ENV{PERL_MM_MANIFEST_DEBUG} || 0;
1N/A$Verbose = defined $ENV{PERL_MM_MANIFEST_VERBOSE} ?
1N/A $ENV{PERL_MM_MANIFEST_VERBOSE} : 1;
1N/A$Quiet = 0;
1N/A$MANIFEST = 'MANIFEST';
1N/A
1N/Amy $Filename = __FILE__;
1N/A$DEFAULT_MSKIP = (File::Spec->splitpath($Filename))[1].
1N/A "$MANIFEST.SKIP";
1N/A
1N/A
1N/A=head1 NAME
1N/A
1N/AExtUtils::Manifest - utilities to write and check a MANIFEST file
1N/A
1N/A=head1 SYNOPSIS
1N/A
1N/A use ExtUtils::Manifest qw(...funcs to import...);
1N/A
1N/A mkmanifest();
1N/A
1N/A my @missing_files = manicheck;
1N/A my @skipped = skipcheck;
1N/A my @extra_files = filecheck;
1N/A my($missing, $extra) = fullcheck;
1N/A
1N/A my $found = manifind();
1N/A
1N/A my $manifest = maniread();
1N/A
1N/A manicopy($read,$target);
1N/A
1N/A maniadd({$file => $comment, ...});
1N/A
1N/A
1N/A=head1 DESCRIPTION
1N/A
1N/A=head2 Functions
1N/A
1N/AExtUtils::Manifest exports no functions by default. The following are
1N/Aexported on request
1N/A
1N/A=over 4
1N/A
1N/A=item mkmanifest
1N/A
1N/A mkmanifest();
1N/A
1N/AWrites all files in and below the current directory to your F<MANIFEST>.
1N/AIt works similar to
1N/A
1N/A find . > MANIFEST
1N/A
1N/AAll files that match any regular expression in a file F<MANIFEST.SKIP>
1N/A(if it exists) are ignored.
1N/A
1N/AAny existing F<MANIFEST> file will be saved as F<MANIFEST.bak>. Lines
1N/Afrom the old F<MANIFEST> file is preserved, including any comments
1N/Athat are found in the existing F<MANIFEST> file in the new one.
1N/A
1N/A=cut
1N/A
1N/Asub _sort {
1N/A return sort { lc $a cmp lc $b } @_;
1N/A}
1N/A
1N/Asub mkmanifest {
1N/A my $manimiss = 0;
1N/A my $read = (-r 'MANIFEST' && maniread()) or $manimiss++;
1N/A $read = {} if $manimiss;
1N/A local *M;
1N/A rename $MANIFEST, "$MANIFEST.bak" unless $manimiss;
1N/A open M, ">$MANIFEST" or die "Could not open $MANIFEST: $!";
1N/A my $skip = _maniskip();
1N/A my $found = manifind();
1N/A my($key,$val,$file,%all);
1N/A %all = (%$found, %$read);
1N/A $all{$MANIFEST} = ($Is_VMS ? "$MANIFEST\t\t" : '') . 'This list of files'
1N/A if $manimiss; # add new MANIFEST to known file list
1N/A foreach $file (_sort keys %all) {
1N/A if ($skip->($file)) {
1N/A # Policy: only remove files if they're listed in MANIFEST.SKIP.
1N/A # Don't remove files just because they don't exist.
1N/A warn "Removed from $MANIFEST: $file\n" if $Verbose and exists $read->{$file};
1N/A next;
1N/A }
1N/A if ($Verbose){
1N/A warn "Added to $MANIFEST: $file\n" unless exists $read->{$file};
1N/A }
1N/A my $text = $all{$file};
1N/A ($file,$text) = split(/\s+/,$text,2) if $Is_VMS && $text;
1N/A $file = _unmacify($file);
1N/A my $tabs = (5 - (length($file)+1)/8);
1N/A $tabs = 1 if $tabs < 1;
1N/A $tabs = 0 unless $text;
1N/A print M $file, "\t" x $tabs, $text, "\n";
1N/A }
1N/A close M;
1N/A}
1N/A
1N/A# Geez, shouldn't this use File::Spec or File::Basename or something?
1N/A# Why so careful about dependencies?
1N/Asub clean_up_filename {
1N/A my $filename = shift;
1N/A $filename =~ s|^\./||;
1N/A $filename =~ s/^:([^:]+)$/$1/ if $Is_MacOS;
1N/A return $filename;
1N/A}
1N/A
1N/A
1N/A=item manifind
1N/A
1N/A my $found = manifind();
1N/A
1N/Areturns a hash reference. The keys of the hash are the files found
1N/Abelow the current directory.
1N/A
1N/A=cut
1N/A
1N/Asub manifind {
1N/A my $p = shift || {};
1N/A my $found = {};
1N/A
1N/A my $wanted = sub {
1N/A my $name = clean_up_filename($File::Find::name);
1N/A warn "Debug: diskfile $name\n" if $Debug;
1N/A return if -d $_;
1N/A
1N/A if( $Is_VMS ) {
1N/A $name =~ s#(.*)\.$#\L$1#;
1N/A $name = uc($name) if $name =~ /^MANIFEST(\.SKIP)?$/i;
1N/A }
1N/A $found->{$name} = "";
1N/A };
1N/A
1N/A # We have to use "$File::Find::dir/$_" in preprocess, because
1N/A # $File::Find::name is unavailable.
1N/A # Also, it's okay to use / here, because MANIFEST files use Unix-style
1N/A # paths.
1N/A find({wanted => $wanted},
1N/A $Is_MacOS ? ":" : ".");
1N/A
1N/A return $found;
1N/A}
1N/A
1N/A
1N/A=item manicheck
1N/A
1N/A my @missing_files = manicheck();
1N/A
1N/Achecks if all the files within a C<MANIFEST> in the current directory
1N/Areally do exist. If C<MANIFEST> and the tree below the current
1N/Adirectory are in sync it silently returns an empty list.
1N/AOtherwise it returns a list of files which are listed in the
1N/AC<MANIFEST> but missing from the directory, and by default also
1N/Aoutputs these names to STDERR.
1N/A
1N/A=cut
1N/A
1N/Asub manicheck {
1N/A return _check_files();
1N/A}
1N/A
1N/A
1N/A=item filecheck
1N/A
1N/A my @extra_files = filecheck();
1N/A
1N/Afinds files below the current directory that are not mentioned in the
1N/AC<MANIFEST> file. An optional file C<MANIFEST.SKIP> will be
1N/Aconsulted. Any file matching a regular expression in such a file will
1N/Anot be reported as missing in the C<MANIFEST> file. The list of any
1N/Aextraneous files found is returned, and by default also reported to
1N/ASTDERR.
1N/A
1N/A=cut
1N/A
1N/Asub filecheck {
1N/A return _check_manifest();
1N/A}
1N/A
1N/A
1N/A=item fullcheck
1N/A
1N/A my($missing, $extra) = fullcheck();
1N/A
1N/Adoes both a manicheck() and a filecheck(), returning then as two array
1N/Arefs.
1N/A
1N/A=cut
1N/A
1N/Asub fullcheck {
1N/A return [_check_files()], [_check_manifest()];
1N/A}
1N/A
1N/A
1N/A=item skipcheck
1N/A
1N/A my @skipped = skipcheck();
1N/A
1N/Alists all the files that are skipped due to your C<MANIFEST.SKIP>
1N/Afile.
1N/A
1N/A=cut
1N/A
1N/Asub skipcheck {
1N/A my($p) = @_;
1N/A my $found = manifind();
1N/A my $matches = _maniskip();
1N/A
1N/A my @skipped = ();
1N/A foreach my $file (_sort keys %$found){
1N/A if (&$matches($file)){
1N/A warn "Skipping $file\n";
1N/A push @skipped, $file;
1N/A next;
1N/A }
1N/A }
1N/A
1N/A return @skipped;
1N/A}
1N/A
1N/A
1N/Asub _check_files {
1N/A my $p = shift;
1N/A my $dosnames=(defined(&Dos::UseLFN) && Dos::UseLFN()==0);
1N/A my $read = maniread() || {};
1N/A my $found = manifind($p);
1N/A
1N/A my(@missfile) = ();
1N/A foreach my $file (_sort keys %$read){
1N/A warn "Debug: manicheck checking from $MANIFEST $file\n" if $Debug;
1N/A if ($dosnames){
1N/A $file = lc $file;
1N/A $file =~ s=(\.(\w|-)+)=substr ($1,0,4)=ge;
1N/A $file =~ s=((\w|-)+)=substr ($1,0,8)=ge;
1N/A }
1N/A unless ( exists $found->{$file} ) {
1N/A warn "No such file: $file\n" unless $Quiet;
1N/A push @missfile, $file;
1N/A }
1N/A }
1N/A
1N/A return @missfile;
1N/A}
1N/A
1N/A
1N/Asub _check_manifest {
1N/A my($p) = @_;
1N/A my $read = maniread() || {};
1N/A my $found = manifind($p);
1N/A my $skip = _maniskip();
1N/A
1N/A my @missentry = ();
1N/A foreach my $file (_sort keys %$found){
1N/A next if $skip->($file);
1N/A warn "Debug: manicheck checking from disk $file\n" if $Debug;
1N/A unless ( exists $read->{$file} ) {
1N/A my $canon = $Is_MacOS ? "\t" . _unmacify($file) : '';
1N/A warn "Not in $MANIFEST: $file$canon\n" unless $Quiet;
1N/A push @missentry, $file;
1N/A }
1N/A }
1N/A
1N/A return @missentry;
1N/A}
1N/A
1N/A
1N/A=item maniread
1N/A
1N/A my $manifest = maniread();
1N/A my $manifest = maniread($manifest_file);
1N/A
1N/Areads a named C<MANIFEST> file (defaults to C<MANIFEST> in the current
1N/Adirectory) and returns a HASH reference with files being the keys and
1N/Acomments being the values of the HASH. Blank lines and lines which
1N/Astart with C<#> in the C<MANIFEST> file are discarded.
1N/A
1N/A=cut
1N/A
1N/Asub maniread {
1N/A my ($mfile) = @_;
1N/A $mfile ||= $MANIFEST;
1N/A my $read = {};
1N/A local *M;
1N/A unless (open M, $mfile){
1N/A warn "$mfile: $!";
1N/A return $read;
1N/A }
1N/A local $_;
1N/A while (<M>){
1N/A chomp;
1N/A next if /^\s*#/;
1N/A
1N/A my($file, $comment) = /^(\S+)\s*(.*)/;
1N/A next unless $file;
1N/A
1N/A if ($Is_MacOS) {
1N/A $file = _macify($file);
1N/A $file =~ s/\\([0-3][0-7][0-7])/sprintf("%c", oct($1))/ge;
1N/A }
1N/A elsif ($Is_VMS) {
1N/A require File::Basename;
1N/A my($base,$dir) = File::Basename::fileparse($file);
1N/A # Resolve illegal file specifications in the same way as tar
1N/A $dir =~ tr/./_/;
1N/A my(@pieces) = split(/\./,$base);
1N/A if (@pieces > 2) { $base = shift(@pieces) . '.' . join('_',@pieces); }
1N/A my $okfile = "$dir$base";
1N/A warn "Debug: Illegal name $file changed to $okfile\n" if $Debug;
1N/A $file = $okfile;
1N/A $file = lc($file) unless $file =~ /^MANIFEST(\.SKIP)?$/;
1N/A }
1N/A
1N/A $read->{$file} = $comment;
1N/A }
1N/A close M;
1N/A $read;
1N/A}
1N/A
1N/A# returns an anonymous sub that decides if an argument matches
1N/Asub _maniskip {
1N/A my @skip ;
1N/A my $mfile = "$MANIFEST.SKIP";
1N/A local(*M,$_);
1N/A open M, $mfile or open M, $DEFAULT_MSKIP or return sub {0};
1N/A while (<M>){
1N/A chomp;
1N/A next if /^#/;
1N/A next if /^\s*$/;
1N/A push @skip, _macify($_);
1N/A }
1N/A close M;
1N/A my $opts = $Is_VMS ? '(?i)' : '';
1N/A
1N/A # Make sure each entry is isolated in its own parentheses, in case
1N/A # any of them contain alternations
1N/A my $regex = join '|', map "(?:$_)", @skip;
1N/A
1N/A return sub { $_[0] =~ qr{$opts$regex} };
1N/A}
1N/A
1N/A=item manicopy
1N/A
1N/A manicopy($src, $dest_dir);
1N/A manicopy($src, $dest_dir, $how);
1N/A
1N/Acopies the files that are the keys in the HASH I<%$src> to the
1N/A$dest_dir. The HASH reference $read is typically returned by the
1N/Amaniread() function. This function is useful for producing a directory
1N/Atree identical to the intended distribution tree. The third parameter
1N/A$how can be used to specify a different methods of "copying". Valid
1N/Avalues are C<cp>, which actually copies the files, C<ln> which creates
1N/Ahard links, and C<best> which mostly links the files but copies any
1N/Asymbolic link to make a tree without any symbolic link. Best is the
1N/Adefault.
1N/A
1N/A=cut
1N/A
1N/Asub manicopy {
1N/A my($read,$target,$how)=@_;
1N/A croak "manicopy() called without target argument" unless defined $target;
1N/A $how ||= 'cp';
1N/A require File::Path;
1N/A require File::Basename;
1N/A
1N/A $target = VMS::Filespec::unixify($target) if $Is_VMS;
1N/A File::Path::mkpath([ $target ],! $Quiet,$Is_VMS ? undef : 0755);
1N/A foreach my $file (keys %$read){
1N/A if ($Is_MacOS) {
1N/A if ($file =~ m!:!) {
1N/A my $dir = _maccat($target, $file);
1N/A $dir =~ s/[^:]+$//;
1N/A File::Path::mkpath($dir,1,0755);
1N/A }
1N/A cp_if_diff($file, _maccat($target, $file), $how);
1N/A } else {
1N/A $file = VMS::Filespec::unixify($file) if $Is_VMS;
1N/A if ($file =~ m!/!) { # Ilya, that hurts, I fear, or maybe not?
1N/A my $dir = File::Basename::dirname($file);
1N/A $dir = VMS::Filespec::unixify($dir) if $Is_VMS;
1N/A File::Path::mkpath(["$target/$dir"],! $Quiet,$Is_VMS ? undef : 0755);
1N/A }
1N/A cp_if_diff($file, "$target/$file", $how);
1N/A }
1N/A }
1N/A}
1N/A
1N/Asub cp_if_diff {
1N/A my($from, $to, $how)=@_;
1N/A -f $from or carp "$0: $from not found";
1N/A my($diff) = 0;
1N/A local(*F,*T);
1N/A open(F,"< $from\0") or die "Can't read $from: $!\n";
1N/A if (open(T,"< $to\0")) {
1N/A local $_;
1N/A while (<F>) { $diff++,last if $_ ne <T>; }
1N/A $diff++ unless eof(T);
1N/A close T;
1N/A }
1N/A else { $diff++; }
1N/A close F;
1N/A if ($diff) {
1N/A if (-e $to) {
1N/A unlink($to) or confess "unlink $to: $!";
1N/A }
1N/A STRICT_SWITCH: {
1N/A best($from,$to), last STRICT_SWITCH if $how eq 'best';
1N/A cp($from,$to), last STRICT_SWITCH if $how eq 'cp';
1N/A ln($from,$to), last STRICT_SWITCH if $how eq 'ln';
1N/A croak("ExtUtils::Manifest::cp_if_diff " .
1N/A "called with illegal how argument [$how]. " .
1N/A "Legal values are 'best', 'cp', and 'ln'.");
1N/A }
1N/A }
1N/A}
1N/A
1N/Asub cp {
1N/A my ($srcFile, $dstFile) = @_;
1N/A my ($perm,$access,$mod) = (stat $srcFile)[2,8,9];
1N/A copy($srcFile,$dstFile);
1N/A utime $access, $mod + ($Is_VMS ? 1 : 0), $dstFile;
1N/A # chmod a+rX-w,go-w
1N/A chmod( 0444 | ( $perm & 0111 ? 0111 : 0 ), $dstFile )
1N/A unless ($^O eq 'MacOS');
1N/A}
1N/A
1N/Asub ln {
1N/A my ($srcFile, $dstFile) = @_;
1N/A return &cp if $Is_VMS or ($^O eq 'MSWin32' and Win32::IsWin95());
1N/A link($srcFile, $dstFile);
1N/A
1N/A # chmod a+r,go-w+X (except "X" only applies to u=x)
1N/A local($_) = $dstFile;
1N/A my $mode= 0444 | (stat)[2] & 0700;
1N/A if (! chmod( $mode | ( $mode & 0100 ? 0111 : 0 ), $_ )) {
1N/A unlink $dstFile;
1N/A return;
1N/A }
1N/A 1;
1N/A}
1N/A
1N/Aunless (defined $Config{d_link}) {
1N/A # Really cool fix from Ilya :)
1N/A local $SIG{__WARN__} = sub {
1N/A warn @_ unless $_[0] =~ /^Subroutine .* redefined/;
1N/A };
1N/A *ln = \&cp;
1N/A}
1N/A
1N/A
1N/A
1N/A
1N/Asub best {
1N/A my ($srcFile, $dstFile) = @_;
1N/A if (-l $srcFile) {
1N/A cp($srcFile, $dstFile);
1N/A } else {
1N/A ln($srcFile, $dstFile) or cp($srcFile, $dstFile);
1N/A }
1N/A}
1N/A
1N/Asub _macify {
1N/A my($file) = @_;
1N/A
1N/A return $file unless $Is_MacOS;
1N/A
1N/A $file =~ s|^\./||;
1N/A if ($file =~ m|/|) {
1N/A $file =~ s|/+|:|g;
1N/A $file = ":$file";
1N/A }
1N/A
1N/A $file;
1N/A}
1N/A
1N/Asub _maccat {
1N/A my($f1, $f2) = @_;
1N/A
1N/A return "$f1/$f2" unless $Is_MacOS;
1N/A
1N/A $f1 .= ":$f2";
1N/A $f1 =~ s/([^:]:):/$1/g;
1N/A return $f1;
1N/A}
1N/A
1N/Asub _unmacify {
1N/A my($file) = @_;
1N/A
1N/A return $file unless $Is_MacOS;
1N/A
1N/A $file =~ s|^:||;
1N/A $file =~ s|([/ \n])|sprintf("\\%03o", unpack("c", $1))|ge;
1N/A $file =~ y|:|/|;
1N/A
1N/A $file;
1N/A}
1N/A
1N/A
1N/A=item maniadd
1N/A
1N/A maniadd({ $file => $comment, ...});
1N/A
1N/AAdds an entry to an existing F<MANIFEST> unless its already there.
1N/A
1N/A$file will be normalized (ie. Unixified). B<UNIMPLEMENTED>
1N/A
1N/A=cut
1N/A
1N/Asub maniadd {
1N/A my($additions) = shift;
1N/A
1N/A _normalize($additions);
1N/A _fix_manifest($MANIFEST);
1N/A
1N/A my $manifest = maniread();
1N/A my @needed = grep { !exists $manifest->{$_} } keys %$additions;
1N/A return 1 unless @needed;
1N/A
1N/A open(MANIFEST, ">>$MANIFEST") or
1N/A die "maniadd() could not open $MANIFEST: $!";
1N/A
1N/A foreach my $file (_sort @needed) {
1N/A my $comment = $additions->{$file} || '';
1N/A printf MANIFEST "%-40s %s\n", $file, $comment;
1N/A }
1N/A close MANIFEST or die "Error closing $MANIFEST: $!";
1N/A
1N/A return 1;
1N/A}
1N/A
1N/A
1N/A# Sometimes MANIFESTs are missing a trailing newline. Fix this.
1N/Asub _fix_manifest {
1N/A my $manifest_file = shift;
1N/A
1N/A open MANIFEST, $MANIFEST or die "Could not open $MANIFEST: $!";
1N/A
1N/A # Yes, we should be using seek(), but I'd like to avoid loading POSIX
1N/A # to get SEEK_*
1N/A my @manifest = <MANIFEST>;
1N/A close MANIFEST;
1N/A
1N/A unless( $manifest[-1] =~ /\n\z/ ) {
1N/A open MANIFEST, ">>$MANIFEST" or die "Could not open $MANIFEST: $!";
1N/A print MANIFEST "\n";
1N/A close MANIFEST;
1N/A }
1N/A}
1N/A
1N/A
1N/A# UNIMPLEMENTED
1N/Asub _normalize {
1N/A return;
1N/A}
1N/A
1N/A
1N/A=back
1N/A
1N/A=head2 MANIFEST
1N/A
1N/AAnything between white space and an end of line within a C<MANIFEST>
1N/Afile is considered to be a comment. Filenames and comments are
1N/Aseparated by one or more TAB characters in the output.
1N/A
1N/A
1N/A=head2 MANIFEST.SKIP
1N/A
1N/AThe file MANIFEST.SKIP may contain regular expressions of files that
1N/Ashould be ignored by mkmanifest() and filecheck(). The regular
1N/Aexpressions should appear one on each line. Blank lines and lines
1N/Awhich start with C<#> are skipped. Use C<\#> if you need a regular
1N/Aexpression to start with a sharp character. A typical example:
1N/A
1N/A # Version control files and dirs.
1N/A \bRCS\b
1N/A \bCVS\b
1N/A ,v$
1N/A \B\.svn\b
1N/A
1N/A # Makemaker generated files and dirs.
1N/A ^MANIFEST\.
1N/A ^Makefile$
1N/A ^blib/
1N/A ^MakeMaker-\d
1N/A
1N/A # Temp, old and emacs backup files.
1N/A ~$
1N/A \.old$
1N/A ^#.*#$
1N/A ^\.#
1N/A
1N/AIf no MANIFEST.SKIP file is found, a default set of skips will be
1N/Aused, similar to the example above. If you want nothing skipped,
1N/Asimply make an empty MANIFEST.SKIP file.
1N/A
1N/A
1N/A=head2 EXPORT_OK
1N/A
1N/AC<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
1N/AC<&maniread>, and C<&manicopy> are exportable.
1N/A
1N/A=head2 GLOBAL VARIABLES
1N/A
1N/AC<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
1N/Aresults in both a different C<MANIFEST> and a different
1N/AC<MANIFEST.SKIP> file. This is useful if you want to maintain
1N/Adifferent distributions for different audiences (say a user version
1N/Aand a developer version including RCS).
1N/A
1N/AC<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
1N/Aall functions act silently.
1N/A
1N/AC<$ExtUtils::Manifest::Debug> defaults to 0. If set to a true value,
1N/Aor if PERL_MM_MANIFEST_DEBUG is true, debugging output will be
1N/Aproduced.
1N/A
1N/A=head1 DIAGNOSTICS
1N/A
1N/AAll diagnostic output is sent to C<STDERR>.
1N/A
1N/A=over 4
1N/A
1N/A=item C<Not in MANIFEST:> I<file>
1N/A
1N/Ais reported if a file is found which is not in C<MANIFEST>.
1N/A
1N/A=item C<Skipping> I<file>
1N/A
1N/Ais reported if a file is skipped due to an entry in C<MANIFEST.SKIP>.
1N/A
1N/A=item C<No such file:> I<file>
1N/A
1N/Ais reported if a file mentioned in a C<MANIFEST> file does not
1N/Aexist.
1N/A
1N/A=item C<MANIFEST:> I<$!>
1N/A
1N/Ais reported if C<MANIFEST> could not be opened.
1N/A
1N/A=item C<Added to MANIFEST:> I<file>
1N/A
1N/Ais reported by mkmanifest() if $Verbose is set and a file is added
1N/Ato MANIFEST. $Verbose is set to 1 by default.
1N/A
1N/A=back
1N/A
1N/A=head1 ENVIRONMENT
1N/A
1N/A=over 4
1N/A
1N/A=item B<PERL_MM_MANIFEST_DEBUG>
1N/A
1N/ATurns on debugging
1N/A
1N/A=back
1N/A
1N/A=head1 SEE ALSO
1N/A
1N/AL<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
1N/A
1N/A=head1 AUTHOR
1N/A
1N/AAndreas Koenig <F<andreas.koenig@anima.de>>
1N/A
1N/A=cut
1N/A
1N/A1;