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