The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Build.PL 670
Changes 449
MANIFEST 11
META.json 061
META.yml 2133
Makefile.PL 346
lib/ExtUtils/Install.pm 4645
lib/ExtUtils/Installed.pm 716
lib/ExtUtils/Packlist.pm 16
t/Install.t 1491
t/InstallWithMM.t 1218
t/Installapi2.t 1313
t/Installed.t 1147
t/Packlist.t 1015
t/lib/MakeMaker/Test/Setup/BFD.pm 51
t/lib/MakeMaker/Test/Utils.pm 3672
16 files changed (This is a version diff) 251514
@@ -1,67 +0,0 @@
-use strict;
-use Module::Build;
-use lib qw(lib);
-
-# On Win32 things work better if Win32API::File is available.
-# Activestate builds have it by default, but the core distro doesn't
-# so we recommend it on Win32.
-#
-# * BUT *
-#
-# We can't recommend it on the release system as it then goes in the YAML.pl
-# and then non-Win32 CPAN clients think they need it get upset when it fails
-# to build on their system.
-#
-# Until CPAN and Module::Build and the other infrastructure has a better
-# way to deal with this we assume UNIX when building a release.
-#
-# The pre-build stage will moan on Win32 anyway.
-
-my $Recommend_Win32API_File =  $ENV{USERNAME} ne 'demerphq'
-                            && ($^O eq 'MSWin32' || $^O eq 'cygwin');
-
-
-my $builder = Module::Build->new(
-    module_name         => 'ExtUtils::Install',
-    license             => 'perl',
-    dist_name           => 'ExtUtils-Install',
-    dist_author         => 'demerphq <yves@cpan.org>',
-    dist_version_from   => 'lib/ExtUtils/Install.pm',
-    dynamic_config      => 1,
-
-    installdirs         => 'core',
-
-    build_requires => {
-#       'Test::More' => 0, # This is bundled, but not in @INC for prereqs
-    },
-
-    requires => {
-        'perl' => '5.006',
-#        'vars' => 0,
-
-#        'AutoSplit' => 0,
-#        'Exporter' => 0,
-
-        'Carp' => 0,
-#        'Config' => 0,
-
-        'Cwd' => 0,
-
-        'File::Basename' => 0,
-        'File::Compare' => 0,
-        'File::Copy' => 0,
-        'File::Find' => 0,
-        'File::Path' => 0,
-        'File::Spec' => 0,
-
-        ($^O eq 'VMS' ? ('VMS::Filespec' => 0) : ()),
-
-        'ExtUtils::MakeMaker' => 0,
-    },
-
-    recommends => {
-        ($Recommend_Win32API_File ? ('Win32API::File' => 0) : ()),
-    },
-);
-
-$builder->create_build_script();
@@ -1,5 +1,50 @@
 Revision history for ExtUtils-Install
 
+1.68
+
+- Introduce env var PERL_INSTALL_QUIET to silence pm_to_blib() output
+
+1.67
+
+- better -w tests
+
+1.66
+
+- Fix writable tests when running as root
+
+1.65
+
+- ExtUtils::Install handle symbolic and hard links
+
+1.64
+
+- Remove MM_TEST_ROOT feature from ExtUtils::Install tests
+
+1.63
+
+- Enable tests to run in parallel
+
+1.62
+
+- Various POD fixes and typos
+- Cross-compilation fixes
+- VMS fixes
+
+1.57
+
+Adds 'skip_cwd' parameter to ExtUtils::Installed.  With this new parameter,
+the current directory is not included in the installed module search.  This
+avoids finding modules from other perls which happen to be below the
+current directory.
+
+1.56
+
+Pod fixes.
+
+1.55
+
+Pod fixes.
+
 1.54
 
 This is a "no-change" version bump because I pushed the v1.53 change
@@ -85,7 +130,7 @@ SVN revision 39.
 Synchronize with the changes that were made in blead perl
 patch #33567. VMS changes by Craig Berry. See
 
-http://public.activestate.com/cgi-bin/perlbrowse/p/33567
+http://perl5.git.perl.org/perl.git/commit/553b5000d7907cb0cb8f4658c1d6a2aac379415b
 
 This was marked in the pod as 1.51 but not actually version bumped.
 
@@ -113,7 +158,7 @@ http://rt.cpan.org/Ticket/Display.html?id=37727
 Version only released as part of bleadperl added in revision #33566.
 Cygwin related changes by Steve Hay, and others, see
 
-http://public.activestate.com/cgi-bin/perlbrowse/p/33566
+http://perl5.git.perl.org/perl.git/commit/038ae9a45711aea142f721498a4a61353b40c4e4
 
 and discussion at
 
@@ -128,7 +173,7 @@ highlight the pod properly.
 
 1.49
 
-Turns out that the new can_write_dir.t doesnt work properly under root
+Turns out that the new can_write_dir.t doesn't work properly under root
 as root can read the files regardless as to their mode. So we skip those
 tests when the effective UID is 0 indicating root.
 
@@ -276,7 +321,7 @@ This means that you can make .svn directories be ignored on install.
 
 - Integrated patch from Randy Sims.
 
-    1. Fixes error during `perl Makefile.PL` because it MakeMaker can't
+    1. Fixes error during 'perl Makefile.PL' because it MakeMaker can't
     find the NAME section describing DISTNAME (which has the 'ex-'
     prefix).
 
@@ -1,4 +1,3 @@
-Build.PL
 Changes
 INSTALL.SKIP
 lib/ExtUtils/Install.pm
@@ -7,6 +6,7 @@ lib/ExtUtils/Packlist.pm
 Makefile.PL
 MANIFEST
 MANIFEST.SKIP
+META.json
 META.yml
 README
 t/can_write_dir.t
