1 package ExtUtils::Install;
3 $VERSION = substr q$Revision: 1.28 $, 10;
4 # $Date: 1998/01/25 07:08:24 $
5 # $FreeBSD: src/contrib/perl5/lib/ExtUtils/Install.pm,v 1.2 2000/01/29 17:27:17 markm Exp $
9 use Config qw(%Config);
10 use vars qw(@ISA @EXPORT $VERSION);
12 @EXPORT = ('install','uninstall','pm_to_blib', 'install_default');
13 $Is_VMS = $^O eq 'VMS';
15 my $splitchar = $^O eq 'VMS' ? '|' : ($^O eq 'os2' || $^O eq 'dos') ? ';' : ':';
16 my @PERL_ENV_LIB = split $splitchar, defined $ENV{'PERL5LIB'} ? $ENV{'PERL5LIB'} : $ENV{'PERLLIB'} || '';
17 my $Inc_uninstall_warn_handler;
19 #use vars qw( @EXPORT @ISA $Is_VMS );
24 unlink $_[0] or Carp::croak("Cannot forceunlink $_[0]: $!")
28 my($hash,$verbose,$nonono,$inc_uninstall) = @_;
33 use ExtUtils::MakeMaker; # to implement a MY class
34 use ExtUtils::Packlist;
35 use File::Basename qw(dirname);
36 use File::Copy qw(copy);
37 use File::Find qw(find);
38 use File::Path qw(mkpath);
39 use File::Compare qw(compare);
42 my(%pack, $dir, $warn_permissions);
43 my($packlist) = ExtUtils::Packlist->new();
44 # -w doesn't work reliably on FAT dirs
45 $warn_permissions++ if $^O eq 'MSWin32';
47 for (qw/read write/) {
51 my($source_dir_or_file);
52 foreach $source_dir_or_file (sort keys %hash) {
53 #Check if there are files, and if yes, look if the corresponding
54 #target directory is writable for us
55 opendir DIR, $source_dir_or_file or next;
57 next if $_ eq "." || $_ eq ".." || $_ eq ".exists";
58 if (-w $hash{$source_dir_or_file} ||
59 mkpath($hash{$source_dir_or_file})) {
62 warn "Warning: You do not have permissions to " .
63 "install into $hash{$source_dir_or_file}"
64 unless $warn_permissions++;
69 $packlist->read($pack{"read"}) if (-f $pack{"read"});
71 my $umask = umask 0 unless $Is_VMS;
74 MOD_INSTALL: foreach $source (sort keys %hash) {
75 #copy the tree to the target directory without altering
76 #timestamp and permission and remember for the .packlist
77 #file. The packlist file contains the absolute paths of the
78 #install locations. AFS users may call this a bug. We'll have
79 #to reconsider how to add the means to satisfy AFS users also.
81 # FreeBSD also doesn't like this (much). At install time, the
82 # ctime should change, even if the file does not.
84 #October 1997: we want to install .pm files into archlib if
85 #there are any files in arch. So we depend on having ./blib/arch
87 my $targetroot = $hash{$source};
88 if ($source eq "blib/lib" and
89 exists $hash{"blib/arch"} and
90 directory_not_empty("blib/arch")) {
91 $targetroot = $hash{"blib/arch"};
92 print "Files found in blib/arch --> Installing files in "
93 . "blib/lib into architecture dependend library tree!\n"
96 chdir($source) or next;
98 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
99 $atime,$mtime,$ctime,$blksize,$blocks) = stat;
101 return if $_ eq ".exists";
102 my $targetdir = MY->catdir($targetroot,$File::Find::dir);
103 my $targetfile = MY->catfile($targetdir,$_);
106 if ( -f $targetfile && -s _ == $size) {
107 # We have a good chance, we can skip this one
108 $diff = compare($_,$targetfile);
110 print "$_ differs\n" if $verbose>1;
113 my $diff = 1; # Nasty, lowdown, rotten, scumsucking
114 # hack to make FreeBSD _really_ install.
118 forceunlink($targetfile) unless $nonono;
120 mkpath($targetdir,0,0755) unless $nonono;
121 print "mkpath($targetdir,0,0755)\n" if $verbose>1;
123 copy($_,$targetfile) unless $nonono;
124 print "Installing $targetfile\n";
125 utime($atime,$mtime + $Is_VMS,$targetfile) unless $nonono>1;
126 print "utime($atime,$mtime,$targetfile)\n" if $verbose>1;
127 $mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
128 chmod $mode, $targetfile;
129 print "chmod($mode, $targetfile)\n" if $verbose>1;
131 print "Skipping $targetfile (unchanged)\n" if $verbose;
134 if (! defined $inc_uninstall) { # it's called
135 } elsif ($inc_uninstall == 0){
136 inc_uninstall($_,$File::Find::dir,$verbose,1); # nonono set to 1
138 inc_uninstall($_,$File::Find::dir,$verbose,0); # nonono set to 0
140 $packlist->{$targetfile}++;
143 chdir($cwd) or Carp::croak("Couldn't chdir to $cwd: $!");
145 umask $umask unless $Is_VMS;
146 if ($pack{'write'}) {
147 $dir = dirname($pack{'write'});
149 print "Writing $pack{'write'}\n";
150 $packlist->write($pack{'write'});
154 sub directory_not_empty ($) {
158 return if $_ eq ".exists";
160 $File::Find::prune++;
167 sub install_default {
168 @_ < 2 or die "install_default should be called with 0 or 1 argument";
169 my $FULLEXT = @_ ? shift : $ARGV[0];
170 defined $FULLEXT or die "Do not know to where to write install log";
171 my $INST_LIB = MM->catdir(MM->curdir,"blib","lib");
172 my $INST_ARCHLIB = MM->catdir(MM->curdir,"blib","arch");
173 my $INST_BIN = MM->catdir(MM->curdir,'blib','bin');
174 my $INST_SCRIPT = MM->catdir(MM->curdir,'blib','script');
175 my $INST_MAN1DIR = MM->catdir(MM->curdir,'blib','man1');
176 my $INST_MAN3DIR = MM->catdir(MM->curdir,'blib','man3');
178 read => "$Config{sitearchexp}/auto/$FULLEXT/.packlist",
179 write => "$Config{installsitearch}/auto/$FULLEXT/.packlist",
180 $INST_LIB => (directory_not_empty($INST_ARCHLIB)) ?
181 $Config{installsitearch} :
182 $Config{installsitelib},
183 $INST_ARCHLIB => $Config{installsitearch},
184 $INST_BIN => $Config{installbin} ,
185 $INST_SCRIPT => $Config{installscript},
186 $INST_MAN1DIR => $Config{installman1dir},
187 $INST_MAN3DIR => $Config{installman3dir},
192 use ExtUtils::Packlist;
193 my($fil,$verbose,$nonono) = @_;
194 die "no packlist file found: $fil" unless -f $fil;
195 # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al));
196 # require $my_req; # Hairy, but for the first
197 my ($packlist) = ExtUtils::Packlist->new($fil);
198 foreach (sort(keys(%$packlist))) {
200 print "unlink $_\n" if $verbose;
201 forceunlink($_) unless $nonono;
203 print "unlink $fil\n" if $verbose;
205 forceunlink($fil) unless $nonono;
209 my($file,$libdir,$verbose,$nonono) = @_;
212 foreach $dir (@INC, @PERL_ENV_LIB, @Config{qw(archlibexp
217 next if $seen_dir{$dir}++;
218 my($targetfile) = MY->catfile($dir,$libdir,$file);
219 next unless -f $targetfile;
221 # The reason why we compare file's contents is, that we cannot
222 # know, which is the file we just installed (AFS). So we leave
223 # an identical file in place
225 if ( -f $targetfile && -s _ == -s $file) {
226 # We have a good chance, we can skip this one
227 $diff = compare($file,$targetfile);
229 print "#$file and $targetfile differ\n" if $verbose>1;
236 $Inc_uninstall_warn_handler ||= new ExtUtils::Install::Warn;
237 $libdir =~ s|^\./|| ; # That's just cosmetics, no need to port. It looks prettier.
238 $Inc_uninstall_warn_handler->add("$libdir/$file",$targetfile);
240 # if not verbose, we just say nothing
242 print "Unlinking $targetfile (shadowing?)\n";
243 forceunlink($targetfile);
249 my($fromto,$autodir) = @_;
251 use File::Basename qw(dirname);
252 use File::Copy qw(copy);
253 use File::Path qw(mkpath);
254 use File::Compare qw(compare);
256 # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al));
257 # require $my_req; # Hairy, but for the first
259 if (!ref($fromto) && -r $fromto)
261 # Win32 has severe command line length limitations, but
262 # can generate temporary files on-the-fly
263 # so we pass name of file here - eval it to get hash
264 open(FROMTO,"<$fromto") or die "Cannot open $fromto:$!";
265 my $str = '$fromto = {qw{'.join('',<FROMTO>).'}}';
270 my $umask = umask 0022 unless $Is_VMS;
271 mkpath($autodir,0,0755);
272 foreach (keys %$fromto) {
273 next if -f $fromto->{$_} && -M $fromto->{$_} < -M $_;
274 unless (compare($_,$fromto->{$_})){
275 print "Skip $fromto->{$_} (unchanged)\n";
278 if (-f $fromto->{$_}){
279 forceunlink($fromto->{$_});
281 mkpath(dirname($fromto->{$_}),0,0755);
283 copy($_,$fromto->{$_});
284 my($mode,$atime,$mtime) = (stat)[2,8,9];
285 utime($atime,$mtime+$Is_VMS,$fromto->{$_});
286 chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$fromto->{$_});
287 print "cp $_ $fromto->{$_}\n";
289 autosplit($fromto->{$_},$autodir);
291 umask $umask unless $Is_VMS;
294 package ExtUtils::Install::Warn;
296 sub new { bless {}, shift }
299 my($self,$file,$targetfile) = @_;
300 push @{$self->{$file}}, $targetfile;
305 my($file,$i,$plural);
306 foreach $file (sort keys %$self) {
307 $plural = @{$self->{$file}} > 1 ? "s" : "";
308 print "## Differing version$plural of $file found. You might like to\n";
309 for (0..$#{$self->{$file}}) {
310 print "rm ", $self->{$file}[$_], "\n";
314 $plural = $i>1 ? "all those files" : "this file";
315 print "## Running 'make install UNINST=1' will unlink $plural for you.\n";
324 ExtUtils::Install - install files from here to there
328 B<use ExtUtils::Install;>
330 B<install($hashref,$verbose,$nonono);>
332 B<uninstall($packlistfile,$verbose,$nonono);>
334 B<pm_to_blib($hashref);>
338 Both install() and uninstall() are specific to the way
339 ExtUtils::MakeMaker handles the installation and deinstallation of
340 perl modules. They are not designed as general purpose tools.
342 install() takes three arguments. A reference to a hash, a verbose
343 switch and a don't-really-do-it switch. The hash ref contains a
344 mapping of directories: each key/value pair is a combination of
345 directories to be copied. Key is a directory to copy from, value is a
346 directory to copy to. The whole tree below the "from" directory will
347 be copied preserving timestamps and permissions.
349 There are two keys with a special meaning in the hash: "read" and
350 "write". After the copying is done, install will write the list of
351 target files to the file named by C<$hashref-E<gt>{write}>. If there is
352 another file named by C<$hashref-E<gt>{read}>, the contents of this file will
353 be merged into the written file. The read and the written file may be
354 identical, but on AFS it is quite likely, people are installing to a
355 different directory than the one where the files later appear.
357 install_default() takes one or less arguments. If no arguments are
358 specified, it takes $ARGV[0] as if it was specified as an argument.
359 The argument is the value of MakeMaker's C<FULLEXT> key, like F<Tk/Canvas>.
360 This function calls install() with the same arguments as the defaults
361 the MakeMaker would use.
363 The argument-less form is convenient for install scripts like
365 perl -MExtUtils::Install -e install_default Tk/Canvas
367 Assuming this command is executed in a directory with populated F<blib>
368 directory, it will proceed as if the F<blib> was build by MakeMaker on
369 this machine. This is useful for binary distributions.
371 uninstall() takes as first argument a file containing filenames to be
372 unlinked. The second argument is a verbose switch, the third is a
373 no-don't-really-do-it-now switch.
375 pm_to_blib() takes a hashref as the first argument and copies all keys
376 of the hash to the corresponding values efficiently. Filenames with
377 the extension pm are autosplit. Second argument is the autosplit