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