This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade BigInt and BigRat
[perl5.git] / lib / ExtUtils / Install.pm
CommitLineData
4b6d56d3 1package ExtUtils::Install;
2
57b1a898
MS
3use 5.00503;
4use vars qw(@ISA @EXPORT $VERSION);
dedf98bc 5$VERSION = 1.32;
f1387719 6
08ad6bd5 7use Exporter;
08ad6bd5 8use Carp ();
c3648e42 9use Config qw(%Config);
4b6d56d3 10@ISA = ('Exporter');
c3648e42 11@EXPORT = ('install','uninstall','pm_to_blib', 'install_default');
479d2113
MS
12$Is_VMS = $^O eq 'VMS';
13$Is_MacPerl = $^O eq 'MacOS';
08ad6bd5 14
39e571d4 15my $splitchar = $^O eq 'VMS' ? '|' : ($^O eq 'os2' || $^O eq 'dos') ? ';' : ':';
f1387719 16my $Inc_uninstall_warn_handler;
17
a9d83807
BC
18# install relative to here
19
20my $INSTALL_ROOT = $ENV{PERL_INSTALL_ROOT};
21
22use File::Spec;
479d2113
MS
23my $Curdir = File::Spec->curdir;
24my $Updir = File::Spec->updir;
a9d83807 25
a9d83807 26
479d2113 27=head1 NAME
a9d83807 28
479d2113 29ExtUtils::Install - install files from here to there
4b6d56d3 30
479d2113
MS
31=head1 SYNOPSIS
32
33 use ExtUtils::Install;
34
35 install({ 'blib/lib' => 'some/install/dir' } );
36
37 uninstall($packlist);
38
39 pm_to_blib({ 'lib/Foo/Bar.pm' => 'blib/lib/Foo/Bar.pm' });
40
41
42=head1 DESCRIPTION
43
44Handles the installing and uninstalling of perl modules, scripts, man
45pages, etc...
46
47Both install() and uninstall() are specific to the way
48ExtUtils::MakeMaker handles the installation and deinstallation of
49perl modules. They are not designed as general purpose tools.
50
51=head2 Functions
52
53=over 4
54
55=item B<install>
56
57 install(\%from_to);
1df8d179 58 install(\%from_to, $verbose, $dont_execute, $uninstall_shadows);
479d2113
MS
59
60Copies each directory tree of %from_to to its corresponding value
61preserving timestamps and permissions.
62
63There are two keys with a special meaning in the hash: "read" and
64"write". These contain packlist files. After the copying is done,
65install() will write the list of target files to $from_to{write}. If
66$from_to{read} is given the contents of this file will be merged into
67the written file. The read and the written file may be identical, but
68on AFS it is quite likely that people are installing to a different
69directory than the one where the files later appear.
70
71If $verbose is true, will print out each file removed. Default is
1df8d179 72false. This is "make install VERBINST=1"
479d2113
MS
73
74If $dont_execute is true it will only print what it was going to do
75without actually doing it. Default is false.
76
1df8d179
MS
77If $uninstall_shadows is true any differing versions throughout @INC
78will be uninstalled. This is "make install UNINST=1"
79
479d2113 80=cut
08ad6bd5 81
4b6d56d3 82sub install {
479d2113 83 my($from_to,$verbose,$nonono,$inc_uninstall) = @_;
4b6d56d3 84 $verbose ||= 0;
85 $nonono ||= 0;
08ad6bd5 86
87 use Cwd qw(cwd);
354f3b56 88 use ExtUtils::Packlist;
08ad6bd5 89 use File::Basename qw(dirname);
90 use File::Copy qw(copy);
91 use File::Find qw(find);
92 use File::Path qw(mkpath);
fb73857a 93 use File::Compare qw(compare);
08ad6bd5 94
479d2113 95 my(%from_to) = %$from_to;
354f3b56
AB
96 my(%pack, $dir, $warn_permissions);
97 my($packlist) = ExtUtils::Packlist->new();
3e3baf6d
TB
98 # -w doesn't work reliably on FAT dirs
99 $warn_permissions++ if $^O eq 'MSWin32';
354f3b56 100 local(*DIR);
4b6d56d3 101 for (qw/read write/) {
479d2113
MS
102 $pack{$_}=$from_to{$_};
103 delete $from_to{$_};
4b6d56d3 104 }
08ad6bd5 105 my($source_dir_or_file);
479d2113 106 foreach $source_dir_or_file (sort keys %from_to) {
4b6d56d3 107 #Check if there are files, and if yes, look if the corresponding
108 #target directory is writable for us
08ad6bd5 109 opendir DIR, $source_dir_or_file or next;
f1387719 110 for (readdir DIR) {
479d2113
MS
111 next if $_ eq $Curdir || $_ eq $Updir || $_ eq ".exists";
112 my $targetdir = install_rooted_dir($from_to{$source_dir_or_file});
2530b651
MS
113 mkpath($targetdir) unless $nonono;
114 if (!$nonono && !-w $targetdir) {
115 warn "Warning: You do not have permissions to " .
116 "install into $from_to{$source_dir_or_file}"
117 unless $warn_permissions++;
4b6d56d3 118 }
119 }
120 closedir DIR;
121 }
a9d83807
BC
122 my $tmpfile = install_rooted_file($pack{"read"});
123 $packlist->read($tmpfile) if (-f $tmpfile);
4b6d56d3 124 my $cwd = cwd();
4b6d56d3 125
479d2113 126 MOD_INSTALL: foreach my $source (sort keys %from_to) {
4b6d56d3 127 #copy the tree to the target directory without altering
128 #timestamp and permission and remember for the .packlist
129 #file. The packlist file contains the absolute paths of the
130 #install locations. AFS users may call this a bug. We'll have
131 #to reconsider how to add the means to satisfy AFS users also.
456e5c25
A
132
133 #October 1997: we want to install .pm files into archlib if
134 #there are any files in arch. So we depend on having ./blib/arch
135 #hardcoded here.
a9d83807 136
479d2113 137 my $targetroot = install_rooted_dir($from_to{$source});
a9d83807 138
479d2113
MS
139 my $blib_lib = File::Spec->catdir('blib', 'lib');
140 my $blib_arch = File::Spec->catdir('blib', 'arch');
141 if ($source eq $blib_lib and
142 exists $from_to{$blib_arch} and
143 directory_not_empty($blib_arch)) {
144 $targetroot = install_rooted_dir($from_to{$blib_arch});
145 print "Files found in $blib_arch: installing files in $blib_lib into architecture dependent library tree\n";
456e5c25 146 }
479d2113
MS
147
148 chdir $source or next;
4b6d56d3 149 find(sub {
479d2113 150 my ($mode,$size,$atime,$mtime) = (stat)[2,7,8,9];
4b6d56d3 151 return unless -f _;
1df8d179
MS
152
153 my $origfile = $_;
154 return if $origfile eq ".exists";
3ac85e8f 155 my $targetdir = File::Spec->catdir($targetroot, $File::Find::dir);
1df8d179 156 my $targetfile = File::Spec->catfile($targetdir, $origfile);
479d2113 157 my $sourcedir = File::Spec->catdir($source, $File::Find::dir);
1df8d179 158 my $sourcefile = File::Spec->catfile($sourcedir, $origfile);
479d2113
MS
159
160 my $save_cwd = cwd;
161 chdir $cwd; # in case the target is relative
162 # 5.5.3's File::Find missing no_chdir option.
4b6d56d3 163
f1387719 164 my $diff = 0;
4b6d56d3 165 if ( -f $targetfile && -s _ == $size) {
166 # We have a good chance, we can skip this one
479d2113 167 $diff = compare($sourcefile, $targetfile);
4b6d56d3 168 } else {
479d2113 169 print "$sourcefile differs\n" if $verbose>1;
4b6d56d3 170 $diff++;
171 }
172
173 if ($diff){
08ad6bd5 174 if (-f $targetfile){
f1387719 175 forceunlink($targetfile) unless $nonono;
08ad6bd5 176 } else {
177 mkpath($targetdir,0,0755) unless $nonono;
178 print "mkpath($targetdir,0,0755)\n" if $verbose>1;
179 }
479d2113 180 copy($sourcefile, $targetfile) unless $nonono;
f1387719 181 print "Installing $targetfile\n";
08ad6bd5 182 utime($atime,$mtime + $Is_VMS,$targetfile) unless $nonono>1;
4b6d56d3 183 print "utime($atime,$mtime,$targetfile)\n" if $verbose>1;
f1387719 184 $mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
4b6d56d3 185 chmod $mode, $targetfile;
186 print "chmod($mode, $targetfile)\n" if $verbose>1;
187 } else {
f1387719 188 print "Skipping $targetfile (unchanged)\n" if $verbose;
189 }
479d2113
MS
190
191 if (defined $inc_uninstall) {
192 inc_uninstall($sourcefile,$File::Find::dir,$verbose,
193 $inc_uninstall ? 0 : 1);
4b6d56d3 194 }
479d2113 195
8c05f1d0 196 # Record the full pathname.
007a26ab 197 $packlist->{$targetfile}++;
4b6d56d3 198
479d2113
MS
199 # File::Find can get confused if you chdir in here.
200 chdir $save_cwd;
201
202 # File::Find seems to always be Unixy except on MacPerl :(
203 }, $Is_MacPerl ? $Curdir : '.' );
08ad6bd5 204 chdir($cwd) or Carp::croak("Couldn't chdir to $cwd: $!");
4b6d56d3 205 }
4b6d56d3 206 if ($pack{'write'}) {
a9d83807 207 $dir = install_rooted_dir(dirname($pack{'write'}));
ab00ffcd 208 mkpath($dir,0,0755) unless $nonono;
4b6d56d3 209 print "Writing $pack{'write'}\n";
ab00ffcd 210 $packlist->write(install_rooted_file($pack{'write'})) unless $nonono;
4b6d56d3 211 }
212}
213
479d2113
MS
214sub install_rooted_file {
215 if (defined $INSTALL_ROOT) {
216 File::Spec->catfile($INSTALL_ROOT, $_[0]);
217 } else {
218 $_[0];
219 }
220}
221
222
223sub install_rooted_dir {
224 if (defined $INSTALL_ROOT) {
225 File::Spec->catdir($INSTALL_ROOT, $_[0]);
226 } else {
227 $_[0];
228 }
229}
230
231
232sub forceunlink {
233 chmod 0666, $_[0];
234 unlink $_[0] or Carp::croak("Cannot forceunlink $_[0]: $!")
235}
236
237
456e5c25
A
238sub directory_not_empty ($) {
239 my($dir) = @_;
240 my $files = 0;
241 find(sub {
242 return if $_ eq ".exists";
243 if (-f) {
244 $File::Find::prune++;
245 $files = 1;
246 }
247 }, $dir);
248 return $files;
249}
250
479d2113
MS
251
252=item B<install_default> I<DISCOURAGED>
253
254 install_default();
255 install_default($fullext);
256
257Calls install() with arguments to copy a module from blib/ to the
258default site installation location.
259
260$fullext is the name of the module converted to a directory
261(ie. Foo::Bar would be Foo/Bar). If $fullext is not specified, it
262will attempt to read it from @ARGV.
263
264This is primarily useful for install scripts.
265
266B<NOTE> This function is not really useful because of the hard-coded
267install location with no way to control site vs core vs vendor
268directories and the strange way in which the module name is given.
269Consider its use discouraged.
270
271=cut
272
c3648e42
IZ
273sub install_default {
274 @_ < 2 or die "install_default should be called with 0 or 1 argument";
275 my $FULLEXT = @_ ? shift : $ARGV[0];
276 defined $FULLEXT or die "Do not know to where to write install log";
5de3f0da
DR
277 my $INST_LIB = File::Spec->catdir(File::Spec->curdir,"blib","lib");
278 my $INST_ARCHLIB = File::Spec->catdir(File::Spec->curdir,"blib","arch");
279 my $INST_BIN = File::Spec->catdir(File::Spec->curdir,'blib','bin');
280 my $INST_SCRIPT = File::Spec->catdir(File::Spec->curdir,'blib','script');
281 my $INST_MAN1DIR = File::Spec->catdir(File::Spec->curdir,'blib','man1');
282 my $INST_MAN3DIR = File::Spec->catdir(File::Spec->curdir,'blib','man3');
c3648e42
IZ
283 install({
284 read => "$Config{sitearchexp}/auto/$FULLEXT/.packlist",
285 write => "$Config{installsitearch}/auto/$FULLEXT/.packlist",
456e5c25
A
286 $INST_LIB => (directory_not_empty($INST_ARCHLIB)) ?
287 $Config{installsitearch} :
288 $Config{installsitelib},
c3648e42
IZ
289 $INST_ARCHLIB => $Config{installsitearch},
290 $INST_BIN => $Config{installbin} ,
291 $INST_SCRIPT => $Config{installscript},
292 $INST_MAN1DIR => $Config{installman1dir},
293 $INST_MAN3DIR => $Config{installman3dir},
294 },1,0,0);
295}
296
479d2113
MS
297
298=item B<uninstall>
299
300 uninstall($packlist_file);
301 uninstall($packlist_file, $verbose, $dont_execute);
302
303Removes the files listed in a $packlist_file.
304
305If $verbose is true, will print out each file removed. Default is
306false.
307
308If $dont_execute is true it will only print what it was going to do
309without actually doing it. Default is false.
310
311=cut
312
4b6d56d3 313sub uninstall {
354f3b56 314 use ExtUtils::Packlist;
4b6d56d3 315 my($fil,$verbose,$nonono) = @_;
479d2113
MS
316 $verbose ||= 0;
317 $nonono ||= 0;
318
4b6d56d3 319 die "no packlist file found: $fil" unless -f $fil;
f1387719 320 # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al));
321 # require $my_req; # Hairy, but for the first
354f3b56
AB
322 my ($packlist) = ExtUtils::Packlist->new($fil);
323 foreach (sort(keys(%$packlist))) {
4b6d56d3 324 chomp;
325 print "unlink $_\n" if $verbose;
f1387719 326 forceunlink($_) unless $nonono;
4b6d56d3 327 }
328 print "unlink $fil\n" if $verbose;
f1387719 329 forceunlink($fil) unless $nonono;
330}
331
332sub inc_uninstall {
1df8d179 333 my($filepath,$libdir,$verbose,$nonono) = @_;
f1387719 334 my($dir);
1df8d179 335 my $file = (File::Spec->splitpath($filepath))[2];
f1387719 336 my %seen_dir = ();
1df8d179
MS
337
338 my @PERL_ENV_LIB = split $splitchar, defined $ENV{'PERL5LIB'}
339 ? $ENV{'PERL5LIB'} : $ENV{'PERLLIB'} || '';
340
456e5c25
A
341 foreach $dir (@INC, @PERL_ENV_LIB, @Config{qw(archlibexp
342 privlibexp
343 sitearchexp
344 sitelibexp)}) {
479d2113 345 next if $dir eq $Curdir;
f1387719 346 next if $seen_dir{$dir}++;
3ac85e8f 347 my($targetfile) = File::Spec->catfile($dir,$libdir,$file);
f1387719 348 next unless -f $targetfile;
349
350 # The reason why we compare file's contents is, that we cannot
351 # know, which is the file we just installed (AFS). So we leave
352 # an identical file in place
353 my $diff = 0;
1df8d179 354 if ( -f $targetfile && -s _ == -s $filepath) {
f1387719 355 # We have a good chance, we can skip this one
1df8d179 356 $diff = compare($filepath,$targetfile);
f1387719 357 } else {
358 print "#$file and $targetfile differ\n" if $verbose>1;
359 $diff++;
360 }
361
362 next unless $diff;
363 if ($nonono) {
364 if ($verbose) {
365 $Inc_uninstall_warn_handler ||= new ExtUtils::Install::Warn;
4f44ac69 366 $libdir =~ s|^\./||s ; # That's just cosmetics, no need to port. It looks prettier.
479d2113
MS
367 $Inc_uninstall_warn_handler->add(
368 File::Spec->catfile($libdir, $file),
369 $targetfile
370 );
f1387719 371 }
372 # if not verbose, we just say nothing
373 } else {
374 print "Unlinking $targetfile (shadowing?)\n";
375 forceunlink($targetfile);
376 }
377 }
08ad6bd5 378}
379
131aa089
RM
380sub run_filter {
381 my ($cmd, $src, $dest) = @_;
1df8d179 382 local(*CMD, *SRC);
57b1a898
MS
383 open(CMD, "|$cmd >$dest") || die "Cannot fork: $!";
384 open(SRC, $src) || die "Cannot open $src: $!";
131aa089
RM
385 my $buf;
386 my $sz = 1024;
57b1a898
MS
387 while (my $len = sysread(SRC, $buf, $sz)) {
388 syswrite(CMD, $buf, $len);
131aa089 389 }
57b1a898
MS
390 close SRC;
391 close CMD or die "Filter command '$cmd' failed for $src";
131aa089
RM
392}
393
479d2113
MS
394
395=item B<pm_to_blib>
396
397 pm_to_blib(\%from_to, $autosplit_dir);
398 pm_to_blib(\%from_to, $autosplit_dir, $filter_cmd);
399
400Copies each key of %from_to to its corresponding value efficiently.
401Filenames with the extension .pm are autosplit into the $autosplit_dir.
402
403$filter_cmd is an optional shell command to run each .pm file through
404prior to splitting and copying. Input is the contents of the module,
405output the new module contents.
406
407You can have an environment variable PERL_INSTALL_ROOT set which will
408be prepended as a directory to each installed file (and directory).
409
410=cut
411
08ad6bd5 412sub pm_to_blib {
131aa089 413 my($fromto,$autodir,$pm_filter) = @_;
08ad6bd5 414
415 use File::Basename qw(dirname);
416 use File::Copy qw(copy);
417 use File::Path qw(mkpath);
fb73857a 418 use File::Compare qw(compare);
08ad6bd5 419 use AutoSplit;
f1387719 420 # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al));
421 # require $my_req; # Hairy, but for the first
08ad6bd5 422
68dc0745 423 if (!ref($fromto) && -r $fromto)
424 {
425 # Win32 has severe command line length limitations, but
426 # can generate temporary files on-the-fly
427 # so we pass name of file here - eval it to get hash
428 open(FROMTO,"<$fromto") or die "Cannot open $fromto:$!";
429 my $str = '$fromto = {qw{'.join('',<FROMTO>).'}}';
430 eval $str;
431 close(FROMTO);
432 }
433
08ad6bd5 434 mkpath($autodir,0,0755);
479d2113 435 while(my($from, $to) = each %$fromto) {
dedf98bc
MS
436 if( -f $to && -s $from == -s $to && -M $to < -M $from ) {
437 print "Skip $to (unchanged)\n";
438 next;
439 }
131aa089
RM
440
441 # When a pm_filter is defined, we need to pre-process the source first
442 # to determine whether it has changed or not. Therefore, only perform
443 # the comparison check when there's no filter to be ran.
444 # -- RAM, 03/01/2001
445
479d2113
MS
446 my $need_filtering = defined $pm_filter && length $pm_filter &&
447 $from =~ /\.pm$/;
131aa089 448
479d2113
MS
449 if (!$need_filtering && 0 == compare($from,$to)) {
450 print "Skip $to (unchanged)\n";
08ad6bd5 451 next;
452 }
479d2113
MS
453 if (-f $to){
454 forceunlink($to);
131aa089 455 } else {
479d2113 456 mkpath(dirname($to),0,0755);
131aa089
RM
457 }
458 if ($need_filtering) {
479d2113
MS
459 run_filter($pm_filter, $from, $to);
460 print "$pm_filter <$from >$to\n";
08ad6bd5 461 } else {
479d2113
MS
462 copy($from,$to);
463 print "cp $from $to\n";
08ad6bd5 464 }
479d2113
MS
465 my($mode,$atime,$mtime) = (stat $from)[2,8,9];
466 utime($atime,$mtime+$Is_VMS,$to);
467 chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$to);
468 next unless $from =~ /\.pm$/;
469 _autosplit($to,$autodir);
08ad6bd5 470 }
4b6d56d3 471}
472
479d2113
MS
473
474=begin _private
475
476=item _autosplit
477
478From 1.0307 back, AutoSplit will sometimes leave an open filehandle to
479the file being split. This causes problems on systems with mandatory
480locking (ie. Windows). So we wrap it and close the filehandle.
481
482=end _private
483
484=cut
485
486sub _autosplit {
487 my $retval = autosplit(@_);
488 close *AutoSplit::IN if defined *AutoSplit::IN{IO};
489
490 return $retval;
491}
492
493
f1387719 494package ExtUtils::Install::Warn;
495
496sub new { bless {}, shift }
497
498sub add {
499 my($self,$file,$targetfile) = @_;
500 push @{$self->{$file}}, $targetfile;
501}
502
503sub DESTROY {
479d2113
MS
504 unless(defined $INSTALL_ROOT) {
505 my $self = shift;
506 my($file,$i,$plural);
507 foreach $file (sort keys %$self) {
508 $plural = @{$self->{$file}} > 1 ? "s" : "";
509 print "## Differing version$plural of $file found. You might like to\n";
510 for (0..$#{$self->{$file}}) {
511 print "rm ", $self->{$file}[$_], "\n";
512 $i++;
513 }
514 }
515 $plural = $i>1 ? "all those files" : "this file";
516 print "## Running 'make install UNINST=1' will unlink $plural for you.\n";
517 }
f1387719 518}
519
479d2113 520=back
4b6d56d3 521
4b6d56d3 522
479d2113 523=head1 ENVIRONMENT
4b6d56d3 524
479d2113 525=over 4
4b6d56d3 526
479d2113 527=item B<PERL_INSTALL_ROOT>
4b6d56d3 528
479d2113 529Will be prepended to each install path.
4b6d56d3 530
479d2113 531=back
4b6d56d3 532
479d2113 533=head1 AUTHOR
4b6d56d3 534
479d2113 535Original author lost in the mists of time. Probably the same as Makemaker.
08ad6bd5 536
479d2113 537Currently maintained by Michael G Schwern <F<schwern@pobox.com>>
4b6d56d3 538
479d2113 539Send patches and ideas to <F<makemaker@perl.org>>.
4b6d56d3 540
479d2113
MS
541Send bug reports via http://rt.cpan.org/. Please send your
542generated Makefile along with your report.
4b6d56d3 543
479d2113
MS
544For more up-to-date information, see http://www.makemaker.org.
545
546
547=head1 LICENSE
548
549This program is free software; you can redistribute it and/or
550modify it under the same terms as Perl itself.
551
552See F<http://www.perl.com/perl/misc/Artistic.html>
4b6d56d3 553
ae1d6394 554
08ad6bd5 555=cut
479d2113
MS
556
5571;