@@ -0,0 +1,61 @@
+{
+   "abstract" : "install files from here to there",
+   "author" : [
+      "demerphq <yves@cpan.org>"
+   ],
+   "dynamic_config" : 1,
+   "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141520",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : "2"
+   },
+   "name" : "ExtUtils-Install",
+   "no_index" : {
+      "directory" : [
+         "t",
+         "inc"
+      ]
+   },
+   "prereqs" : {
+      "build" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "Carp" : "0",
+            "Cwd" : "0",
+            "ExtUtils::MakeMaker" : "0",
+            "File::Basename" : "0",
+            "File::Compare" : "0",
+            "File::Copy" : "0",
+            "File::Find" : "0",
+            "File::Path" : "0",
+            "File::Spec" : "0",
+            "File::Temp" : "0"
+         }
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "mailto" : "perlbug@perl.org",
+         "web" : "http://rt.perl.org/rt3/"
+      },
+      "repository" : {
+         "type" : "git",
+         "url" : "git://perl5.git.perl.org/perl.git",
+         "web" : "http://perl5.git.perl.org/perl.git/"
+      }
+   },
+   "version" : "1.68"
+}
@@ -1,22 +1,34 @@
---- #YAML:1.0
-name:                ExtUtils-Install
-version:             1.54
-abstract:            install files from here to there
-license:             ~
-author:              
-    - demerphq <yves@cpan.org>
-generated_by:        ExtUtils::MakeMaker version 6.42
-distribution_type:   module
-requires:     
-    Carp:                          0
-    Cwd:                           0
-    ExtUtils::MakeMaker:           0
-    File::Basename:                0
-    File::Compare:                 0
-    File::Copy:                    0
-    File::Find:                    0
-    File::Path:                    0
-    File::Spec:                    0
+---
+abstract: 'install files from here to there'
+author:
+  - 'demerphq <yves@cpan.org>'
+build_requires:
+  ExtUtils::MakeMaker: '0'
+configure_requires:
+  ExtUtils::MakeMaker: '0'
+dynamic_config: 1
+generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141520'
+license: perl
 meta-spec:
-    url:     http://module-build.sourceforge.net/META-spec-v1.3.html
-    version: 1.3
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: '1.4'
+name: ExtUtils-Install
+no_index:
+  directory:
+    - t
+    - inc
+requires:
+  Carp: '0'
+  Cwd: '0'
+  ExtUtils::MakeMaker: '0'
+  File::Basename: '0'
+  File::Compare: '0'
+  File::Copy: '0'
+  File::Find: '0'
+  File::Path: '0'
+  File::Spec: '0'
+  File::Temp: '0'
+resources:
+  bugtracker: http://rt.perl.org/rt3/
+  repository: git://perl5.git.perl.org/perl.git
+version: '1.68'
@@ -23,7 +23,11 @@ my $Recommend_Win32API_File =  $ENV{USERNAME} ne 'demerphq'
 
 use ExtUtils::MakeMaker;
 
-WriteMakefile(
+WriteMakefile1(
+    LICENSE => 'perl',
+    #BUILD_REQUIRES => {
+    #},
+
     NAME                => 'ExtUtils::Install',
     AUTHOR              => 'demerphq <yves@cpan.org>',
     VERSION_FROM        => 'lib/ExtUtils/Install.pm',
@@ -52,6 +56,7 @@ WriteMakefile(
         'File::Find' => 0,
         'File::Path' => 0,
         'File::Spec' => 0,
+        'File::Temp' => 0,
 
         ($^O eq 'VMS' ? ('VMS::Filespec' => 0) : ()),
         ($Recommend_Win32API_File ? ('Win32API::File' => 0) : ()),
@@ -61,12 +66,27 @@ WriteMakefile(
 #       'Test::More' => 0, # This is bundled, but not in @INC for prereqs
     },
 
-    INSTALLDIRS     => 'perl', # install into site not into lib.
-    
+    INSTALLDIRS     => ( $] < 5.012 ? 'perl' : 'site' ),
+
     #NO_META => 1,
 
     dist  => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
     clean => { FILES => 'ExtUtils-Install-*' },
+
+    META_MERGE => {
+      "meta-spec" => { version => 2 },
+      resources => {
+        repository => {
+          type => 'git',
+          url => 'git://perl5.git.perl.org/perl.git',
+          web => 'http://perl5.git.perl.org/perl.git/',
+        },
+        bugtracker => {
+         "mailto" => 'perlbug@perl.org',
+         "web"    => 'http://rt.perl.org/rt3/',
+        },
+      },
+    },
 );
 
 {
@@ -87,3 +107,26 @@ WriteMakefile(
         $self->{FULLPERLRUN} .= qq{ "-I$lib"};
     }
 }
+
+sub WriteMakefile1 {  #Written by Alexandr Ciornii, version 0.21. Added by eumm-upgrade.
+    my %params=@_;
+    my $eumm_version=$ExtUtils::MakeMaker::VERSION;
+    $eumm_version=eval $eumm_version;
+    die "EXTRA_META is deprecated" if exists $params{EXTRA_META};
+    die "License not specified" if not exists $params{LICENSE};
+    if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) {
+        #EUMM 6.5502 has problems with BUILD_REQUIRES
+        $params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} };
+        delete $params{BUILD_REQUIRES};
+    }
+    delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52;
+    delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48;
+    delete $params{META_MERGE} if $eumm_version < 6.46;
+    delete $params{META_ADD} if $eumm_version < 6.46;
+    delete $params{LICENSE} if $eumm_version < 6.31;
+    delete $params{AUTHOR} if $] < 5.005;
+    delete $params{ABSTRACT_FROM} if $] < 5.005;
+    delete $params{BINARY_LOCATION} if $] < 5.005;
+
+    WriteMakefile(%params);
+}
@@ -38,11 +38,11 @@ ExtUtils::Install - install files from here to there
 
 =head1 VERSION
 
-1.54
+1.68
 
 =cut
 
-$VERSION = '1.54';  # <---- dont forget to update the POD section just above this line!
+$VERSION = '1.68';  # <-- do not forget to update the POD section just above this line!
 $VERSION = eval $VERSION;
 
 =pod
