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