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