@@ -57,7 +57,7 @@ ExtUtils::MakeMaker handles the installation and deinstallation of
 perl modules. They are not designed as general purpose tools.
 
 On some operating systems such as Win32 installation may not be possible
-until after a reboot has occured. This can have varying consequences:
+until after a reboot has occurred. This can have varying consequences:
 removing an old DLL does not impact programs using the new one, but if
 a new DLL cannot be installed properly until reboot then anything
 depending on it must wait. The package variable
@@ -66,13 +66,15 @@ depending on it must wait. The package variable
 
 is used to store this status.
 
-If this variable is true then such an operation has occured and
+If this variable is true then such an operation has occurred and
 anything depending on this module cannot proceed until a reboot
-has occured.
+has occurred.
 
 If this value is defined but false then such an operation has
 ocurred, but should not impact later operations.
 
+=over
+
 =begin _private
 
 =item _chmod($$;$)
@@ -87,39 +89,18 @@ Warns about something only once.
 
 Dies with a special message.
 
+=back
+
 =end _private
 
 =cut
 
 my $Is_VMS     = $^O eq 'VMS';
-my $Is_VMS_noefs = $Is_VMS;
 my $Is_MacPerl = $^O eq 'MacOS';
 my $Is_Win32   = $^O eq 'MSWin32';
 my $Is_cygwin  = $^O eq 'cygwin';
 my $CanMoveAtBoot = ($Is_Win32 || $Is_cygwin);
 
-    if( $Is_VMS ) {
-        my $vms_unix_rpt;
-        my $vms_efs;
-        my $vms_case;
-
-        if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
-            $vms_unix_rpt = VMS::Feature::current("filename_unix_report");
-            $vms_efs = VMS::Feature::current("efs_charset");
-            $vms_case = VMS::Feature::current("efs_case_preserve");
-        } else {
-            my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
-            my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || '';
-            my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
-            $vms_unix_rpt = $unix_rpt =~ /^[ET1]/i;
-            $vms_efs = $efs_charset =~ /^[ET1]/i;
-            $vms_case = $efs_case =~ /^[ET1]/i;
-        }
-        $Is_VMS_noefs = 0 if ($vms_efs);
-    }
-
-
-
 # *note* CanMoveAtBoot is only incidentally the same condition as below
 # this needs not hold true in the future.
 my $Has_Win32API_File = ($Is_Win32 || $Is_cygwin)
@@ -132,6 +113,7 @@ my $Inc_uninstall_warn_handler;
 # install relative to here
 
 my $INSTALL_ROOT = $ENV{PERL_INSTALL_ROOT};
+my $INSTALL_QUIET = $ENV{PERL_INSTALL_QUIET};
 
 my $Curdir = File::Spec->curdir;
 my $Updir  = File::Spec->updir;
