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