1package ExtUtils::Install; 2use strict; 3 4use Config qw(%Config); 5use Cwd qw(cwd); 6use Exporter (); 7use File::Basename qw(dirname); 8use File::Copy; 9use File::Path; 10use File::Spec; 11 12our @ISA = ('Exporter'); 13our @EXPORT = ('install','uninstall','pm_to_blib', 'install_default'); 14 15our $MUST_REBOOT; 16 17=pod 18 19=head1 NAME 20 21ExtUtils::Install - install files from here to there 22 23=head1 SYNOPSIS 24 25 use ExtUtils::Install; 26 27 install({ 'blib/lib' => 'some/install/dir' } ); 28 29 uninstall($packlist); 30 31 pm_to_blib({ 'lib/Foo/Bar.pm' => 'blib/lib/Foo/Bar.pm' }); 32 33=head1 VERSION 34 352.22 36 37=cut 38 39our $VERSION = '2.22'; # <-- do not forget to update the POD section just above this line! 40$VERSION = eval $VERSION; 41 42=pod 43 44=head1 DESCRIPTION 45 46Handles the installing and uninstalling of perl modules, scripts, man 47pages, etc... 48 49Both install() and uninstall() are specific to the way 50ExtUtils::MakeMaker handles the installation and deinstallation of 51perl modules. They are not designed as general purpose tools. 52 53On some operating systems such as Win32 installation may not be possible 54until after a reboot has occurred. This can have varying consequences: 55removing an old DLL does not impact programs using the new one, but if 56a new DLL cannot be installed properly until reboot then anything 57depending on it must wait. The package variable 58 59 $ExtUtils::Install::MUST_REBOOT 60 61is used to store this status. 62 63If this variable is true then such an operation has occurred and 64anything depending on this module cannot proceed until a reboot 65has occurred. 66 67If this value is defined but false then such an operation has 68occurred, but should not impact later operations. 69 70=begin _private 71 72=head2 _chmod($$;$) 73 74Wrapper to chmod() for debugging and error trapping. 75 76=head2 _warnonce(@) 77 78Warns about something only once. 79 80=head2 _choke(@) 81 82Dies with a special message. 83 84=end _private 85 86=cut 87 88BEGIN { 89 *_Is_VMS = $^O eq 'VMS' ? sub(){1} : sub(){0}; 90 *_Is_Win32 = $^O eq 'MSWin32' ? sub(){1} : sub(){0}; 91 *_Is_cygwin = $^O eq 'cygwin' ? sub(){1} : sub(){0}; 92 *_CanMoveAtBoot = ($^O eq 'MSWin32' || $^O eq 'cygwin') ? sub(){1} : sub(){0}; 93} 94 95my $Inc_uninstall_warn_handler; 96 97# install relative to here 98 99my $INSTALL_ROOT = $ENV{PERL_INSTALL_ROOT}; 100my $INSTALL_QUIET = $ENV{PERL_INSTALL_QUIET}; 101$INSTALL_QUIET = 1 102 if (!exists $ENV{PERL_INSTALL_QUIET} and 103 defined $ENV{MAKEFLAGS} and 104 $ENV{MAKEFLAGS} =~ /\b(s|silent|quiet)\b/); 105 106my $Curdir = File::Spec->curdir; 107my $Perm_Dir = $ENV{PERL_CORE} ? 0770 : 0755; 108 109sub _estr(@) { 110 return join "\n",'!' x 72,@_,'!' x 72,''; 111} 112 113{my %warned; 114sub _warnonce(@) { 115 my $first=shift; 116 my $msg=_estr "WARNING: $first",@_; 117 warn $msg unless $warned{$msg}++; 118}} 119 120sub _choke(@) { 121 my $first=shift; 122 my $msg=_estr "ERROR: $first",@_; 123 require Carp; 124 Carp::croak($msg); 125} 126 127sub _croak { 128 require Carp; 129 Carp::croak(@_); 130} 131sub _confess { 132 require Carp; 133 Carp::confess(@_); 134} 135 136sub _compare { 137 # avoid loading File::Compare in the common case 138 if (-f $_[1] && -s _ == -s $_[0]) { 139 require File::Compare; 140 return File::Compare::compare(@_); 141 } 142 return 1; 143} 144 145 146sub _chmod($$;$) { 147 my ( $mode, $item, $verbose )=@_; 148 $verbose ||= 0; 149 if (chmod $mode, $item) { 150 printf "chmod(0%o, %s)\n",$mode, $item if $verbose > 1; 151 } else { 152 my $err="$!"; 153 _warnonce sprintf "WARNING: Failed chmod(0%o, %s): %s\n", 154 $mode, $item, $err 155 if -e $item; 156 } 157} 158 159=begin _private 160 161=head2 _move_file_at_boot( $file, $target, $moan ) 162 163OS-Specific, Win32/Cygwin 164 165Schedules a file to be moved/renamed/deleted at next boot. 166$file should be a filespec of an existing file 167$target should be a ref to an array if the file is to be deleted 168otherwise it should be a filespec for a rename. If the file is existing 169it will be replaced. 170 171Sets $MUST_REBOOT to 0 to indicate a deletion operation has occurred 172and sets it to 1 to indicate that a move operation has been requested. 173 174returns 1 on success, on failure if $moan is false errors are fatal. 175If $moan is true then returns 0 on error and warns instead of dies. 176 177=end _private 178 179=cut 180 181{ 182 my $Has_Win32API_File; 183 sub _move_file_at_boot { #XXX OS-SPECIFIC 184 my ( $file, $target, $moan )= @_; 185 _confess("Panic: Can't _move_file_at_boot on this platform!") 186 unless _CanMoveAtBoot; 187 188 my $descr= ref $target 189 ? "'$file' for deletion" 190 : "'$file' for installation as '$target'"; 191 192 # *note* _CanMoveAtBoot is only incidentally the same condition as below 193 # this needs not hold true in the future. 194 $Has_Win32API_File = (_Is_Win32 || _Is_cygwin) 195 ? (eval {require Win32API::File; 1} || 0) 196 : 0 unless defined $Has_Win32API_File; 197 if ( ! $Has_Win32API_File ) { 198 199 my @msg=( 200 "Cannot schedule $descr at reboot.", 201 "Try installing Win32API::File to allow operations on locked files", 202 "to be scheduled during reboot. Or try to perform the operation by", 203 "hand yourself. (You may need to close other perl processes first)" 204 ); 205 if ( $moan ) { _warnonce(@msg) } else { _choke(@msg) } 206 return 0; 207 } 208 my $opts= Win32API::File::MOVEFILE_DELAY_UNTIL_REBOOT(); 209 $opts= $opts | Win32API::File::MOVEFILE_REPLACE_EXISTING() 210 unless ref $target; 211 212 _chmod( 0666, $file ); 213 _chmod( 0666, $target ) unless ref $target; 214 215 if (Win32API::File::MoveFileEx( $file, $target, $opts )) { 216 $MUST_REBOOT ||= ref $target ? 0 : 1; 217 return 1; 218 } else { 219 my @msg=( 220 "MoveFileEx $descr at reboot failed: $^E", 221 "You may try to perform the operation by hand yourself. ", 222 "(You may need to close other perl processes first).", 223 ); 224 if ( $moan ) { _warnonce(@msg) } else { _choke(@msg) } 225 } 226 return 0; 227 } 228} 229 230 231=begin _private 232 233=head2 _unlink_or_rename( $file, $tryhard, $installing ) 234 235OS-Specific, Win32/Cygwin 236 237Tries to get a file out of the way by unlinking it or renaming it. On 238some OS'es (Win32 based) DLL files can end up locked such that they can 239be renamed but not deleted. Likewise sometimes a file can be locked such 240that it cant even be renamed or changed except at reboot. To handle 241these cases this routine finds a tempfile name that it can either rename 242the file out of the way or use as a proxy for the install so that the 243rename can happen later (at reboot). 244 245 $file : the file to remove. 246 $tryhard : should advanced tricks be used for deletion 247 $installing : we are not merely deleting but we want to overwrite 248 249When $tryhard is not true if the unlink fails its fatal. When $tryhard 250is true then the file is attempted to be renamed. The renamed file is 251then scheduled for deletion. If the rename fails then $installing 252governs what happens. If it is false the failure is fatal. If it is true 253then an attempt is made to schedule installation at boot using a 254temporary file to hold the new file. If this fails then a fatal error is 255thrown, if it succeeds it returns the temporary file name (which will be 256a derivative of the original in the same directory) so that the caller can 257use it to install under. In all other cases of success returns $file. 258On failure throws a fatal error. 259 260=end _private 261 262=cut 263 264sub _unlink_or_rename { #XXX OS-SPECIFIC 265 my ( $file, $tryhard, $installing )= @_; 266 267 # this chmod was originally unconditional. However, its not needed on 268 # POSIXy systems since permission to unlink a file is specified by the 269 # directory rather than the file; and in fact it screwed up hard- and 270 # symlinked files. Keep it for other platforms in case its still 271 # needed there. 272 if ($^O =~ /^(dos|os2|MSWin32|VMS)$/) { 273 _chmod( 0666, $file ); 274 } 275 my $unlink_count = 0; 276 while (unlink $file) { $unlink_count++; } 277 return $file if $unlink_count > 0; 278 my $error="$!"; 279 280 _choke("Cannot unlink '$file': $!") 281 unless _CanMoveAtBoot && $tryhard; 282 283 my $tmp= "AAA"; 284 ++$tmp while -e "$file.$tmp"; 285 $tmp= "$file.$tmp"; 286 287 warn "WARNING: Unable to unlink '$file': $error\n", 288 "Going to try to rename it to '$tmp'.\n"; 289 290 if ( rename $file, $tmp ) { 291 warn "Rename successful. Scheduling '$tmp'\nfor deletion at reboot.\n"; 292 # when $installing we can set $moan to true. 293 # IOW, if we cant delete the renamed file at reboot its 294 # not the end of the world. The other cases are more serious 295 # and need to be fatal. 296 _move_file_at_boot( $tmp, [], $installing ); 297 return $file; 298 } elsif ( $installing ) { 299 _warnonce("Rename failed: $!. Scheduling '$tmp'\nfor". 300 " installation as '$file' at reboot.\n"); 301 _move_file_at_boot( $tmp, $file ); 302 return $tmp; 303 } else { 304 _choke("Rename failed:$!", "Cannot proceed."); 305 } 306 307} 308 309=head1 Functions 310 311=begin _private 312 313=head2 _get_install_skip 314 315Handles loading the INSTALL.SKIP file. Returns an array of patterns to use. 316 317=cut 318 319sub _get_install_skip { 320 my ( $skip, $verbose )= @_; 321 if ($ENV{EU_INSTALL_IGNORE_SKIP}) { 322 print "EU_INSTALL_IGNORE_SKIP is set, ignore skipfile settings\n" 323 if $verbose>2; 324 return []; 325 } 326 if ( ! defined $skip ) { 327 print "Looking for install skip list\n" 328 if $verbose>2; 329 for my $file ( 'INSTALL.SKIP', $ENV{EU_INSTALL_SITE_SKIPFILE} ) { 330 next unless $file; 331 print "\tChecking for $file\n" 332 if $verbose>2; 333 if (-e $file) { 334 $skip= $file; 335 last; 336 } 337 } 338 } 339 if ($skip && !ref $skip) { 340 print "Reading skip patterns from '$skip'.\n" 341 if $verbose; 342 if (open my $fh,$skip ) { 343 my @patterns; 344 while (<$fh>) { 345 chomp; 346 next if /^\s*(?:#|$)/; 347 print "\tSkip pattern: $_\n" if $verbose>3; 348 push @patterns, $_; 349 } 350 $skip= \@patterns; 351 } else { 352 warn "Can't read skip file:'$skip':$!\n"; 353 $skip=[]; 354 } 355 } elsif ( UNIVERSAL::isa($skip,'ARRAY') ) { 356 print "Using array for skip list\n" 357 if $verbose>2; 358 } elsif ($verbose) { 359 print "No skip list found.\n" 360 if $verbose>1; 361 $skip= []; 362 } 363 warn "Got @{[0+@$skip]} skip patterns.\n" 364 if $verbose>3; 365 return $skip 366} 367 368=head2 _have_write_access 369 370Abstract a -w check that tries to use POSIX::access() if possible. 371 372=cut 373 374{ 375 my $has_posix; 376 sub _have_write_access { 377 my $dir=shift; 378 unless (defined $has_posix) { 379 $has_posix = (!_Is_cygwin && !_Is_Win32 380 && eval { local $^W; require POSIX; 1} ) || 0; 381 } 382 if ($has_posix) { 383 return POSIX::access($dir, POSIX::W_OK()); 384 } else { 385 return -w $dir; 386 } 387 } 388} 389 390=head2 _can_write_dir(C<$dir>) 391 392Checks whether a given directory is writable, taking account 393the possibility that the directory might not exist and would have to 394be created first. 395 396Returns a list, containing: C<($writable, $determined_by, @create)> 397 398C<$writable> says whether the directory is (hypothetically) writable 399 400C<$determined_by> is the directory the status was determined from. It will be 401either the C<$dir>, or one of its parents. 402 403C<@create> is a list of directories that would probably have to be created 404to make the requested directory. It may not actually be correct on 405relative paths with C<..> in them. But for our purposes it should work ok 406 407=cut 408 409sub _can_write_dir { 410 my $dir=shift; 411 return 412 unless defined $dir and length $dir; 413 414 my ($vol, $dirs, $file) = File::Spec->splitpath($dir,1); 415 my @dirs = File::Spec->splitdir($dirs); 416 unshift @dirs, File::Spec->curdir 417 unless File::Spec->file_name_is_absolute($dir); 418 419 my $path=''; 420 my @make; 421 while (@dirs) { 422 if (_Is_VMS) { 423 $dir = File::Spec->catdir($vol,@dirs); 424 } 425 else { 426 $dir = File::Spec->catdir(@dirs); 427 $dir = File::Spec->catpath($vol,$dir,'') 428 if defined $vol and length $vol; 429 } 430 next if ( $dir eq $path ); 431 if ( ! -e $dir ) { 432 unshift @make,$dir; 433 next; 434 } 435 if ( _have_write_access($dir) ) { 436 return 1,$dir,@make 437 } else { 438 return 0,$dir,@make 439 } 440 } continue { 441 pop @dirs; 442 } 443 return 0; 444} 445 446=head2 _mkpath($dir,$show,$mode,$verbose,$dry_run) 447 448Wrapper around File::Path::mkpath() to handle errors. 449 450If $verbose is true and >1 then additional diagnostics will be produced, also 451this will force $show to true. 452 453If $dry_run is true then the directory will not be created but a check will be 454made to see whether it would be possible to write to the directory, or that 455it would be possible to create the directory. 456 457If $dry_run is not true dies if the directory can not be created or is not 458writable. 459 460=cut 461 462sub _mkpath { 463 my ($dir,$show,$mode,$verbose,$dry_run)=@_; 464 if ( $verbose && $verbose > 1 && ! -d $dir) { 465 $show= 1; 466 printf "mkpath(%s,%d,%#o)\n", $dir, $show, $mode; 467 } 468 if (!$dry_run) { 469 my @created; 470 eval { 471 @created = File::Path::mkpath($dir,$show,$mode); 472 1; 473 } or _choke("Can't create '$dir'","$@"); 474 # if we created any directories, we were able to write and don't need 475 # extra checks 476 if (@created) { 477 return; 478 } 479 } 480 my ($can,$root,@make)=_can_write_dir($dir); 481 if (!$can) { 482 my @msg=( 483 "Can't create '$dir'", 484 $root ? "Do not have write permissions on '$root'" 485 : "Unknown Error" 486 ); 487 if ($dry_run) { 488 _warnonce @msg; 489 } else { 490 _choke @msg; 491 } 492 } elsif ($show and $dry_run) { 493 print "$_\n" for @make; 494 } 495 496} 497 498=head2 _copy($from,$to,$verbose,$dry_run) 499 500Wrapper around File::Copy::copy to handle errors. 501 502If $verbose is true and >1 then additional diagnostics will be emitted. 503 504If $dry_run is true then the copy will not actually occur. 505 506Dies if the copy fails. 507 508=cut 509 510sub _copy { 511 my ( $from, $to, $verbose, $dry_run)=@_; 512 if ($verbose && $verbose>1) { 513 printf "copy(%s,%s)\n", $from, $to; 514 } 515 if (!$dry_run) { 516 File::Copy::copy($from,$to) 517 or _croak( _estr "ERROR: Cannot copy '$from' to '$to': $!" ); 518 } 519} 520 521=pod 522 523=head2 _chdir($from) 524 525Wrapper around chdir to catch errors. 526 527If not called in void context returns the cwd from before the chdir. 528 529dies on error. 530 531=cut 532 533sub _chdir { 534 my ($dir)= @_; 535 my $ret; 536 if (defined wantarray) { 537 $ret= cwd; 538 } 539 chdir $dir 540 or _choke("Couldn't chdir to '$dir': $!"); 541 return $ret; 542} 543 544=end _private 545 546=head2 install 547 548 # deprecated forms 549 install(\%from_to); 550 install(\%from_to, $verbose, $dry_run, $uninstall_shadows, 551 $skip, $always_copy, \%result); 552 553 # recommended form as of 1.47 554 install([ 555 from_to => \%from_to, 556 verbose => 1, 557 dry_run => 0, 558 uninstall_shadows => 1, 559 skip => undef, 560 always_copy => 1, 561 result => \%install_results, 562 ]); 563 564 565Copies each directory tree of %from_to to its corresponding value 566preserving timestamps and permissions. 567 568There are two keys with a special meaning in the hash: "read" and 569"write". These contain packlist files. After the copying is done, 570install() will write the list of target files to $from_to{write}. If 571$from_to{read} is given the contents of this file will be merged into 572the written file. The read and the written file may be identical, but 573on AFS it is quite likely that people are installing to a different 574directory than the one where the files later appear. 575 576If $verbose is true, will print out each file removed. Default is 577false. This is "make install VERBINST=1". $verbose values going 578up to 5 show increasingly more diagnostics output. 579 580If $dry_run is true it will only print what it was going to do 581without actually doing it. Default is false. 582 583If $uninstall_shadows is true any differing versions throughout @INC 584will be uninstalled. This is "make install UNINST=1" 585 586As of 1.37_02 install() supports the use of a list of patterns to filter out 587files that shouldn't be installed. If $skip is omitted or undefined then 588install will try to read the list from INSTALL.SKIP in the CWD. This file is 589a list of regular expressions and is just like the MANIFEST.SKIP file used 590by L<ExtUtils::Manifest>. 591 592A default site INSTALL.SKIP may be provided by setting then environment 593variable EU_INSTALL_SITE_SKIPFILE, this will only be used when there isn't a 594distribution specific INSTALL.SKIP. If the environment variable 595EU_INSTALL_IGNORE_SKIP is true then no install file filtering will be 596performed. 597 598If $skip is undefined then the skip file will be autodetected and used if it 599is found. If $skip is a reference to an array then it is assumed the array 600contains the list of patterns, if $skip is a true non reference it is 601assumed to be the filename holding the list of patterns, any other value of 602$skip is taken to mean that no install filtering should occur. 603 604B<Changes As of Version 1.47> 605 606As of version 1.47 the following additions were made to the install interface. 607Note that the new argument style and use of the %result hash is recommended. 608 609The $always_copy parameter which when true causes files to be updated 610regardless as to whether they have changed, if it is defined but false then 611copies are made only if the files have changed, if it is undefined then the 612value of the environment variable EU_INSTALL_ALWAYS_COPY is used as default. 613 614The %result hash will be populated with the various keys/subhashes reflecting 615the install. Currently these keys and their structure are: 616 617 install => { $target => $source }, 618 install_fail => { $target => $source }, 619 install_unchanged => { $target => $source }, 620 621 install_filtered => { $source => $pattern }, 622 623 uninstall => { $uninstalled => $source }, 624 uninstall_fail => { $uninstalled => $source }, 625 626where C<$source> is the filespec of the file being installed. C<$target> is where 627it is being installed to, and C<$uninstalled> is any shadow file that is in C<@INC> 628or C<$ENV{PERL5LIB}> or other standard locations, and C<$pattern> is the pattern that 629caused a source file to be skipped. In future more keys will be added, such as to 630show created directories, however this requires changes in other modules and must 631therefore wait. 632 633These keys will be populated before any exceptions are thrown should there be an 634error. 635 636Note that all updates of the %result are additive, the hash will not be 637cleared before use, thus allowing status results of many installs to be easily 638aggregated. 639 640B<NEW ARGUMENT STYLE> 641 642If there is only one argument and it is a reference to an array then 643the array is assumed to contain a list of key-value pairs specifying 644the options. In this case the option "from_to" is mandatory. This style 645means that you do not have to supply a cryptic list of arguments and can 646use a self documenting argument list that is easier to understand. 647 648This is now the recommended interface to install(). 649 650B<RETURN> 651 652If all actions were successful install will return a hashref of the results 653as described above for the $result parameter. If any action is a failure 654then install will die, therefore it is recommended to pass in the $result 655parameter instead of using the return value. If the result parameter is 656provided then the returned hashref will be the passed in hashref. 657 658=cut 659 660sub install { #XXX OS-SPECIFIC 661 my($from_to,$verbose,$dry_run,$uninstall_shadows,$skip,$always_copy,$result) = @_; 662 if (@_==1 and eval { 1+@$from_to }) { 663 my %opts = @$from_to; 664 $from_to = $opts{from_to} 665 or _confess("from_to is a mandatory parameter"); 666 $verbose = $opts{verbose}; 667 $dry_run = $opts{dry_run}; 668 $uninstall_shadows = $opts{uninstall_shadows}; 669 $skip = $opts{skip}; 670 $always_copy = $opts{always_copy}; 671 $result = $opts{result}; 672 } 673 674 $result ||= {}; 675 $verbose ||= 0; 676 $dry_run ||= 0; 677 678 $skip= _get_install_skip($skip,$verbose); 679 $always_copy = $ENV{EU_INSTALL_ALWAYS_COPY} 680 || $ENV{EU_ALWAYS_COPY} 681 || 0 682 unless defined $always_copy; 683 684 my(%from_to) = %$from_to; 685 my(%pack, $dir, %warned); 686 require ExtUtils::Packlist; 687 my($packlist) = ExtUtils::Packlist->new(); 688 689 local(*DIR); 690 for (qw/read write/) { 691 $pack{$_}=$from_to{$_}; 692 delete $from_to{$_}; 693 } 694 my $tmpfile = install_rooted_file($pack{"read"}); 695 $packlist->read($tmpfile) if (-f $tmpfile); 696 my $cwd = cwd(); 697 my @found_files; 698 my %check_dirs; 699 require File::Find; 700 701 my $blib_lib = File::Spec->catdir('blib', 'lib'); 702 my $blib_arch = File::Spec->catdir('blib', 'arch'); 703 704 # File::Find seems to always be Unixy except on MacPerl :( 705 my $current_directory = $^O eq 'MacOS' ? $Curdir : '.'; 706 707 MOD_INSTALL: foreach my $source (sort keys %from_to) { 708 #copy the tree to the target directory without altering 709 #timestamp and permission and remember for the .packlist 710 #file. The packlist file contains the absolute paths of the 711 #install locations. AFS users may call this a bug. We'll have 712 #to reconsider how to add the means to satisfy AFS users also. 713 714 #October 1997: we want to install .pm files into archlib if 715 #there are any files in arch. So we depend on having ./blib/arch 716 #hardcoded here. 717 718 my $targetroot = install_rooted_dir($from_to{$source}); 719 720 if ($source eq $blib_lib and 721 exists $from_to{$blib_arch} and 722 directory_not_empty($blib_arch) 723 ){ 724 $targetroot = install_rooted_dir($from_to{$blib_arch}); 725 print "Files found in $blib_arch: installing files in $blib_lib into architecture dependent library tree\n"; 726 } 727 728 next unless -d $source; 729 _chdir($source); 730 # 5.5.3's File::Find missing no_chdir option 731 # XXX OS-SPECIFIC 732 File::Find::find(sub { 733 my ($mode,$size,$atime,$mtime) = (stat)[2,7,8,9]; 734 735 return if !-f _; 736 my $origfile = $_; 737 738 return if $origfile eq ".exists"; 739 my $targetdir = File::Spec->catdir($targetroot, $File::Find::dir); 740 my $targetfile = File::Spec->catfile($targetdir, $origfile); 741 my $sourcedir = File::Spec->catdir($source, $File::Find::dir); 742 my $sourcefile = File::Spec->catfile($sourcedir, $origfile); 743 744 for my $pat (@$skip) { 745 if ( $sourcefile=~/$pat/ ) { 746 print "Skipping $targetfile (filtered)\n" 747 if $verbose>1; 748 $result->{install_filtered}{$sourcefile} = $pat; 749 return; 750 } 751 } 752 # we have to do this for back compat with old File::Finds 753 # and because the target is relative 754 my $save_cwd = File::Spec->catfile($cwd, $sourcedir); 755 _chdir($cwd); 756 my $diff = $always_copy || _compare($sourcefile, $targetfile); 757 $check_dirs{$targetdir}++ 758 unless -w $targetfile; 759 760 push @found_files, 761 [ $diff, $File::Find::dir, $origfile, 762 $mode, $size, $atime, $mtime, 763 $targetdir, $targetfile, $sourcedir, $sourcefile, 764 765 ]; 766 #restore the original directory we were in when File::Find 767 #called us so that it doesn't get horribly confused. 768 _chdir($save_cwd); 769 }, $current_directory ); 770 _chdir($cwd); 771 } 772 foreach my $targetdir (sort keys %check_dirs) { 773 _mkpath( $targetdir, 0, $Perm_Dir, $verbose, $dry_run ); 774 } 775 foreach my $found (@found_files) { 776 my ($diff, $ffd, $origfile, $mode, $size, $atime, $mtime, 777 $targetdir, $targetfile, $sourcedir, $sourcefile)= @$found; 778 779 my $realtarget= $targetfile; 780 if ($diff) { 781 eval { 782 if (-f $targetfile) { 783 print "_unlink_or_rename($targetfile)\n" if $verbose>1; 784 $targetfile= _unlink_or_rename( $targetfile, 'tryhard', 'install' ) 785 unless $dry_run; 786 } elsif ( ! -d $targetdir ) { 787 _mkpath( $targetdir, 0, $Perm_Dir, $verbose, $dry_run ); 788 } 789 print "Installing $targetfile\n"; 790 791 _copy( $sourcefile, $targetfile, $verbose, $dry_run, ); 792 793 794 #XXX OS-SPECIFIC 795 print "utime($atime,$mtime,$targetfile)\n" if $verbose>1; 796 utime($atime,$mtime + _Is_VMS,$targetfile) unless $dry_run>1; 797 798 799 $mode = 0444 | ( $mode & 0111 ? 0111 : 0 ); 800 $mode = $mode | 0222 801 if $realtarget ne $targetfile; 802 _chmod( $mode, $targetfile, $verbose ); 803 $result->{install}{$targetfile} = $sourcefile; 804 1 805 } or do { 806 $result->{install_fail}{$targetfile} = $sourcefile; 807 die $@; 808 }; 809 } else { 810 $result->{install_unchanged}{$targetfile} = $sourcefile; 811 print "Skipping $targetfile (unchanged)\n" if $verbose; 812 } 813 814 if ( $uninstall_shadows ) { 815 inc_uninstall($sourcefile,$ffd, $verbose, 816 $dry_run, 817 $realtarget ne $targetfile ? $realtarget : "", 818 $result); 819 } 820 821 # Record the full pathname. 822 $packlist->{$targetfile}++; 823 } 824 825 if ($pack{'write'}) { 826 $dir = install_rooted_dir(dirname($pack{'write'})); 827 _mkpath( $dir, 0, $Perm_Dir, $verbose, $dry_run ); 828 print "Writing $pack{'write'}\n" if $verbose; 829 $packlist->write(install_rooted_file($pack{'write'})) unless $dry_run; 830 } 831 832 _do_cleanup($verbose); 833 return $result; 834} 835 836=begin _private 837 838=head2 _do_cleanup 839 840Standardize finish event for after another instruction has occurred. 841Handles converting $MUST_REBOOT to a die for instance. 842 843=end _private 844 845=cut 846 847sub _do_cleanup { 848 my ($verbose) = @_; 849 if ($MUST_REBOOT) { 850 die _estr "Operation not completed! ", 851 "You must reboot to complete the installation.", 852 "Sorry."; 853 } elsif (defined $MUST_REBOOT & $verbose) { 854 warn _estr "Installation will be completed at the next reboot.\n", 855 "However it is not necessary to reboot immediately.\n"; 856 } 857} 858 859=begin _undocumented 860 861=head2 install_rooted_file( $file ) 862 863Returns $file, or catfile($INSTALL_ROOT,$file) if $INSTALL_ROOT 864is defined. 865 866=head2 install_rooted_dir( $dir ) 867 868Returns $dir, or catdir($INSTALL_ROOT,$dir) if $INSTALL_ROOT 869is defined. 870 871=end _undocumented 872 873=cut 874 875sub install_rooted_file { 876 if (defined $INSTALL_ROOT) { 877 File::Spec->catfile($INSTALL_ROOT, $_[0]); 878 } else { 879 $_[0]; 880 } 881} 882 883 884sub install_rooted_dir { 885 if (defined $INSTALL_ROOT) { 886 File::Spec->catdir($INSTALL_ROOT, $_[0]); 887 } else { 888 $_[0]; 889 } 890} 891 892=begin _undocumented 893 894=head2 forceunlink( $file, $tryhard ) 895 896Tries to delete a file. If $tryhard is true then we will use whatever 897devious tricks we can to delete the file. Currently this only applies to 898Win32 in that it will try to use Win32API::File to schedule a delete at 899reboot. A wrapper for _unlink_or_rename(). 900 901=end _undocumented 902 903=cut 904 905sub forceunlink { 906 my ( $file, $tryhard )= @_; #XXX OS-SPECIFIC 907 _unlink_or_rename( $file, $tryhard, not("installing") ); 908} 909 910=begin _undocumented 911 912=head2 directory_not_empty( $dir ) 913 914Returns 1 if there is an .exists file somewhere in a directory tree. 915Returns 0 if there is not. 916 917=end _undocumented 918 919=cut 920 921sub directory_not_empty ($) { 922 my($dir) = @_; 923 my $files = 0; 924 require File::Find; 925 File::Find::find(sub { 926 return if $_ eq ".exists"; 927 if (-f) { 928 $File::Find::prune++; 929 $files = 1; 930 } 931 }, $dir); 932 return $files; 933} 934 935=head2 install_default 936 937I<DISCOURAGED> 938 939 install_default(); 940 install_default($fullext); 941 942Calls install() with arguments to copy a module from blib/ to the 943default site installation location. 944 945$fullext is the name of the module converted to a directory 946(ie. Foo::Bar would be Foo/Bar). If $fullext is not specified, it 947will attempt to read it from @ARGV. 948 949This is primarily useful for install scripts. 950 951B<NOTE> This function is not really useful because of the hard-coded 952install location with no way to control site vs core vs vendor 953directories and the strange way in which the module name is given. 954Consider its use discouraged. 955 956=cut 957 958sub install_default { 959 @_ < 2 or _croak("install_default should be called with 0 or 1 argument"); 960 my $FULLEXT = @_ ? shift : $ARGV[0]; 961 defined $FULLEXT or die "Do not know to where to write install log"; 962 my $INST_LIB = File::Spec->catdir($Curdir,"blib","lib"); 963 my $INST_ARCHLIB = File::Spec->catdir($Curdir,"blib","arch"); 964 my $INST_BIN = File::Spec->catdir($Curdir,'blib','bin'); 965 my $INST_SCRIPT = File::Spec->catdir($Curdir,'blib','script'); 966 my $INST_MAN1DIR = File::Spec->catdir($Curdir,'blib','man1'); 967 my $INST_MAN3DIR = File::Spec->catdir($Curdir,'blib','man3'); 968 969 my @INST_HTML; 970 if($Config{installhtmldir}) { 971 my $INST_HTMLDIR = File::Spec->catdir($Curdir,'blib','html'); 972 @INST_HTML = ($INST_HTMLDIR => $Config{installhtmldir}); 973 } 974 975 install({ 976 read => "$Config{sitearchexp}/auto/$FULLEXT/.packlist", 977 write => "$Config{installsitearch}/auto/$FULLEXT/.packlist", 978 $INST_LIB => (directory_not_empty($INST_ARCHLIB)) ? 979 $Config{installsitearch} : 980 $Config{installsitelib}, 981 $INST_ARCHLIB => $Config{installsitearch}, 982 $INST_BIN => $Config{installbin} , 983 $INST_SCRIPT => $Config{installscript}, 984 $INST_MAN1DIR => $Config{installman1dir}, 985 $INST_MAN3DIR => $Config{installman3dir}, 986 @INST_HTML, 987 },1,0,0); 988} 989 990 991=head2 uninstall 992 993 uninstall($packlist_file); 994 uninstall($packlist_file, $verbose, $dont_execute); 995 996Removes the files listed in a $packlist_file. 997 998If $verbose is true, will print out each file removed. Default is 999false. 1000 1001If $dont_execute is true it will only print what it was going to do 1002without actually doing it. Default is false. 1003 1004=cut 1005 1006sub uninstall { 1007 my($fil,$verbose,$dry_run) = @_; 1008 $verbose ||= 0; 1009 $dry_run ||= 0; 1010 1011 die _estr "ERROR: no packlist file found: '$fil'" 1012 unless -f $fil; 1013 # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al)); 1014 # require $my_req; # Hairy, but for the first 1015 require ExtUtils::Packlist; 1016 my ($packlist) = ExtUtils::Packlist->new($fil); 1017 foreach (sort(keys(%$packlist))) { 1018 chomp; 1019 print "unlink $_\n" if $verbose; 1020 forceunlink($_,'tryhard') unless $dry_run; 1021 } 1022 print "unlink $fil\n" if $verbose; 1023 forceunlink($fil, 'tryhard') unless $dry_run; 1024 _do_cleanup($verbose); 1025} 1026 1027=begin _undocumented 1028 1029=head2 inc_uninstall($filepath,$libdir,$verbose,$dry_run,$ignore,$results) 1030 1031Remove shadowed files. If $ignore is true then it is assumed to hold 1032a filename to ignore. This is used to prevent spurious warnings from 1033occurring when doing an install at reboot. 1034 1035We now only die when failing to remove a file that has precedence over 1036our own, when our install has precedence we only warn. 1037 1038$results is assumed to contain a hashref which will have the keys 1039'uninstall' and 'uninstall_fail' populated with keys for the files 1040removed and values of the source files they would shadow. 1041 1042=end _undocumented 1043 1044=cut 1045 1046sub inc_uninstall { 1047 my($filepath,$libdir,$verbose,$dry_run,$ignore,$results) = @_; 1048 my($dir); 1049 $ignore||=""; 1050 my $file = (File::Spec->splitpath($filepath))[2]; 1051 my %seen_dir = (); 1052 1053 my @PERL_ENV_LIB = split $Config{path_sep}, defined $ENV{'PERL5LIB'} 1054 ? $ENV{'PERL5LIB'} : $ENV{'PERLLIB'} || ''; 1055 1056 my @dirs=( @PERL_ENV_LIB, 1057 @INC, 1058 @Config{qw(archlibexp 1059 privlibexp 1060 sitearchexp 1061 sitelibexp)}); 1062 1063 #warn join "\n","---",@dirs,"---"; 1064 my $seen_ours; 1065 foreach $dir ( @dirs ) { 1066 my $canonpath = _Is_VMS ? $dir : File::Spec->canonpath($dir); 1067 next if $canonpath eq $Curdir; 1068 next if $seen_dir{$canonpath}++; 1069 my $targetfile = File::Spec->catfile($canonpath,$libdir,$file); 1070 next unless -f $targetfile; 1071 1072 # The reason why we compare file's contents is, that we cannot 1073 # know, which is the file we just installed (AFS). So we leave 1074 # an identical file in place 1075 my $diff = _compare($filepath,$targetfile); 1076 1077 print "#$file and $targetfile differ\n" if $diff && $verbose > 1; 1078 1079 if (!$diff or $targetfile eq $ignore) { 1080 $seen_ours = 1; 1081 next; 1082 } 1083 if ($dry_run) { 1084 $results->{uninstall}{$targetfile} = $filepath; 1085 if ($verbose) { 1086 $Inc_uninstall_warn_handler ||= ExtUtils::Install::Warn->new(); 1087 $libdir =~ s|^\./||s ; # That's just cosmetics, no need to port. It looks prettier. 1088 $Inc_uninstall_warn_handler->add( 1089 File::Spec->catfile($libdir, $file), 1090 $targetfile 1091 ); 1092 } 1093 # if not verbose, we just say nothing 1094 } else { 1095 print "Unlinking $targetfile (shadowing?)\n" if $verbose; 1096 eval { 1097 die "Fake die for testing" 1098 if $ExtUtils::Install::Testing and 1099 ucase(File::Spec->canonpath($ExtUtils::Install::Testing)) eq ucase($targetfile); 1100 forceunlink($targetfile,'tryhard'); 1101 $results->{uninstall}{$targetfile} = $filepath; 1102 1; 1103 } or do { 1104 $results->{fail_uninstall}{$targetfile} = $filepath; 1105 if ($seen_ours) { 1106 warn "Failed to remove probably harmless shadow file '$targetfile'\n"; 1107 } else { 1108 die "$@\n"; 1109 } 1110 }; 1111 } 1112 } 1113} 1114 1115=begin _undocumented 1116 1117=head2 run_filter($cmd,$src,$dest) 1118 1119Filter $src using $cmd into $dest. 1120 1121=end _undocumented 1122 1123=cut 1124 1125sub run_filter { 1126 my ($cmd, $src, $dest) = @_; 1127 local(*CMD, *SRC); 1128 open(CMD, "|$cmd >$dest") || die "Cannot fork: $!"; 1129 open(SRC, $src) || die "Cannot open $src: $!"; 1130 my $buf; 1131 my $sz = 1024; 1132 while (my $len = sysread(SRC, $buf, $sz)) { 1133 syswrite(CMD, $buf, $len); 1134 } 1135 close SRC; 1136 close CMD or die "Filter command '$cmd' failed for $src"; 1137} 1138 1139=head2 pm_to_blib 1140 1141 pm_to_blib(\%from_to); 1142 pm_to_blib(\%from_to, $autosplit_dir); 1143 pm_to_blib(\%from_to, $autosplit_dir, $filter_cmd); 1144 1145Copies each key of %from_to to its corresponding value efficiently. 1146If an $autosplit_dir is provided, all .pm files will be autosplit into it. 1147Any destination directories are created. 1148 1149$filter_cmd is an optional shell command to run each .pm file through 1150prior to splitting and copying. Input is the contents of the module, 1151output the new module contents. 1152 1153You can have an environment variable PERL_INSTALL_ROOT set which will 1154be prepended as a directory to each installed file (and directory). 1155 1156By default verbose output is generated, setting the PERL_INSTALL_QUIET 1157environment variable will silence this output. 1158 1159=cut 1160 1161sub pm_to_blib { 1162 my($fromto,$autodir,$pm_filter) = @_; 1163 1164 my %dirs; 1165 _mkpath($autodir,0,$Perm_Dir) if defined $autodir; 1166 while(my($from, $to) = each %$fromto) { 1167 if( -f $to && -s $from == -s $to && -M $to < -M $from ) { 1168 print "Skip $to (unchanged)\n" unless $INSTALL_QUIET; 1169 next; 1170 } 1171 1172 # When a pm_filter is defined, we need to pre-process the source first 1173 # to determine whether it has changed or not. Therefore, only perform 1174 # the comparison check when there's no filter to be ran. 1175 # -- RAM, 03/01/2001 1176 1177 my $need_filtering = defined $pm_filter && length $pm_filter && 1178 $from =~ /\.pm$/; 1179 1180 if (!$need_filtering && !_compare($from,$to)) { 1181 print "Skip $to (unchanged)\n" unless $INSTALL_QUIET; 1182 next; 1183 } 1184 if (-f $to){ 1185 # we wont try hard here. its too likely to mess things up. 1186 forceunlink($to); 1187 } else { 1188 my $dirname = dirname($to); 1189 if (!$dirs{$dirname}++) { 1190 _mkpath($dirname,0,$Perm_Dir); 1191 } 1192 } 1193 if ($need_filtering) { 1194 run_filter($pm_filter, $from, $to); 1195 print "$pm_filter <$from >$to\n"; 1196 } else { 1197 _copy( $from, $to ); 1198 print "cp $from $to\n" unless $INSTALL_QUIET; 1199 } 1200 my($mode,$atime,$mtime) = (stat $from)[2,8,9]; 1201 utime($atime,$mtime+_Is_VMS,$to); 1202 _chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$to); 1203 next unless $from =~ /\.pm$/; 1204 _autosplit($to,$autodir) if defined $autodir; 1205 } 1206} 1207 1208=begin _private 1209 1210=head2 _autosplit 1211 1212From 1.0307 back, AutoSplit will sometimes leave an open filehandle to 1213the file being split. This causes problems on systems with mandatory 1214locking (ie. Windows). So we wrap it and close the filehandle. 1215 1216=end _private 1217 1218=cut 1219 1220sub _autosplit { #XXX OS-SPECIFIC 1221 require AutoSplit; 1222 my $retval = AutoSplit::autosplit(@_); 1223 close *AutoSplit::IN if defined *AutoSplit::IN{IO}; 1224 1225 return $retval; 1226} 1227 1228 1229package ExtUtils::Install::Warn; 1230 1231sub new { bless {}, shift } 1232 1233sub add { 1234 my($self,$file,$targetfile) = @_; 1235 push @{$self->{$file}}, $targetfile; 1236} 1237 1238sub DESTROY { 1239 unless(defined $INSTALL_ROOT) { 1240 my $self = shift; 1241 my($file,$i,$plural); 1242 foreach $file (sort keys %$self) { 1243 $plural = @{$self->{$file}} > 1 ? "s" : ""; 1244 print "## Differing version$plural of $file found. You might like to\n"; 1245 for (0..$#{$self->{$file}}) { 1246 print "rm ", $self->{$file}[$_], "\n"; 1247 $i++; 1248 } 1249 } 1250 $plural = $i>1 ? "all those files" : "this file"; 1251 my $inst = (_invokant() eq 'ExtUtils::MakeMaker') 1252 ? ( $Config::Config{make} || 'make' ).' install' 1253 . ( ExtUtils::Install::_Is_VMS ? '/MACRO="UNINST"=1' : ' UNINST=1' ) 1254 : './Build install uninst=1'; 1255 print "## Running '$inst' will unlink $plural for you.\n"; 1256 } 1257} 1258 1259=begin _private 1260 1261=head2 _invokant 1262 1263Does a heuristic on the stack to see who called us for more intelligent 1264error messages. Currently assumes we will be called only by Module::Build 1265or by ExtUtils::MakeMaker. 1266 1267=end _private 1268 1269=cut 1270 1271sub _invokant { 1272 my @stack; 1273 my $frame = 0; 1274 while (my $file = (caller($frame++))[1]) { 1275 push @stack, (File::Spec->splitpath($file))[2]; 1276 } 1277 1278 my $builder; 1279 my $top = pop @stack; 1280 if ($top =~ /^Build/i || exists($INC{'Module/Build.pm'})) { 1281 $builder = 'Module::Build'; 1282 } else { 1283 $builder = 'ExtUtils::MakeMaker'; 1284 } 1285 return $builder; 1286} 1287 1288=head1 ENVIRONMENT 1289 1290=over 4 1291 1292=item B<PERL_INSTALL_ROOT> 1293 1294Will be prepended to each install path. 1295 1296=item B<EU_INSTALL_IGNORE_SKIP> 1297 1298Will prevent the automatic use of INSTALL.SKIP as the install skip file. 1299 1300=item B<EU_INSTALL_SITE_SKIPFILE> 1301 1302If there is no INSTALL.SKIP file in the make directory then this value 1303can be used to provide a default. 1304 1305=item B<EU_INSTALL_ALWAYS_COPY> 1306 1307If this environment variable is true then normal install processes will 1308always overwrite older identical files during the install process. 1309 1310Note that the alias EU_ALWAYS_COPY will be supported if EU_INSTALL_ALWAYS_COPY 1311is not defined until at least the 1.50 release. Please ensure you use the 1312correct EU_INSTALL_ALWAYS_COPY. 1313 1314=back 1315 1316=head1 AUTHOR 1317 1318Original author lost in the mists of time. Probably the same as Makemaker. 1319 1320Production release currently maintained by demerphq C<yves at cpan.org>, 1321extensive changes by Michael G. Schwern. 1322 1323Send bug reports via http://rt.cpan.org/. Please send your 1324generated Makefile along with your report. 1325 1326=head1 LICENSE 1327 1328This program is free software; you can redistribute it and/or 1329modify it under the same terms as Perl itself. 1330 1331See L<http://www.perl.com/perl/misc/Artistic.html> 1332 1333 1334=cut 1335 13361; 1337