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