@@ -169,6 +151,8 @@ sub _chmod($$;$) {
 
 =begin _private
 
+=over
+
 =item _move_file_at_boot( $file, $target, $moan  )
 
 OS-Specific, Win32/Cygwin
@@ -179,7 +163,7 @@ $target should be a ref to an array if the file is to be deleted
 otherwise it should be a filespec for a rename. If the file is existing
 it will be replaced.
 
-Sets $MUST_REBOOT to 0 to indicate a deletion operation has occured
+Sets $MUST_REBOOT to 0 to indicate a deletion operation has occurred
 and sets it to 1 to indicate that a move operation has been requested.
 
 returns 1 on success, on failure if $moan is false errors are fatal.
@@ -235,6 +219,7 @@ sub _move_file_at_boot { #XXX OS-SPECIFIC
 
 =begin _private
 
+
 =item _unlink_or_rename( $file, $tryhard, $installing )
 
 OS-Specific, Win32/Cygwin
@@ -271,7 +256,14 @@ On failure throws a fatal error.
 sub _unlink_or_rename { #XXX OS-SPECIFIC
     my ( $file, $tryhard, $installing )= @_;
 
-    _chmod( 0666, $file );
+    # this chmod was originally unconditional. However, its not needed on
+    # POSIXy systems since permission to unlink a file is specified by the
+    # directory rather than the file; and in fact it screwed up hard- and
+    # symlinked files. Keep it for other platforms in case its still
+    # needed there.
+    if ($^O =~ /^(dos|os2|MSWin32|VMS)$/) {
+        _chmod( 0666, $file );
+    }
     my $unlink_count = 0;
     while (unlink $file) { $unlink_count++; }
     return $file if $unlink_count > 0;
@@ -288,7 +280,7 @@ sub _unlink_or_rename { #XXX OS-SPECIFIC
          "Going to try to rename it to '$tmp'.\n";
 
     if ( rename $file, $tmp ) {
-        warn "Rename succesful. Scheduling '$tmp'\nfor deletion at reboot.\n";
+        warn "Rename successful. Scheduling '$tmp'\nfor deletion at reboot.\n";
         # when $installing we can set $moan to true.
         # IOW, if we cant delete the renamed file at reboot its
         # not the end of the world. The other cases are more serious
@@ -301,7 +293,7 @@ sub _unlink_or_rename { #XXX OS-SPECIFIC
         _move_file_at_boot( $tmp, $file );
         return $tmp;
     } else {
-        _choke("Rename failed:$!", "Cannot procede.");
+        _choke("Rename failed:$!", "Cannot proceed.");
     }
 
 }
@@ -309,10 +301,14 @@ sub _unlink_or_rename { #XXX OS-SPECIFIC
 
 =pod
 
+=back
+
 =head2 Functions
 
 =begin _private
 
+=over
+
 =item _get_install_skip
 
 Handles loading the INSTALL.SKIP file. Returns an array of patterns to use.
@@ -404,7 +400,7 @@ be created first.
 
 Returns a list, containing: C<($writable, $determined_by, @create)>
 
-C<$writable> says whether whether the directory is (hypothetically) writable
+C<$writable> says whether the directory is (hypothetically) writable
 
 C<$determined_by> is the directory the status was determined from. It will be
 either the C<$dir>, or one of its parents.
@@ -429,9 +425,7 @@ sub _can_write_dir {
     my $path='';
     my @make;
     while (@dirs) {
-        if ($Is_VMS_noefs) {
-            # There is a bug in catdir that is fixed when the EFS character
-            # set is enabled, which requires this VMS specific code.
+        if ($Is_VMS) {
             $dir = File::Spec->catdir($vol,@dirs);
         }
         else {
@@ -509,7 +503,7 @@ sub _mkpath {
 
 Wrapper around File::Copy::copy to handle errors.
 
-If $verbose is true and >1 then additional dignostics will be emitted.
+If $verbose is true and >1 then additional diagnostics will be emitted.
 
 If $dry_run is true then the copy will not actually occur.
 
@@ -554,9 +548,11 @@ sub _chdir {
 
 =pod
 
+=back
+
 =end _private
 
-=over 4
+=over
 
 =item B<install>
 
@@ -622,7 +618,7 @@ As of version 1.47 the following additions were made to the install interface.
 Note that the new argument style and use of the %result hash is recommended.
 
 The $always_copy parameter which when true causes files to be updated
-regardles as to whether they have changed, if it is defined but false then
+regardless as to whether they have changed, if it is defined but false then
 copies are made only if the files have changed, if it is undefined then the
 value of the environment variable EU_INSTALL_ALWAYS_COPY is used as default.
 
@@ -657,7 +653,7 @@ B<NEW ARGUMENT STYLE>
 If there is only one argument and it is a reference to an array then
 the array is assumed to contain a list of key-value pairs specifying
 the options. In this case the option "from_to" is mandatory. This style
-means that you dont have to supply a cryptic list of arguments and can
+means that you do not have to supply a cryptic list of arguments and can
 use a self documenting argument list that is easier to understand.
 
 This is now the recommended interface to install().
@@ -781,7 +777,7 @@ sub install { #XXX OS-SPECIFIC
 
                 ];
             #restore the original directory we were in when File::Find
-            #called us so that it doesnt get horribly confused.
+            #called us so that it doesn't get horribly confused.
             _chdir($save_cwd);
         }, $current_directory );
         _chdir($cwd);
@@ -854,7 +850,7 @@ sub install { #XXX OS-SPECIFIC
 
 =item _do_cleanup
 
-Standardize finish event for after another instruction has occured.
+Standardize finish event for after another instruction has occurred.
 Handles converting $MUST_REBOOT to a die for instance.
 
 =end _private
@@ -1047,7 +1043,7 @@ sub uninstall {
 
 Remove shadowed files. If $ignore is true then it is assumed to hold
 a filename to ignore. This is used to prevent spurious warnings from
-occuring when doing an install at reboot.
+occurring when doing an install at reboot.
 
 We now only die when failing to remove a file that has precedence over
 our own, when our install has precedence we only warn.
@@ -1176,6 +1172,9 @@ output the new module contents.
 You can have an environment variable PERL_INSTALL_ROOT set which will
 be prepended as a directory to each installed file (and directory).
 
+By default verbose output is generated, setting the PERL_INSTALL_QUIET
+environment variable will silence this output.
+
 =cut
 
 sub pm_to_blib {
@@ -1184,7 +1183,7 @@ sub pm_to_blib {
     _mkpath($autodir,0,0755);
     while(my($from, $to) = each %$fromto) {
         if( -f $to && -s $from == -s $to && -M $to < -M $from ) {
-            print "Skip $to (unchanged)\n";
+            print "Skip $to (unchanged)\n" unless $INSTALL_QUIET;
             next;
         }
 
@@ -1197,7 +1196,7 @@ sub pm_to_blib {
                              $from =~ /\.pm$/;
 
         if (!$need_filtering && 0 == compare($from,$to)) {
-            print "Skip $to (unchanged)\n";
+            print "Skip $to (unchanged)\n" unless $INSTALL_QUIET;
             next;
         }
         if (-f $to){
@@ -1211,7 +1210,7 @@ sub pm_to_blib {
             print "$pm_filter <$from >$to\n";
         } else {
             _copy( $from, $to );
-            print "cp $from $to\n";
+            print "cp $from $to\n" unless $INSTALL_QUIET;
         }
         my($mode,$atime,$mtime) = (stat $from)[2,8,9];
         utime($atime,$mtime+$Is_VMS,$to);
@@ -17,7 +17,7 @@ my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/);
 require VMS::Filespec if $Is_VMS;
 
 use vars qw($VERSION);
-$VERSION = '1.999_001';
+$VERSION = '1.999005';
 $VERSION = eval $VERSION;
 
 sub _is_prefix {
@@ -162,7 +162,9 @@ sub new {
     }
     {
         my %dupe;
-        @{$self->{':private:'}{LIBDIRS}} = grep { -e $_ && !$dupe{$_}++ }
+        @{$self->{':private:'}{LIBDIRS}} =
+            grep { $_ ne '.' || ! $args{skip_cwd} }
+            grep { -e $_ && !$dupe{$_}++ }
             @{$self->{':private:'}{EXTRA}}, @{$self->{':private:'}{INC}};
     }
 
@@ -327,7 +329,7 @@ ExtUtils::Installed - Inventory management of installed modules
 =head1 SYNOPSIS
 
    use ExtUtils::Installed;
-   my ($inst) = ExtUtils::Installed->new();
+   my ($inst) = ExtUtils::Installed->new( skip_cwd => 1 );
    my (@modules) = $inst->modules();
    my (@missing) = $inst->validate("DBI");
    my $all_files = $inst->files("DBI");
@@ -369,6 +371,11 @@ information from C<%Config::Config> and the default module search
 paths C<@INC>. The packlists are read using the
 L<ExtUtils::Packlist> module.
 
+If the named parameter C<skip_cwd> is true, the current directory C<.> will
+be stripped from C<@INC> before searching for .packlists.  This keeps
+ExtUtils::Installed from finding modules installed in other perls that
+happen to be located below the current directory.
+
 If the named parameter C<config_override> is specified,
 it should be a reference to a hash which contains all information
 usually found in C<%Config::Config>. For example, you can obtain
@@ -376,7 +383,8 @@ the configuration information for a separate perl installation and
 pass that in.
 
     my $yoda_cfg  = get_fake_config('yoda');
-    my $yoda_inst = ExtUtils::Installed->new(config_override=>$yoda_cfg);
+    my $yoda_inst =
+               ExtUtils::Installed->new(config_override=>$yoda_cfg);
 
 Similarly, the parameter C<inc_override> may be a reference to an
 array which is used in place of the default module search paths
@@ -389,12 +397,13 @@ from C<@INC>.
 B<Note>: You probably do not want to use these options alone, almost always
 you will want to set both together.
 
-The parameter c<extra_libs> can be used to specify B<additional> paths to
+The parameter C<extra_libs> can be used to specify B<additional> paths to
 search for installed modules. For instance
 
-    my $installed = ExtUtils::Installed->new(extra_libs=>["/my/lib/path"]);
+    my $installed =
+             ExtUtils::Installed->new(extra_libs=>["/my/lib/path"]);
 
-This should only be necessary if C</my/lib/path> is not in PERL5LIB.
+This should only be necessary if F</my/lib/path> is not in PERL5LIB.
 
 Finally there is the 'default', and the related 'default_get' and 'default_set'
 options. These options control the "default" object which is provided by the
@@ -5,7 +5,7 @@ use strict;
 use Carp qw();
 use Config;
 use vars qw($VERSION $Relocations);
-$VERSION = '1.43';
+$VERSION = '1.48';
 $VERSION = eval $VERSION;
 
 # Used for generating filehandle globs.  IO::File might not be available!
@@ -13,6 +13,8 @@ my $fhname = "FH1";
 
 =begin _undocumented
 
+=over
+
 =item mkfh()
 
 Make a filehandle. Same kind of idea as Symbol::gensym().
@@ -22,6 +24,7 @@ Make a filehandle. Same kind of idea as Symbol::gensym().
 sub mkfh()
 {
 no strict;
+local $^W;
 my $fh = \*{$fhname++};
 use strict;
 return($fh);
@@ -32,6 +35,8 @@ return($fh);
 Works out what absolute paths in the configuration have been located at run
 time relative to $^X, and generates a regexp that matches them
 
+=back
+
 =end _undocumented
 
 =cut
@@ -3,38 +3,38 @@
 # Test ExtUtils::Install.
 
 BEGIN {
-    if( $ENV{PERL_CORE} ) {
-        @INC = ('../../lib', '../lib', 'lib');
-    }
-    else {
-        unshift @INC, 't/lib';
-    }
+    unshift @INC, 't/lib';
 }
-chdir 't';
 
 use strict;
 use TieOut;
 use File::Path;
 use File::Spec;
+use File::Temp qw[tempdir];
 
-use Test::More tests => 52;
+use Test::More tests => 60;
 
 use MakeMaker::Test::Setup::BFD;
 
-BEGIN { use_ok('ExtUtils::Install') }
-# ensure the env doesnt pollute our tests
+BEGIN {
+  local $ENV{PERL_INSTALL_QUIET};
+  use_ok('ExtUtils::Install');
+}
+# ensure the env doesn't pollute our tests
 local $ENV{EU_INSTALL_ALWAYS_COPY};
-local $ENV{EU_ALWAYS_COPY};    
+local $ENV{EU_ALWAYS_COPY};
 
 # Check exports.
 foreach my $func (qw(install uninstall pm_to_blib install_default)) {
     can_ok(__PACKAGE__, $func);
 }
 
+my $tmpdir = tempdir( DIR => 't', CLEANUP => 1 );
+chdir $tmpdir;
 
 ok( setup_recurs(), 'setup' );
 END {
-    ok( chdir File::Spec->updir );
+    ok( chdir File::Spec->updir, 'chdir ..');
     ok( teardown_recurs(), 'teardown' );
 }
 
@@ -51,6 +51,7 @@ ok( -r 'blib/lib/Big/Dummy.pm', '  copied .pm file' );
 ok( -r 'blib/lib/auto',         '  created autosplit dir' );
 is( $stdout->read, "cp lib/Big/Dummy.pm blib/lib/Big/Dummy.pm\n" );
 
+
 pm_to_blib( { 'lib/Big/Dummy.pm' => 'blib/lib/Big/Dummy.pm' },
             'blib/lib/auto'
           );
@@ -59,6 +60,7 @@ ok( -r 'blib/lib/Big/Dummy.pm', '  .pm file still there' );
 ok( -r 'blib/lib/auto',         '  autosplit still there' );
 is( $stdout->read, "Skip blib/lib/Big/Dummy.pm (unchanged)\n" );
 
+
 install( { 'blib/lib' => 'install-test/lib/perl',
            read   => 'install-test/packlist',
            write  => 'install-test/packlist'
@@ -125,7 +127,7 @@ close DUMMY;
                                              '  UNINST=0 left different' );
 }
 
-# Test UNINST=1 only warning when failing to remove an irrelevent shadow file
+# Test UNINST=1 only warning when failing to remove an irrelevant shadow file
 {
   my $tfile='install-test/lib/perl/Big/Dummy.pm';
   local $ExtUtils::Install::Testing = $tfile; 
@@ -151,7 +153,7 @@ close DUMMY;
   
 }
 
-# Test UNINST=1 dieing when failing to remove an relevent shadow file
+# Test UNINST=1 dieing when failing to remove an relevant shadow file
 {
   my $tfile='install-test/lib/perl/Big/Dummy.pm';
   local $ExtUtils::Install::Testing = $tfile;
@@ -192,3 +194,78 @@ close DUMMY;
                                              '  UNINST=1 removed different' );
 }
 
+
+# do a -w style test, but based on just on file perms rather than UID
+# (on UNIX, root sees everything as writeable)
+
+sub writeable {
+    my ($file) = @_;
+    my @stat = stat $file;
+    return 0 unless defined $stat[2]; # mode
+    return $stat[2] & 0200;
+}
+
+
+# really this test should be run on any platform that supports
+# symbolic and hard links, but this representative sample should do for
+# now
+
+
+# check hard and symbolic links
+
+SKIP: {
+    my $has_links =
+        $^O =~ /^(aix|bsdos|darwin|freebsd|hpux|irix|linux|openbsd|solaris)$/;
+    skip "(sym)links not supported", 8 unless $has_links;
+
+    install([ from_to => { 'blib/lib/' => 'install-links',
+                           read   => 'install-links/packlist',
+                           write  => 'install-links/packlist'
+                         },
+    ]);
+
+    # make orig file a hard link and check that it doesn't get messed up
+
+    my $bigdir = 'install-links/Big';
+    ok link("$bigdir/Dummy.pm", "$bigdir/DummyHard.pm"),
+        'link DummyHard.pm';
+
+    open(my $fh, ">>", "blib/lib/Big/Dummy.pm") or die $!;
+    print $fh "Extra stuff 2\n";
+    close $fh;
+
+    install([ from_to => { 'blib/lib/' => 'install-links',
+                           read   => 'install-links/packlist',
+                           write  => 'install-links/packlist'
+                         },
+    ]);
+
+    ok( !writeable("$bigdir/DummyHard.pm"), 'DummyHard.pm not writeable' );
+
+    use File::Compare;
+    ok(compare("$bigdir/Dummy.pm", "$bigdir/DummyHard.pm"),
+        "hard-linked file should be different");
+
+    # make orig file a symlink and check that it doesn't get messed up
+
+    ok rename("$bigdir/Dummy.pm", "$bigdir/DummyOrig.pm"),
+        'rename DummyOrig.pm';
+    ok symlink('DummyOrig.pm', "$bigdir/Dummy.pm"),
+        'symlink Dummy.pm';
+
+
+    open($fh, ">>", "blib/lib/Big/Dummy.pm") or die $!;
+    print $fh "Extra stuff 3\n";
+    close $fh;
+
+    install([ from_to => { 'blib/lib/' => 'install-links',
+                           read   => 'install-links/packlist',
+                           write  => 'install-links/packlist'
+                         },
+    ]);
+
+    ok( !writeable("$bigdir/DummyOrig.pm"), 'DummyOrig.pm not writeable' );
+    ok( !-l "$bigdir/Dummy.pm", 'Dummy.pm not a link' );
+    ok(compare("$bigdir/Dummy.pm", "$bigdir/DummyOrig.pm"),
+        "orig file should be different");
+}
@@ -3,27 +3,32 @@
 # Make sure EUI works with MakeMaker
 
 BEGIN {
-    if( $ENV{PERL_CORE} ) {
-        chdir 't' if -d 't';
-        @INC = ('../lib', 'lib');
-    }
-    else {
-        unshift @INC, 't/lib';
-    }
+    unshift @INC, 't/lib';
 }
 
 use strict;
 use Config;
 use ExtUtils::MakeMaker;
 
-use Test::More tests => 15;
+use Test::More;
 use MakeMaker::Test::Utils;
+
+my $make;
+BEGIN {
+    $make = make_run();
+    if (!$make) {
+	plan skip_all => "make isn't available";
+    }
+    else {
+	plan tests => 15;
+    }
+}
+
 use MakeMaker::Test::Setup::BFD;
 use File::Find;
 use File::Spec;
 use File::Path;
-
-my $make = make_run();
+use File::Temp qw[tempdir];
 
 # Environment variables which interfere with our testing.
 delete @ENV{qw(PREFIX LIB MAKEFLAGS)};
@@ -33,10 +38,11 @@ delete @ENV{qw(PREFIX LIB MAKEFLAGS)};
     my $perl = which_perl();
     my $Is_VMS = $^O eq 'VMS';
 
-    chdir 't';
-
     perl_lib;
 
+    my $tmpdir = tempdir( DIR => 't', CLEANUP => 1 );
+    chdir $tmpdir;
+
     my $Touch_Time = calibrate_mtime();
 
     $| = 1;
@@ -3,41 +3,41 @@
 # Test ExtUtils::Install.
 
 BEGIN {
-    if( $ENV{PERL_CORE} ) {
-        @INC = ('../../lib', '../lib', 'lib');
-    }
-    else {
-        unshift @INC, 't/lib';
-    }
+    unshift @INC, 't/lib';
 }
-chdir 't';
 
 use strict;
 use TieOut;
 use File::Path;
 use File::Spec;
+use File::Temp qw[tempdir];
 
 use Test::More tests => 70;
 
 use MakeMaker::Test::Setup::BFD;
 
-BEGIN { use_ok('ExtUtils::Install') }
+BEGIN {
+  local $ENV{PERL_INSTALL_QUIET};
+  use_ok('ExtUtils::Install');
+}
 
 # Check exports.
 foreach my $func (qw(install uninstall pm_to_blib install_default)) {
     can_ok(__PACKAGE__, $func);
 }
 
+my $tmpdir = tempdir( DIR => 't', CLEANUP => 1 );
+chdir $tmpdir;
 
 ok( setup_recurs(), 'setup' );
 END {
     ok( chdir File::Spec->updir );
     ok( teardown_recurs(), 'teardown' );
 }
-# ensure the env doesnt pollute our tests
+# ensure the env doesn't pollute our tests
 local $ENV{EU_INSTALL_ALWAYS_COPY};
-local $ENV{EU_ALWAYS_COPY};    
-    
+local $ENV{EU_ALWAYS_COPY};
+
 chdir 'Big-Dummy';
 
 my $stdout = tie *STDOUT, 'TieOut';
@@ -124,7 +124,7 @@ close DUMMY;
                                              '  UNINST=0 left different' );
 }
 
-# Test UNINST=1 only warning when failing to remove an irrelevent shadow file
+# Test UNINST=1 only warning when failing to remove an irrelevant shadow file
 {
   my $tfile='install-test/lib/perl/Big/Dummy.pm';
   local $ExtUtils::Install::Testing = $tfile; 
@@ -150,7 +150,7 @@ close DUMMY;
   
 }
 
-# Test UNINST=1 dieing when failing to remove an relevent shadow file
+# Test UNINST=1 dieing when failing to remove an relevant shadow file
 {
   my $tfile='install-test/lib/perl/Big/Dummy.pm';
   local $ExtUtils::Install::Testing = $tfile;
@@ -1,15 +1,8 @@
 #!/usr/bin/perl -w
 
 BEGIN {
-    if( $ENV{PERL_CORE} ) {
-        chdir 't' if -d 't';
-        @INC = '../lib';
-    }
-    else {
-        unshift @INC, 't/lib/';
-    }
+    unshift @INC, 't/lib/';
 }
-chdir 't';
 
 my $Is_VMS = $^O eq 'VMS';
 
@@ -21,7 +14,7 @@ use File::Path;
 use File::Basename;
 use File::Spec;
 
-use Test::More tests => 63;
+use Test::More tests => 73;
 
 BEGIN { use_ok( 'ExtUtils::Installed' ) }
 
@@ -114,8 +107,7 @@ my $fake_mod_dir = File::Spec->catdir(cwd(), 'auto', 'FakeMod');
         sitearchexp        => $fake_mod_dir,
     );
 
-    # necessary to fool new()
-    push @INC, $fake_mod_dir;
+    # should find $fake_mod_dir via '.' in @INC
 
     my $realei = ExtUtils::Installed->new();
     isa_ok( $realei, 'ExtUtils::Installed' );
@@ -129,6 +121,50 @@ my $fake_mod_dir = File::Spec->catdir(cwd(), 'auto', 'FakeMod');
 	'... should find version in modules' );
 }
 
+{
+    # avoid warning and death by localizing glob
+    local *ExtUtils::Installed::Config;
+    %ExtUtils::Installed::Config = (
+        %Config,
+        archlibexp         => cwd(),
+        sitearchexp        => $fake_mod_dir,
+    );
+
+    # disable '.' search
+
+    my $realei = ExtUtils::Installed->new( skip_cwd => 1 );
+    isa_ok( $realei, 'ExtUtils::Installed' );
+    isa_ok( $realei->{Perl}{packlist}, 'ExtUtils::Packlist' );
+    is( $realei->{Perl}{version}, $Config{version},
+        'new() should set Perl version from %Config' );
+
+    ok( ! exists $realei->{FakeMod}, 'new( skip_cwd => 1 ) should fail to find modules with .packlists');
+}
+
+{
+    # avoid warning and death by localizing glob
+    local *ExtUtils::Installed::Config;
+    %ExtUtils::Installed::Config = (
+        %Config,
+        archlibexp         => cwd(),
+        sitearchexp        => $fake_mod_dir,
+    );
+
+    # necessary to fool new() since we'll disable searching '.'
+    push @INC, $fake_mod_dir;
+
+    my $realei = ExtUtils::Installed->new( skip_cwd => 1 );
+    isa_ok( $realei, 'ExtUtils::Installed' );
+    isa_ok( $realei->{Perl}{packlist}, 'ExtUtils::Packlist' );
+    is( $realei->{Perl}{version}, $Config{version},
+        'new() should set Perl version from %Config' );
+
+    ok( exists $realei->{FakeMod}, 'new() should find modules with .packlists');
+    isa_ok( $realei->{FakeMod}{packlist}, 'ExtUtils::Packlist' );
+    is( $realei->{FakeMod}{version}, '1.1.1',
+	'... should find version in modules' );
+}
+
 # Now try this using PERL5LIB
 {
     local $ENV{PERL5LIB} = join $Config{path_sep}, $fake_mod_dir;
@@ -1,19 +1,12 @@
 #!/usr/bin/perl -w
 
 BEGIN {
-    if( $ENV{PERL_CORE} ) {
-        chdir 't' if -d 't';
-        @INC = '../lib';
-    }
-    else {
-        unshift @INC, 't/lib';
-    }
+    unshift @INC, 't/lib';
 }
-chdir 't';
 
-use Test::More tests => 34;
+use Test::More tests => 35;
 
-use_ok( 'ExtUtils::Packlist' );
+BEGIN { use_ok( 'ExtUtils::Packlist' ); }
 
 is( ref(ExtUtils::Packlist::mkfh()), 'GLOB', 'mkfh() should return a FH' );
 
@@ -169,6 +162,18 @@ is( ExtUtils::Packlist::packlist_file({ packfile => 'pl' }), 'pl',
 is( ExtUtils::Packlist::packlist_file($pl), 'eplist',
 	'packlist_file() should fetch packlist from ExtUtils::Packlist object' );
 
+BEGIN {
+	# Call mkfh at BEGIN time, to make sure it does not trigger "Used
+	# once" warnings.
+	$SIG{__WARN__} = sub { ++$w; warn $_[0] };
+	ExtUtils::Packlist::mkfh();
+	
+}
+INIT {
+	is $w, undef, '[perl #107410] no warnings from BEGIN-time mkfh';
+	delete $SIG{__WARN__};
+}
+
 END {
 	1 while unlink qw( eplist );
 }
@@ -9,13 +9,11 @@ use File::Path;
 use File::Basename;
 use MakeMaker::Test::Utils;
 
-my $Is_VMS = $^O eq 'VMS';
-
 my %Files = (
              'Big-Dummy/lib/Big/Dummy.pm'     => <<'END',
 package Big::Dummy;
 
-$VERSION = 0.01;
+$VERSION = 0.02;
 
 =head1 NAME
 
@@ -96,8 +94,6 @@ END
 
 
 sub setup_recurs {
-    setup_mm_test_root();
-    chdir 'MM_TEST_ROOT:[t]' if $Is_VMS;
 
     while(my($file, $text) = each %Files) {
         # Convert to a relative, native file path.
@@ -12,7 +12,6 @@ our $Is_MacOS = $^O eq 'MacOS';
 
 our @EXPORT = qw(which_perl perl_lib makefile_name makefile_backup
                  make make_run run make_macro calibrate_mtime
-                 setup_mm_test_root
                  have_compiler slurp
                  $Is_VMS $Is_MacOS
                  run_ok
@@ -135,21 +134,30 @@ sub which_perl {
   perl_lib;
 
 Sets up environment variables so perl can find its libraries.
+Run this before changing directories.
 
 =cut
 
 my $old5lib = $ENV{PERL5LIB};
 my $had5lib = exists $ENV{PERL5LIB};
 sub perl_lib {
-                               # perl-src/t/
-    my $lib =  $ENV{PERL_CORE} ? qq{../lib}
-                               # ExtUtils-MakeMaker/t/
-                               : qq{../blib/lib};
-    $lib = File::Spec->rel2abs($lib);
-    my @libs = ($lib);
-    push @libs, $ENV{PERL5LIB} if exists $ENV{PERL5LIB};
-    $ENV{PERL5LIB} = join($Config{path_sep}, @libs);
-    unshift @INC, $lib;
+    if ($ENV{PERL_CORE}) {
+	# Whilst we'll be running in perl-src/cpan/$distname/t/
+	# instead of blib, our code will be copied with all the other code to
+	# the top-level library.
+	# $ENV{PERL5LIB} will be set with this, but (by default) it's a relative
+	# path.
+	$ENV{PERL5LIB} = join $Config{path_sep}, map {
+	    File::Spec->rel2abs($_) } split quotemeta($Config{path_sep}), $ENV{PERL5LIB};
+	@INC = map { File::Spec->rel2abs($_) } @INC;
+    } else {
+	my $lib = 'blib/lib';
+	$lib = File::Spec->rel2abs($lib);
+	my @libs = ($lib);
+	push @libs, $ENV{PERL5LIB} if exists $ENV{PERL5LIB};
+	$ENV{PERL5LIB} = join($Config{path_sep}, @libs);
+	unshift @INC, $lib;
+    }
 }
 
 END { 
@@ -201,6 +209,7 @@ sub make {
     my $make = $Config{make};
     $make = $ENV{MAKE} if exists $ENV{MAKE};
 
+    return if !can_run($make);
     return $make;
 }
 
@@ -214,6 +223,7 @@ Returns the make to run as with make() plus any necessary switches.
 
 sub make_run {
     my $make = make;
+    return if !$make;
     $make .= ' -nologo' if $make eq 'nmake';
 
     return $make;
@@ -324,32 +334,6 @@ sub run_ok {
     return wantarray ? @out : join "", @out;
 }
 
-=item B<setup_mm_test_root>
-
-Creates a rooted logical to avoid the 8-level limit on older VMS systems.  
-No action taken on non-VMS systems.
-
-=cut
-
-sub setup_mm_test_root {
-    if( $Is_VMS ) {
-        # On older systems we might exceed the 8-level directory depth limit
-        # imposed by RMS.  We get around this with a rooted logical, but we
-        # can't create logical names with attributes in Perl, so we do it
-        # in a DCL subprocess and put it in the job table so the parent sees it.
-        open( MMTMP, '>mmtesttmp.com' ) || 
-          die "Error creating command file; $!";
-        print MMTMP <<'COMMAND';
-$ MM_TEST_ROOT = F$PARSE("SYS$DISK:[-]",,,,"NO_CONCEAL")-".][000000"-"]["-"].;"+".]"
-$ DEFINE/JOB/NOLOG/TRANSLATION=CONCEALED MM_TEST_ROOT 'MM_TEST_ROOT'
-COMMAND
-        close MMTMP;
-
-        system '@mmtesttmp.com';
-        1 while unlink 'mmtesttmp.com';
-    }
-}
-
 =item have_compiler
 
   $have_compiler = have_compiler;
@@ -401,6 +385,58 @@ sub slurp {
     return $text;
 }
 
+=item can_run
+
+C<can_run> takes only one argument: the name of a binary you wish
+to locate. C<can_run> works much like the unix binary C<which> or the bash
+command C<type>, which scans through your path, looking for the requested
+binary.
+
+Unlike C<which> and C<type>, this function is platform independent and
+will also work on, for example, Win32.
+
+If called in a scalar context it will return the full path to the binary
+you asked for if it was found, or C<undef> if it was not.
+
+If called in a list context and the global variable C<$INSTANCES> is a true
+value, it will return a list of the full paths to instances
+of the binary where found in C<PATH>, or an empty list if it was not found.
+
+=cut
+
+sub can_run {
+    my $command = shift;
+
+    # a lot of VMS executables have a symbol defined
+    # check those first
+    if ( $^O eq 'VMS' ) {
+        require VMS::DCLsym;
+        my $syms = VMS::DCLsym->new;
+        return $command if scalar $syms->getsym( uc $command );
+    }
+
+    require File::Spec;
+    require ExtUtils::MakeMaker;
+
+    my @possibles;
+
+    if( File::Spec->file_name_is_absolute($command) ) {
+        return MM->maybe_command($command);
+
+    } else {
+        for my $dir (
+            File::Spec->path,
+            File::Spec->curdir
+        ) {
+            next if ! $dir || ! -d $dir;
+            my $abs = File::Spec->catfile( $^O eq 'MSWin32' ? Win32::GetShortPathName( $dir ) : $dir, $command);
+            push @possibles, $abs if $abs = MM->maybe_command($abs);
+        }
+    }
+    return @possibles if wantarray;
+    return shift @possibles;
+}
+
 =back
 
 =head1 AUTHOR