31ca69067ee0e51e96f3f403a4f0ed3aee2de11f
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / MM_VMS.pm
1 #   MM_VMS.pm
2 #   MakeMaker default methods for VMS
3 #   This package is inserted into @ISA of MakeMaker's MM before the
4 #   built-in ExtUtils::MM_Unix methods if MakeMaker.pm is run under VMS.
5 #
6 #   Author:  Charles Bailey  bailey@newman.upenn.edu
7
8 package ExtUtils::MM_VMS;
9
10 use Carp qw( &carp );
11 use Config;
12 require Exporter;
13 use VMS::Filespec;
14 use File::Basename;
15 use File::Spec;
16 use vars qw($Revision @ISA);
17 $Revision = '5.56 (27-Apr-1999)';
18
19 @ISA = qw( File::Spec );
20 unshift @MM::ISA, 'ExtUtils::MM_VMS';
21
22 Exporter::import('ExtUtils::MakeMaker', '$Verbose', '&neatvalue');
23
24 =head1 NAME
25
26 ExtUtils::MM_VMS - methods to override UN*X behaviour in ExtUtils::MakeMaker
27
28 =head1 SYNOPSIS
29
30  use ExtUtils::MM_VMS; # Done internally by ExtUtils::MakeMaker if needed
31
32 =head1 DESCRIPTION
33
34 See ExtUtils::MM_Unix for a documentation of the methods provided
35 there. This package overrides the implementation of these methods, not
36 the semantics.
37
38 =head2 Methods always loaded
39
40 =over
41
42 =item wraplist
43
44 Converts a list into a string wrapped at approximately 80 columns.
45
46 =cut
47
48 sub wraplist {
49     my($self) = shift;
50     my($line,$hlen) = ('',0);
51     my($word);
52
53     foreach $word (@_) {
54       # Perl bug -- seems to occasionally insert extra elements when
55       # traversing array (scalar(@array) doesn't show them, but
56       # foreach(@array) does) (5.00307)
57       next unless $word =~ /\w/;
58       $line .= ' ' if length($line);
59       if ($hlen > 80) { $line .= "\\\n\t"; $hlen = 0; }
60       $line .= $word;
61       $hlen += length($word) + 2;
62     }
63     $line;
64 }
65
66 =item rootdir (override)
67
68 Returns a string representing of the root directory.
69
70 =cut
71
72 sub rootdir {
73     return '';
74 }
75
76 package ExtUtils::MM_VMS;
77
78 sub ExtUtils::MM_VMS::ext;
79 sub ExtUtils::MM_VMS::guess_name;
80 sub ExtUtils::MM_VMS::find_perl;
81 sub ExtUtils::MM_VMS::path;
82 sub ExtUtils::MM_VMS::maybe_command;
83 sub ExtUtils::MM_VMS::maybe_command_in_dirs;
84 sub ExtUtils::MM_VMS::perl_script;
85 sub ExtUtils::MM_VMS::file_name_is_absolute;
86 sub ExtUtils::MM_VMS::replace_manpage_separator;
87 sub ExtUtils::MM_VMS::init_others;
88 sub ExtUtils::MM_VMS::constants;
89 sub ExtUtils::MM_VMS::cflags;
90 sub ExtUtils::MM_VMS::const_cccmd;
91 sub ExtUtils::MM_VMS::pm_to_blib;
92 sub ExtUtils::MM_VMS::tool_autosplit;
93 sub ExtUtils::MM_VMS::tool_xsubpp;
94 sub ExtUtils::MM_VMS::xsubpp_version;
95 sub ExtUtils::MM_VMS::tools_other;
96 sub ExtUtils::MM_VMS::dist;
97 sub ExtUtils::MM_VMS::c_o;
98 sub ExtUtils::MM_VMS::xs_c;
99 sub ExtUtils::MM_VMS::xs_o;
100 sub ExtUtils::MM_VMS::top_targets;
101 sub ExtUtils::MM_VMS::dlsyms;
102 sub ExtUtils::MM_VMS::dynamic_lib;
103 sub ExtUtils::MM_VMS::dynamic_bs;
104 sub ExtUtils::MM_VMS::static_lib;
105 sub ExtUtils::MM_VMS::manifypods;
106 sub ExtUtils::MM_VMS::processPL;
107 sub ExtUtils::MM_VMS::installbin;
108 sub ExtUtils::MM_VMS::subdir_x;
109 sub ExtUtils::MM_VMS::clean;
110 sub ExtUtils::MM_VMS::realclean;
111 sub ExtUtils::MM_VMS::dist_basics;
112 sub ExtUtils::MM_VMS::dist_core;
113 sub ExtUtils::MM_VMS::dist_dir;
114 sub ExtUtils::MM_VMS::dist_test;
115 sub ExtUtils::MM_VMS::install;
116 sub ExtUtils::MM_VMS::perldepend;
117 sub ExtUtils::MM_VMS::makefile;
118 sub ExtUtils::MM_VMS::test;
119 sub ExtUtils::MM_VMS::test_via_harness;
120 sub ExtUtils::MM_VMS::test_via_script;
121 sub ExtUtils::MM_VMS::makeaperl;
122 sub ExtUtils::MM_VMS::ext;
123 sub ExtUtils::MM_VMS::nicetext;
124
125 #use SelfLoader;
126 sub AUTOLOAD {
127     my $code;
128     if (defined fileno(DATA)) {
129         my $fh = select DATA;
130         my $o = $/;                     # For future reads from the file.
131         $/ = "\n__END__\n";
132         $code = <DATA>;
133         $/ = $o;
134         select $fh;
135         close DATA;
136         eval $code;
137         if ($@) {
138             $@ =~ s/ at .*\n//;
139             Carp::croak $@;
140         }
141     } else {
142         warn "AUTOLOAD called unexpectedly for $AUTOLOAD"; 
143     }
144     defined(&$AUTOLOAD) or die "Myloader inconsistency error";
145     goto &$AUTOLOAD;
146 }
147
148 1;
149
150 #__DATA__
151
152
153 # This isn't really an override.  It's just here because ExtUtils::MM_VMS
154 # appears in @MM::ISA before ExtUtils::Liblist, so if there isn't an ext()
155 # in MM_VMS, then AUTOLOAD is called, and bad things happen.  So, we just
156 # mimic inheritance here and hand off to ExtUtils::Liblist.
157 sub ext {
158   ExtUtils::Liblist::ext(@_);
159 }
160
161 =back
162
163 =head2 SelfLoaded methods
164
165 Those methods which override default MM_Unix methods are marked
166 "(override)", while methods unique to MM_VMS are marked "(specific)".
167 For overridden methods, documentation is limited to an explanation
168 of why this method overrides the MM_Unix method; see the ExtUtils::MM_Unix
169 documentation for more details.
170
171 =over
172
173 =item guess_name (override)
174
175 Try to determine name of extension being built.  We begin with the name
176 of the current directory.  Since VMS filenames are case-insensitive,
177 however, we look for a F<.pm> file whose name matches that of the current
178 directory (presumably the 'main' F<.pm> file for this extension), and try
179 to find a C<package> statement from which to obtain the Mixed::Case
180 package name.
181
182 =cut
183
184 sub guess_name {
185     my($self) = @_;
186     my($defname,$defpm,@pm,%xs,$pm);
187     local *PM;
188
189     $defname = basename(fileify($ENV{'DEFAULT'}));
190     $defname =~ s![\d\-_]*\.dir.*$!!;  # Clip off .dir;1 suffix, and package version
191     $defpm = $defname;
192     # Fallback in case for some reason a user has copied the files for an
193     # extension into a working directory whose name doesn't reflect the
194     # extension's name.  We'll use the name of a unique .pm file, or the
195     # first .pm file with a matching .xs file.
196     if (not -e "${defpm}.pm") {
197       @pm = map { s/.pm$//; $_ } glob('*.pm');
198       if (@pm == 1) { ($defpm = $pm[0]) =~ s/.pm$//; }
199       elsif (@pm) {
200         %xs = map { s/.xs$//; ($_,1) } glob('*.xs');
201         if (%xs) { foreach $pm (@pm) { $defpm = $pm, last if exists $xs{$pm}; } }
202       }
203     }
204     if (open(PM,"${defpm}.pm")){
205         while (<PM>) {
206             if (/^\s*package\s+([^;]+)/i) {
207                 $defname = $1;
208                 last;
209             }
210         }
211         print STDOUT "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t",
212                      "defaulting package name to $defname\n"
213             if eof(PM);
214         close PM;
215     }
216     else {
217         print STDOUT "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t",
218                      "defaulting package name to $defname\n";
219     }
220     $defname =~ s#[\d.\-_]+$##;
221     $defname;
222 }
223
224 =item find_perl (override)
225
226 Use VMS file specification syntax and CLI commands to find and
227 invoke Perl images.
228
229 =cut
230
231 sub find_perl {
232     my($self, $ver, $names, $dirs, $trace) = @_;
233     my($name,$dir,$vmsfile,@sdirs,@snames,@cand);
234     my($inabs) = 0;
235     # Check in relative directories first, so we pick up the current
236     # version of Perl if we're running MakeMaker as part of the main build.
237     @sdirs = sort { my($absa) = $self->file_name_is_absolute($a);
238                     my($absb) = $self->file_name_is_absolute($b);
239                     if ($absa && $absb) { return $a cmp $b }
240                     else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); }
241                   } @$dirs;
242     # Check miniperl before perl, and check names likely to contain
243     # version numbers before "generic" names, so we pick up an
244     # executable that's less likely to be from an old installation.
245     @snames = sort { my($ba) = $a =~ m!([^:>\]/]+)$!;  # basename
246                      my($bb) = $b =~ m!([^:>\]/]+)$!;
247                      my($ahasdir) = (length($a) - length($ba) > 0);
248                      my($bhasdir) = (length($b) - length($bb) > 0);
249                      if    ($ahasdir and not $bhasdir) { return 1; }
250                      elsif ($bhasdir and not $ahasdir) { return -1; }
251                      else { $bb =~ /\d/ <=> $ba =~ /\d/
252                             or substr($ba,0,1) cmp substr($bb,0,1)
253                             or length($bb) <=> length($ba) } } @$names;
254     # Image names containing Perl version use '_' instead of '.' under VMS
255     foreach $name (@snames) { $name =~ s/\.(\d+)$/_$1/; }
256     if ($trace >= 2){
257         print "Looking for perl $ver by these names:\n";
258         print "\t@snames,\n";
259         print "in these dirs:\n";
260         print "\t@sdirs\n";
261     }
262     foreach $dir (@sdirs){
263         next unless defined $dir; # $self->{PERL_SRC} may be undefined
264         $inabs++ if $self->file_name_is_absolute($dir);
265         if ($inabs == 1) {
266             # We've covered relative dirs; everything else is an absolute
267             # dir (probably an installed location).  First, we'll try potential
268             # command names, to see whether we can avoid a long MCR expression.
269             foreach $name (@snames) { push(@cand,$name) if $name =~ /^[\w\-\$]+$/; }
270             $inabs++; # Should happen above in next $dir, but just in case . . .
271         }
272         foreach $name (@snames){
273             if ($name !~ m![/:>\]]!) { push(@cand,$self->catfile($dir,$name)); }
274             else                     { push(@cand,$self->fixpath($name,0));    }
275         }
276     }
277     foreach $name (@cand) {
278         print "Checking $name\n" if ($trace >= 2);
279         # If it looks like a potential command, try it without the MCR
280         if ($name =~ /^[\w\-\$]+$/ &&
281             `$name -e "require $ver; print ""VER_OK\n"""` =~ /VER_OK/) {
282             print "Using PERL=$name\n" if $trace;
283             return $name;
284         }
285         next unless $vmsfile = $self->maybe_command($name);
286         $vmsfile =~ s/;[\d\-]*$//;  # Clip off version number; we can use a newer version as well
287         print "Executing $vmsfile\n" if ($trace >= 2);
288         if (`MCR $vmsfile -e "require $ver; print ""VER_OK\n"""` =~ /VER_OK/) {
289             print "Using PERL=MCR $vmsfile\n" if $trace;
290             return "MCR $vmsfile";
291         }
292     }
293     print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
294     0; # false and not empty
295 }
296
297 =item path (override)
298
299 Translate logical name DCL$PATH as a searchlist, rather than trying
300 to C<split> string value of C<$ENV{'PATH'}>.
301
302 =cut
303
304 sub path {
305     my(@dirs,$dir,$i);
306     while ($dir = $ENV{'DCL$PATH;' . $i++}) { push(@dirs,$dir); }
307     @dirs;
308 }
309
310 =item maybe_command (override)
311
312 Follows VMS naming conventions for executable files.
313 If the name passed in doesn't exactly match an executable file,
314 appends F<.Exe> (or equivalent) to check for executable image, and F<.Com>
315 to check for DCL procedure.  If this fails, checks directories in DCL$PATH
316 and finally F<Sys$System:> for an executable file having the name specified,
317 with or without the F<.Exe>-equivalent suffix.
318
319 =cut
320
321 sub maybe_command {
322     my($self,$file) = @_;
323     return $file if -x $file && ! -d _;
324     my(@dirs) = ('');
325     my(@exts) = ('',$Config{'exe_ext'},'.exe','.com');
326     my($dir,$ext);
327     if ($file !~ m![/:>\]]!) {
328         for (my $i = 0; defined $ENV{"DCL\$PATH;$i"}; $i++) {
329             $dir = $ENV{"DCL\$PATH;$i"};
330             $dir .= ':' unless $dir =~ m%[\]:]$%;
331             push(@dirs,$dir);
332         }
333         push(@dirs,'Sys$System:');
334         foreach $dir (@dirs) {
335             my $sysfile = "$dir$file";
336             foreach $ext (@exts) {
337                 return $file if -x "$sysfile$ext" && ! -d _;
338             }
339         }
340     }
341     return 0;
342 }
343
344 =item maybe_command_in_dirs (override)
345
346 Uses DCL argument quoting on test command line.
347
348 =cut
349
350 sub maybe_command_in_dirs {     # $ver is optional argument if looking for perl
351     my($self, $names, $dirs, $trace, $ver) = @_;
352     my($name, $dir);
353     foreach $dir (@$dirs){
354         next unless defined $dir; # $self->{PERL_SRC} may be undefined
355         foreach $name (@$names){
356             my($abs,$tryabs);
357             if ($self->file_name_is_absolute($name)) {
358                 $abs = $name;
359             } else {
360                 $abs = $self->catfile($dir, $name);
361             }
362             print "Checking $abs for $name\n" if ($trace >= 2);
363             next unless $tryabs = $self->maybe_command($abs);
364             print "Substituting $tryabs instead of $abs\n" 
365                 if ($trace >= 2 and $tryabs ne $abs);
366             $abs = $tryabs;
367             if (defined $ver) {
368                 print "Executing $abs\n" if ($trace >= 2);
369                 if (`$abs -e 'require $ver; print "VER_OK\n" ' 2>&1` =~ /VER_OK/) {
370                     print "Using $abs\n" if $trace;
371                     return $abs;
372                 }
373             } else { # Do not look for perl
374                 return $abs;
375             }
376         }
377     }
378 }
379
380 =item perl_script (override)
381
382 If name passed in doesn't specify a readable file, appends F<.com> or
383 F<.pl> and tries again, since it's customary to have file types on all files
384 under VMS.
385
386 =cut
387
388 sub perl_script {
389     my($self,$file) = @_;
390     return $file if -r $file && ! -d _;
391     return "$file.com" if -r "$file.com";
392     return "$file.pl" if -r "$file.pl";
393     return '';
394 }
395
396 =item file_name_is_absolute (override)
397
398 Checks for VMS directory spec as well as Unix separators.
399
400 =cut
401
402 sub file_name_is_absolute {
403     my($self,$file) = @_;
404     # If it's a logical name, expand it.
405     $file = $ENV{$file} while $file =~ /^[\w\$\-]+$/ and $ENV{$file};
406     $file =~ m!^/! or $file =~ m![<\[][^.\-\]>]! or $file =~ /:[^<\[]/;
407 }
408
409 =item replace_manpage_separator
410
411 Use as separator a character which is legal in a VMS-syntax file name.
412
413 =cut
414
415 sub replace_manpage_separator {
416     my($self,$man) = @_;
417     $man = unixify($man);
418     $man =~ s#/+#__#g;
419     $man;
420 }
421
422 =item init_others (override)
423
424 Provide VMS-specific forms of various utility commands, then hand
425 off to the default MM_Unix method.
426
427 =cut
428
429 sub init_others {
430     my($self) = @_;
431
432     $self->{NOOP} = 'Continue';
433     $self->{FIRST_MAKEFILE} ||= 'Descrip.MMS';
434     $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS';
435     $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE};
436     $self->{NOECHO} ||= '@ ';
437     $self->{RM_F} = '$(PERL) -e "foreach (@ARGV) { 1 while ( -d $_ ? rmdir $_ : unlink $_)}"';
438     $self->{RM_RF} = '$(PERL) "-I$(PERL_LIB)" -e "use File::Path; @dirs = map(VMS::Filespec::unixify($_),@ARGV); rmtree(\@dirs,0,0)"';
439     $self->{TOUCH} = '$(PERL) -e "$t=time; foreach (@ARGV) { -e $_ ? utime($t,$t,@ARGV) : (open(F,qq(>$_)),close F)}"';
440     $self->{CHMOD} = '$(PERL) -e "chmod @ARGV"';  # expect Unix syntax from MakeMaker
441     $self->{CP} = 'Copy/NoConfirm';
442     $self->{MV} = 'Rename/NoConfirm';
443     $self->{UMASK_NULL} = '! ';  
444     &ExtUtils::MM_Unix::init_others;
445 }
446
447 =item constants (override)
448
449 Fixes up numerous file and directory macros to insure VMS syntax
450 regardless of input syntax.  Also adds a few VMS-specific macros
451 and makes lists of files comma-separated.
452
453 =cut
454
455 sub constants {
456     my($self) = @_;
457     my(@m,$def,$macro);
458
459     # Be kind about case for pollution
460     for (@ARGV) { $_ = uc($_) if /POLLUTE/i; }
461
462     if ($self->{DEFINE} ne '') {
463         my(@terms) = split(/\s+/,$self->{DEFINE});
464         my(@defs,@udefs);
465         foreach $def (@terms) {
466             next unless $def;
467             my $targ = \@defs;
468             if ($def =~ s/^-([DU])//) {       # If it was a Unix-style definition
469                 if ($1 eq 'U') { $targ = \@udefs; }
470                 $def =~ s/='(.*)'$/=$1/;  # then remove shell-protection ''
471                 $def =~ s/^'(.*)'$/$1/;   # from entire term or argument
472             }
473             if ($def =~ /=/) {
474                 $def =~ s/"/""/g;  # Protect existing " from DCL
475                 $def = qq["$def"]; # and quote to prevent parsing of =
476             }
477             push @$targ, $def;
478         }
479         $self->{DEFINE} = '';
480         if (@defs)  { $self->{DEFINE}  = '/Define=(' . join(',',@defs)  . ')'; }
481         if (@udefs) { $self->{DEFINE} .= '/Undef=('  . join(',',@udefs) . ')'; }
482     }
483
484     if ($self->{OBJECT} =~ /\s/) {
485         $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g;
486         $self->{OBJECT} = $self->wraplist(map($self->fixpath($_,0),split(/,?\s+/,$self->{OBJECT})));
487     }
488     $self->{LDFROM} = $self->wraplist(map($self->fixpath($_,0),split(/,?\s+/,$self->{LDFROM})));
489
490
491     # Fix up directory specs
492     $self->{ROOTEXT} = $self->{ROOTEXT} ? $self->fixpath($self->{ROOTEXT},1)
493                                         : '[]';
494     foreach $macro ( qw [
495             INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB INST_EXE INSTALLPRIVLIB
496             INSTALLARCHLIB INSTALLSCRIPT INSTALLBIN PERL_LIB PERL_ARCHLIB
497             PERL_INC PERL_SRC FULLEXT INST_MAN1DIR INSTALLMAN1DIR
498             INST_MAN3DIR INSTALLMAN3DIR INSTALLSITELIB INSTALLSITEARCH
499             SITELIBEXP SITEARCHEXP ] ) {
500         next unless defined $self->{$macro};
501         $self->{$macro} = $self->fixpath($self->{$macro},1);
502     }
503     $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC},q(VMS))
504         if ($self->{PERL_SRC});
505                         
506
507
508     # Fix up file specs
509     foreach $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKE_APERL_FILE MYEXTLIB] ) {
510         next unless defined $self->{$macro};
511         $self->{$macro} = $self->fixpath($self->{$macro},0);
512     }
513
514     foreach $macro (qw/
515               AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION
516               INST_BIN INST_EXE INST_LIB INST_ARCHLIB INST_SCRIPT PREFIX
517               INSTALLDIRS INSTALLPRIVLIB  INSTALLARCHLIB INSTALLSITELIB
518               INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB
519               PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB
520               FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC PERL_VMS
521               PERL_INC PERL FULLPERL
522               / ) {
523         next unless defined $self->{$macro};
524         push @m, "$macro = $self->{$macro}\n";
525     }
526
527
528     push @m, q[
529 VERSION_MACRO = VERSION
530 DEFINE_VERSION = "$(VERSION_MACRO)=""$(VERSION)"""
531 XS_VERSION_MACRO = XS_VERSION
532 XS_DEFINE_VERSION = "$(XS_VERSION_MACRO)=""$(XS_VERSION)"""
533
534 MAKEMAKER = ],$self->catfile($self->{PERL_LIB},'ExtUtils','MakeMaker.pm'),qq[
535 MM_VERSION = $ExtUtils::MakeMaker::VERSION
536 MM_REVISION = $ExtUtils::MakeMaker::Revision
537 MM_VMS_REVISION = $ExtUtils::MM_VMS::Revision
538
539 # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
540 # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
541 # PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
542 # DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
543 ];
544
545     for $tmp (qw/
546               FULLEXT VERSION_FROM OBJECT LDFROM
547               / ) {
548         next unless defined $self->{$tmp};
549         push @m, "$tmp = ",$self->fixpath($self->{$tmp},0),"\n";
550     }
551
552     for $tmp (qw/
553               BASEEXT PARENT_NAME DLBASE INC DEFINE LINKTYPE
554               / ) {
555         next unless defined $self->{$tmp};
556         push @m, "$tmp = $self->{$tmp}\n";
557     }
558
559     for $tmp (qw/ XS MAN1PODS MAN3PODS PM /) {
560         next unless defined $self->{$tmp};
561         my(%tmp,$key);
562         for $key (keys %{$self->{$tmp}}) {
563             $tmp{$self->fixpath($key,0)} = $self->fixpath($self->{$tmp}{$key},0);
564         }
565         $self->{$tmp} = \%tmp;
566     }
567
568     for $tmp (qw/ C O_FILES H /) {
569         next unless defined $self->{$tmp};
570         my(@tmp,$val);
571         for $val (@{$self->{$tmp}}) {
572             push(@tmp,$self->fixpath($val,0));
573         }
574         $self->{$tmp} = \@tmp;
575     }
576
577     push @m,'
578
579 # Handy lists of source code files:
580 XS_FILES = ',$self->wraplist(sort keys %{$self->{XS}}),'
581 C_FILES  = ',$self->wraplist(@{$self->{C}}),'
582 O_FILES  = ',$self->wraplist(@{$self->{O_FILES}} ),'
583 H_FILES  = ',$self->wraplist(@{$self->{H}}),'
584 MAN1PODS = ',$self->wraplist(sort keys %{$self->{MAN1PODS}}),'
585 MAN3PODS = ',$self->wraplist(sort keys %{$self->{MAN3PODS}}),'
586
587 ';
588
589     for $tmp (qw/
590               INST_MAN1DIR INSTALLMAN1DIR MAN1EXT INST_MAN3DIR INSTALLMAN3DIR MAN3EXT
591               /) {
592         next unless defined $self->{$tmp};
593         push @m, "$tmp = $self->{$tmp}\n";
594     }
595
596 push @m,"
597 .SUFFIXES :
598 .SUFFIXES : \$(OBJ_EXT) .c .cpp .cxx .xs
599
600 # Here is the Config.pm that we are using/depend on
601 CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM)
602
603 # Where to put things:
604 INST_LIBDIR      = $self->{INST_LIBDIR}
605 INST_ARCHLIBDIR  = $self->{INST_ARCHLIBDIR}
606
607 INST_AUTODIR     = $self->{INST_AUTODIR}
608 INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR}
609 ";
610
611     if ($self->has_link_code()) {
612         push @m,'
613 INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT)$(LIB_EXT)
614 INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT)
615 INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs
616 ';
617     } else {
618         my $shr = $Config{'dbgprefix'} . 'PERLSHR';
619         push @m,'
620 INST_STATIC =
621 INST_DYNAMIC =
622 INST_BOOT =
623 EXPORT_LIST = $(BASEEXT).opt
624 PERL_ARCHIVE = ',($ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}"),'
625 ';
626     }
627
628     $self->{TO_INST_PM} = [ sort keys %{$self->{PM}} ];
629     $self->{PM_TO_BLIB} = [ %{$self->{PM}} ];
630     push @m,'
631 TO_INST_PM = ',$self->wraplist(@{$self->{TO_INST_PM}}),'
632
633 PM_TO_BLIB = ',$self->wraplist(@{$self->{PM_TO_BLIB}}),'
634 ';
635
636     join('',@m);
637 }
638
639 =item cflags (override)
640
641 Bypass shell script and produce qualifiers for CC directly (but warn
642 user if a shell script for this extension exists).  Fold multiple
643 /Defines into one, since some C compilers pay attention to only one
644 instance of this qualifier on the command line.
645
646 =cut
647
648 sub cflags {
649     my($self,$libperl) = @_;
650     my($quals) = $self->{CCFLAGS} || $Config{'ccflags'};
651     my($definestr,$undefstr,$flagoptstr) = ('','','');
652     my($incstr) = '/Include=($(PERL_INC)';
653     my($name,$sys,@m);
654
655     ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
656     print STDOUT "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
657          " required to modify CC command for $self->{'BASEEXT'}\n"
658     if ($Config{$name});
659
660     if ($quals =~ / -[DIUOg]/) {
661         while ($quals =~ / -([Og])(\d*)\b/) {
662             my($type,$lvl) = ($1,$2);
663             $quals =~ s/ -$type$lvl\b\s*//;
664             if ($type eq 'g') { $flagoptstr = '/NoOptimize'; }
665             else { $flagoptstr = '/Optimize' . (defined($lvl) ? "=$lvl" : ''); }
666         }
667         while ($quals =~ / -([DIU])(\S+)/) {
668             my($type,$def) = ($1,$2);
669             $quals =~ s/ -$type$def\s*//;
670             $def =~ s/"/""/g;
671             if    ($type eq 'D') { $definestr .= qq["$def",]; }
672             elsif ($type eq 'I') { $incstr .= ',' . $self->fixpath($def,1); }
673             else                 { $undefstr  .= qq["$def",]; }
674         }
675     }
676     if (length $quals and $quals !~ m!/!) {
677         warn "MM_VMS: Ignoring unrecognized CCFLAGS elements \"$quals\"\n";
678         $quals = '';
679     }
680     $definestr .= q["PERL_POLLUTE",] if $self->{POLLUTE};
681     if (length $definestr) { chop($definestr); $quals .= "/Define=($definestr)"; }
682     if (length $undefstr)  { chop($undefstr);  $quals .= "/Undef=($undefstr)";   }
683     # Deal with $self->{DEFINE} here since some C compilers pay attention
684     # to only one /Define clause on command line, so we have to
685     # conflate the ones from $Config{'ccflags'} and $self->{DEFINE}
686     # ($self->{DEFINE} has already been VMSified in constants() above)
687     if ($self->{DEFINE}) { $quals .= $self->{DEFINE}; }
688     for $type (qw(Def Undef)) {
689         my(@terms);
690         while ($quals =~ m:/${type}i?n?e?=([^/]+):ig) {
691                 my $term = $1;
692                 $term =~ s:^\((.+)\)$:$1:;
693                 push @terms, $term;
694             }
695         if ($type eq 'Def') {
696             push @terms, qw[ $(DEFINE_VERSION) $(XS_DEFINE_VERSION) ];
697         }
698         if (@terms) {
699             $quals =~ s:/${type}i?n?e?=[^/]+::ig;
700             $quals .= "/${type}ine=(" . join(',',@terms) . ')';
701         }
702     }
703
704     $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
705
706     # Likewise with $self->{INC} and /Include
707     if ($self->{'INC'}) {
708         my(@includes) = split(/\s+/,$self->{INC});
709         foreach (@includes) {
710             s/^-I//;
711             $incstr .= ','.$self->fixpath($_,1);
712         }
713     }
714     $quals .= "$incstr)";
715 #    $quals =~ s/,,/,/g; $quals =~ s/\(,/(/g;
716     $self->{CCFLAGS} = $quals;
717
718     $self->{OPTIMIZE} ||= $flagoptstr || $Config{'optimize'};
719     if ($self->{OPTIMIZE} !~ m!/!) {
720         if    ($self->{OPTIMIZE} =~ m!\b-g\b!) { $self->{OPTIMIZE} = '/Debug/NoOptimize' }
721         elsif ($self->{OPTIMIZE} =~ /-O(\d*)/) {
722             $self->{OPTIMIZE} = '/Optimize' . (defined($1) ? "=$1" : '');
723         }
724         else {
725             warn "MM_VMS: Can't parse OPTIMIZE \"$self->{OPTIMIZE}\"; using default\n" if length $self->{OPTIMIZE};
726             $self->{OPTIMIZE} = '/Optimize';
727         }
728     }
729
730     return $self->{CFLAGS} = qq{
731 CCFLAGS = $self->{CCFLAGS}
732 OPTIMIZE = $self->{OPTIMIZE}
733 PERLTYPE = $self->{PERLTYPE}
734 SPLIT =
735 LARGE =
736 };
737 }
738
739 =item const_cccmd (override)
740
741 Adds directives to point C preprocessor to the right place when
742 handling #include E<lt>sys/foo.hE<gt> directives.  Also constructs CC
743 command line a bit differently than MM_Unix method.
744
745 =cut
746
747 sub const_cccmd {
748     my($self,$libperl) = @_;
749     my(@m);
750
751     return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
752     return '' unless $self->needs_linking();
753     if ($Config{'vms_cc_type'} eq 'gcc') {
754         push @m,'
755 .FIRST
756         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
757     }
758     elsif ($Config{'vms_cc_type'} eq 'vaxc') {
759         push @m,'
760 .FIRST
761         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
762         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
763     }
764     else {
765         push @m,'
766 .FIRST
767         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
768                 ($Config{'arch'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
769         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
770     }
771
772     push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
773
774     $self->{CONST_CCCMD} = join('',@m);
775 }
776
777 =item pm_to_blib (override)
778
779 DCL I<still> accepts a maximum of 255 characters on a command
780 line, so we write the (potentially) long list of file names
781 to a temp file, then persuade Perl to read it instead of the
782 command line to find args.
783
784 =cut
785
786 sub pm_to_blib {
787     my($self) = @_;
788     my($line,$from,$to,@m);
789     my($autodir) = $self->catdir('$(INST_LIB)','auto');
790     my(@files) = @{$self->{PM_TO_BLIB}};
791
792     push @m, q{
793
794 # Dummy target to match Unix target name; we use pm_to_blib.ts as
795 # timestamp file to avoid repeated invocations under VMS
796 pm_to_blib : pm_to_blib.ts
797         $(NOECHO) $(NOOP)
798
799 # As always, keep under DCL's 255-char limit
800 pm_to_blib.ts : $(TO_INST_PM)
801         $(NOECHO) $(PERL) -e "print '},shift(@files),q{ },shift(@files),q{'" >.MM_tmp
802 };
803
804     $line = '';  # avoid uninitialized var warning
805     while ($from = shift(@files),$to = shift(@files)) {
806         $line .= " $from $to";
807         if (length($line) > 128) {
808             push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n");
809             $line = '';
810         }
811     }
812     push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n") if $line;
813
814     push(@m,q[  $(PERL) "-I$(PERL_LIB)" "-MExtUtils::Install" -e "pm_to_blib({split(' ',<STDIN>)},'].$autodir.q[')" <.MM_tmp]);
815     push(@m,qq[
816         \$(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
817         \$(NOECHO) \$(TOUCH) pm_to_blib.ts
818 ]);
819
820     join('',@m);
821 }
822
823 =item tool_autosplit (override)
824
825 Use VMS-style quoting on command line.
826
827 =cut
828
829 sub tool_autosplit{
830     my($self, %attribs) = @_;
831     my($asl) = "";
832     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
833     q{
834 # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
835 AUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;"
836 };
837 }
838
839 =item tool_sxubpp (override)
840
841 Use VMS-style quoting on xsubpp command line.
842
843 =cut
844
845 sub tool_xsubpp {
846     my($self) = @_;
847     return '' unless $self->needs_linking;
848     my($xsdir) = $self->catdir($self->{PERL_LIB},'ExtUtils');
849     # drop back to old location if xsubpp is not in new location yet
850     $xsdir = $self->catdir($self->{PERL_SRC},'ext') unless (-f $self->catfile($xsdir,'xsubpp'));
851     my(@tmdeps) = '$(XSUBPPDIR)typemap';
852     if( $self->{TYPEMAPS} ){
853         my $typemap;
854         foreach $typemap (@{$self->{TYPEMAPS}}){
855                 if( ! -f  $typemap ){
856                         warn "Typemap $typemap not found.\n";
857                 }
858                 else{
859                         push(@tmdeps, $self->fixpath($typemap,0));
860                 }
861         }
862     }
863     push(@tmdeps, "typemap") if -f "typemap";
864     my(@tmargs) = map("-typemap $_", @tmdeps);
865     if( exists $self->{XSOPT} ){
866         unshift( @tmargs, $self->{XSOPT} );
867     }
868
869     my $xsubpp_version = $self->xsubpp_version($self->catfile($xsdir,'xsubpp'));
870
871     # What are the correct thresholds for version 1 && 2 Paul?
872     if ( $xsubpp_version > 1.923 ){
873         $self->{XSPROTOARG} = '' unless defined $self->{XSPROTOARG};
874     } else {
875         if (defined $self->{XSPROTOARG} && $self->{XSPROTOARG} =~ /\-prototypes/) {
876             print STDOUT qq{Warning: This extension wants to pass the switch "-prototypes" to xsubpp.
877         Your version of xsubpp is $xsubpp_version and cannot handle this.
878         Please upgrade to a more recent version of xsubpp.
879 };
880         } else {
881             $self->{XSPROTOARG} = "";
882         }
883     }
884
885     "
886 XSUBPPDIR = $xsdir
887 XSUBPP = \$(PERL) \"-I\$(PERL_ARCHLIB)\" \"-I\$(PERL_LIB)\" \$(XSUBPPDIR)xsubpp
888 XSPROTOARG = $self->{XSPROTOARG}
889 XSUBPPDEPS = @tmdeps
890 XSUBPPARGS = @tmargs
891 ";
892 }
893
894 =item xsubpp_version (override)
895
896 Test xsubpp exit status according to VMS rules ($sts & 1 ==E<gt> good)
897 rather than Unix rules ($sts == 0 ==E<gt> good).
898
899 =cut
900
901 sub xsubpp_version
902 {
903     my($self,$xsubpp) = @_;
904     my ($version) ;
905     return '' unless $self->needs_linking;
906
907     # try to figure out the version number of the xsubpp on the system
908
909     # first try the -v flag, introduced in 1.921 & 2.000a2
910
911     my $command = "$self->{PERL} \"-I$self->{PERL_LIB}\" $xsubpp -v";
912     print "Running: $command\n" if $Verbose;
913     $version = `$command` ;
914     if ($?) {
915         use vmsish 'status';
916         warn "Running '$command' exits with status $?";
917     }
918     chop $version ;
919
920     return $1 if $version =~ /^xsubpp version (.*)/ ;
921
922     # nope, then try something else
923
924     my $counter = '000';
925     my ($file) = 'temp' ;
926     $counter++ while -e "$file$counter"; # don't overwrite anything
927     $file .= $counter;
928
929     local(*F);
930     open(F, ">$file") or die "Cannot open file '$file': $!\n" ;
931     print F <<EOM ;
932 MODULE = fred PACKAGE = fred
933
934 int
935 fred(a)
936         int     a;
937 EOM
938
939     close F ;
940
941     $command = "$self->{PERL} $xsubpp $file";
942     print "Running: $command\n" if $Verbose;
943     my $text = `$command` ;
944     if ($?) {
945         use vmsish 'status';
946         warn "Running '$command' exits with status $?";
947     }
948     unlink $file ;
949
950     # gets 1.2 -> 1.92 and 2.000a1
951     return $1 if $text =~ /automatically by xsubpp version ([\S]+)\s*/  ;
952
953     # it is either 1.0 or 1.1
954     return 1.1 if $text =~ /^Warning: ignored semicolon/ ;
955
956     # none of the above, so 1.0
957     return "1.0" ;
958 }
959
960 =item tools_other (override)
961
962 Adds a few MM[SK] macros, and shortens some the installatin commands,
963 in order to stay under DCL's 255-character limit.  Also changes
964 EQUALIZE_TIMESTAMP to set revision date of target file to one second
965 later than source file, since MMK interprets precisely equal revision
966 dates for a source and target file as a sign that the target needs
967 to be updated.
968
969 =cut
970
971 sub tools_other {
972     my($self) = @_;
973     qq!
974 # Assumes \$(MMS) invokes MMS or MMK
975 # (It is assumed in some cases later that the default makefile name
976 # (Descrip.MMS for MM[SK]) is used.)
977 USEMAKEFILE = /Descrip=
978 USEMACROS = /Macro=(
979 MACROEND = )
980 MAKEFILE = Descrip.MMS
981 SHELL = Posix
982 TOUCH = $self->{TOUCH}
983 CHMOD = $self->{CHMOD}
984 CP = $self->{CP}
985 MV = $self->{MV}
986 RM_F  = $self->{RM_F}
987 RM_RF = $self->{RM_RF}
988 SAY = Write Sys\$Output
989 UMASK_NULL = $self->{UMASK_NULL}
990 NOOP = $self->{NOOP}
991 NOECHO = $self->{NOECHO}
992 MKPATH = Create/Directory
993 EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])"
994 !. ($self->{PARENT} ? '' : 
995 qq!WARN_IF_OLD_PACKLIST = \$(PERL) -e "if (-f \$ARGV[0]){print qq[WARNING: Old package found (\$ARGV[0]); please check for collisions\\n]}"
996 MOD_INSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "install({split(' ',<STDIN>)},1);"
997 DOC_INSTALL = \$(PERL) -e "\@ARGV=split(/\\|/,<STDIN>);print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];while(\$key=shift && \$val=shift){print qq[=item *\\n\\nC<\$key: \$val>\\n\\n];}print qq[=back\\n\\n]"
998 UNINSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "uninstall(\$ARGV[0],1,1);"
999 !);
1000 }
1001
1002 =item dist (override)
1003
1004 Provide VMSish defaults for some values, then hand off to
1005 default MM_Unix method.
1006
1007 =cut
1008
1009 sub dist {
1010     my($self, %attribs) = @_;
1011     $attribs{VERSION}      ||= $self->{VERSION_SYM};
1012     $attribs{NAME}         ||= $self->{DISTNAME};
1013     $attribs{ZIPFLAGS}     ||= '-Vu';
1014     $attribs{COMPRESS}     ||= 'gzip';
1015     $attribs{SUFFIX}       ||= '-gz';
1016     $attribs{SHAR}         ||= 'vms_share';
1017     $attribs{DIST_DEFAULT} ||= 'zipdist';
1018
1019     # Sanitize these for use in $(DISTVNAME) filespec
1020     $attribs{VERSION} =~ s/[^\w\$]/_/g;
1021     $attribs{NAME} =~ s/[^\w\$]/_/g;
1022
1023     return ExtUtils::MM_Unix::dist($self,%attribs);
1024 }
1025
1026 =item c_o (override)
1027
1028 Use VMS syntax on command line.  In particular, $(DEFINE) and
1029 $(PERL_INC) have been pulled into $(CCCMD).  Also use MM[SK] macros.
1030
1031 =cut
1032
1033 sub c_o {
1034     my($self) = @_;
1035     return '' unless $self->needs_linking();
1036     '
1037 .c$(OBJ_EXT) :
1038         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1039
1040 .cpp$(OBJ_EXT) :
1041         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp
1042
1043 .cxx$(OBJ_EXT) :
1044         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx
1045
1046 ';
1047 }
1048
1049 =item xs_c (override)
1050
1051 Use MM[SK] macros.
1052
1053 =cut
1054
1055 sub xs_c {
1056     my($self) = @_;
1057     return '' unless $self->needs_linking();
1058     '
1059 .xs.c :
1060         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
1061 ';
1062 }
1063
1064 =item xs_o (override)
1065
1066 Use MM[SK] macros, and VMS command line for C compiler.
1067
1068 =cut
1069
1070 sub xs_o {      # many makes are too dumb to use xs_c then c_o
1071     my($self) = @_;
1072     return '' unless $self->needs_linking();
1073     '
1074 .xs$(OBJ_EXT) :
1075         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
1076         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1077 ';
1078 }
1079
1080 =item top_targets (override)
1081
1082 Use VMS quoting on command line for Version_check.
1083
1084 =cut
1085
1086 sub top_targets {
1087     my($self) = shift;
1088     my(@m);
1089     push @m, '
1090 all :: pure_all manifypods
1091         $(NOECHO) $(NOOP)
1092
1093 pure_all :: config pm_to_blib subdirs linkext
1094         $(NOECHO) $(NOOP)
1095
1096 subdirs :: $(MYEXTLIB)
1097         $(NOECHO) $(NOOP)
1098
1099 config :: $(MAKEFILE) $(INST_LIBDIR).exists
1100         $(NOECHO) $(NOOP)
1101
1102 config :: $(INST_ARCHAUTODIR).exists
1103         $(NOECHO) $(NOOP)
1104
1105 config :: $(INST_AUTODIR).exists
1106         $(NOECHO) $(NOOP)
1107 ';
1108
1109     push @m, q{
1110 config :: Version_check
1111         $(NOECHO) $(NOOP)
1112
1113 } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC};
1114
1115
1116     push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
1117     if (%{$self->{MAN1PODS}}) {
1118         push @m, q[
1119 config :: $(INST_MAN1DIR).exists
1120         $(NOECHO) $(NOOP)
1121 ];
1122         push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
1123     }
1124     if (%{$self->{MAN3PODS}}) {
1125         push @m, q[
1126 config :: $(INST_MAN3DIR).exists
1127         $(NOECHO) $(NOOP)
1128 ];
1129         push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
1130     }
1131
1132     push @m, '
1133 $(O_FILES) : $(H_FILES)
1134 ' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
1135
1136     push @m, q{
1137 help :
1138         perldoc ExtUtils::MakeMaker
1139 };
1140
1141     push @m, q{
1142 Version_check :
1143         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1144         "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')"
1145 };
1146
1147     join('',@m);
1148 }
1149
1150 =item dlsyms (override)
1151
1152 Create VMS linker options files specifying universal symbols for this
1153 extension's shareable image, and listing other shareable images or 
1154 libraries to which it should be linked.
1155
1156 =cut
1157
1158 sub dlsyms {
1159     my($self,%attribs) = @_;
1160
1161     return '' unless $self->needs_linking();
1162
1163     my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
1164     my($vars)  = $attribs{DL_VARS}  || $self->{DL_VARS}  || [];
1165     my($funclist)  = $attribs{FUNCLIST}  || $self->{FUNCLIST}  || [];
1166     my(@m);
1167
1168     unless ($self->{SKIPHASH}{'dynamic'}) {
1169         push(@m,'
1170 dynamic :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1171         $(NOECHO) $(NOOP)
1172 ');
1173     }
1174
1175     push(@m,'
1176 static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1177         $(NOECHO) $(NOOP)
1178 ') unless $self->{SKIPHASH}{'static'};
1179
1180     push @m,'
1181 $(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt
1182         $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1183
1184 $(BASEEXT).opt : Makefile.PL
1185         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Mksymlists;" -
1186         ',qq[-e "Mksymlists('NAME' => '$self->{NAME}', 'DL_FUNCS' => ],
1187         neatvalue($funcs),q[, 'DL_VARS' => ],neatvalue($vars),
1188         q[, 'FUNCLIST' => ],neatvalue($funclist),qq[)"\n];
1189
1190     push @m, '  $(PERL) -e "print ""$(INST_STATIC)/Include=';
1191     if ($self->{OBJECT} =~ /\bBASEEXT\b/ or
1192         $self->{OBJECT} =~ /\b$self->{BASEEXT}\b/i) { push @m, '$(BASEEXT)'; }
1193     else {  # We don't have a "main" object file, so pull 'em all in
1194         my(@omods) = map { s/\.[^.]*$//;         # Trim off file type
1195                            s[\$\(\w+_EXT\)][];   # even as a macro
1196                            s/.*[:>\/\]]//;       # Trim off dir spec
1197                            $_; } split ' ', $self->eliminate_macros($self->{OBJECT});
1198         my($tmp,@lines,$elt) = '';
1199         my $tmp = shift @omods;
1200         foreach $elt (@omods) {
1201             $tmp .= ",$elt";
1202                 if (length($tmp) > 80) { push @lines, $tmp;  $tmp = ''; }
1203         }
1204         push @lines, $tmp;
1205         push @m, '(', join( qq[, -\\n\\t"";" >>\$(MMS\$TARGET)\n\t\$(PERL) -e "print ""], @lines),')';
1206     }
1207         push @m, '\n$(INST_STATIC)/Library\n"";" >>$(MMS$TARGET)',"\n";
1208
1209     if (length $self->{LDLOADLIBS}) {
1210         my($lib); my($line) = '';
1211         foreach $lib (split ' ', $self->{LDLOADLIBS}) {
1212             $lib =~ s%\$%\\\$%g;  # Escape '$' in VMS filespecs
1213             if (length($line) + length($lib) > 160) {
1214                 push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n";
1215                 $line = $lib . '\n';
1216             }
1217             else { $line .= $lib . '\n'; }
1218         }
1219         push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n" if $line;
1220     }
1221
1222     join('',@m);
1223
1224 }
1225
1226 =item dynamic_lib (override)
1227
1228 Use VMS Link command.
1229
1230 =cut
1231
1232 sub dynamic_lib {
1233     my($self, %attribs) = @_;
1234     return '' unless $self->needs_linking(); #might be because of a subdir
1235
1236     return '' unless $self->has_link_code();
1237
1238     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
1239     my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
1240     my $shr = $Config{'dbgprefix'} . 'PerlShr';
1241     my(@m);
1242     push @m,"
1243
1244 OTHERLDFLAGS = $otherldflags
1245 INST_DYNAMIC_DEP = $inst_dynamic_dep
1246
1247 ";
1248     push @m, '
1249 $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1250         $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
1251         If F$TrnLNm("',$shr,'").eqs."" Then Define/NoLog/User ',"$shr Sys\$Share:$shr.$Config{'dlext'}",'
1252         Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,$(PERL_INC)perlshr_attr.opt/Option
1253 ';
1254
1255     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1256     join('',@m);
1257 }
1258
1259 =item dynamic_bs (override)
1260
1261 Use VMS-style quoting on Mkbootstrap command line.
1262
1263 =cut
1264
1265 sub dynamic_bs {
1266     my($self, %attribs) = @_;
1267     return '
1268 BOOTSTRAP =
1269 ' unless $self->has_link_code();
1270     '
1271 BOOTSTRAP = '."$self->{BASEEXT}.bs".'
1272
1273 # As MakeMaker mkbootstrap might not write a file (if none is required)
1274 # we use touch to prevent make continually trying to remake it.
1275 # The DynaLoader only reads a non-empty file.
1276 $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists
1277         $(NOECHO) $(SAY) "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
1278         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1279         -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
1280         $(NOECHO) $(TOUCH) $(MMS$TARGET)
1281
1282 $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists
1283         $(NOECHO) $(RM_RF) $(INST_BOOT)
1284         - $(CP) $(BOOTSTRAP) $(INST_BOOT)
1285 ';
1286 }
1287
1288 =item static_lib (override)
1289
1290 Use VMS commands to manipulate object library.
1291
1292 =cut
1293
1294 sub static_lib {
1295     my($self) = @_;
1296     return '' unless $self->needs_linking();
1297
1298     return '
1299 $(INST_STATIC) :
1300         $(NOECHO) $(NOOP)
1301 ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB});
1302
1303     my(@m,$lib);
1304     push @m,'
1305 # Rely on suffix rule for update action
1306 $(OBJECT) : $(INST_ARCHAUTODIR).exists
1307
1308 $(INST_STATIC) : $(OBJECT) $(MYEXTLIB)
1309 ';
1310     # If this extension has it's own library (eg SDBM_File)
1311     # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1312     push(@m, "\t",'$(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1313
1314     push(@m,"\t",'If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)',"\n");
1315
1316     # if there was a library to copy, then we can't use MMS$SOURCE_LIST,
1317     # 'cause it's a library and you can't stick them in other libraries.
1318     # In that case, we use $OBJECT instead and hope for the best
1319     if ($self->{MYEXTLIB}) {
1320       push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) $(OBJECT)',"\n"); 
1321     } else {
1322       push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)',"\n");
1323     }
1324     
1325     push @m, "\t\$(NOECHO) \$(PERL) -e 1 >\$(INST_ARCHAUTODIR)extralibs.ld\n";
1326     foreach $lib (split ' ', $self->{EXTRALIBS}) {
1327       push(@m,"\t",'$(NOECHO) $(PERL) -e "print qq{',$lib,'\n}" >>$(INST_ARCHAUTODIR)extralibs.ld',"\n");
1328     }
1329     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1330     join('',@m);
1331 }
1332
1333
1334 =item manifypods (override)
1335
1336 Use VMS-style quoting on command line, and VMS logical name
1337 to specify fallback location at build time if we can't find pod2man.
1338
1339 =cut
1340
1341
1342 sub manifypods {
1343     my($self, %attribs) = @_;
1344     return "\nmanifypods :\n\t\$(NOECHO) \$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}};
1345     my($dist);
1346     my($pod2man_exe);
1347     if (defined $self->{PERL_SRC}) {
1348         $pod2man_exe = $self->catfile($self->{PERL_SRC},'pod','pod2man');
1349     } else {
1350         $pod2man_exe = $self->catfile($Config{scriptdirexp},'pod2man');
1351     }
1352     if (not ($pod2man_exe = $self->perl_script($pod2man_exe))) {
1353         # No pod2man but some MAN3PODS to be installed
1354         print <<END;
1355
1356 Warning: I could not locate your pod2man program.  As a last choice,
1357          I will look for the file to which the logical name POD2MAN
1358          points when MMK is invoked.
1359
1360 END
1361         $pod2man_exe = "pod2man";
1362     }
1363     my(@m);
1364     push @m,
1365 qq[POD2MAN_EXE = $pod2man_exe\n],
1366 q[POD2MAN = $(PERL) -we "%m=@ARGV;for (keys %m){" -
1367 -e "system(""MCR $^X $(POD2MAN_EXE) $_ >$m{$_}"");}"
1368 ];
1369     push @m, "\nmanifypods : \$(MAN1PODS) \$(MAN3PODS)\n";
1370     if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) {
1371         my($pod);
1372         foreach $pod (sort keys %{$self->{MAN1PODS}}) {
1373             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1374             push @m, "$pod $self->{MAN1PODS}{$pod}\n";
1375         }
1376         foreach $pod (sort keys %{$self->{MAN3PODS}}) {
1377             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1378             push @m, "$pod $self->{MAN3PODS}{$pod}\n";
1379         }
1380     }
1381     join('', @m);
1382 }
1383
1384 =item processPL (override)
1385
1386 Use VMS-style quoting on command line.
1387
1388 =cut
1389
1390 sub processPL {
1391     my($self) = @_;
1392     return "" unless $self->{PL_FILES};
1393     my(@m, $plfile);
1394     foreach $plfile (sort keys %{$self->{PL_FILES}}) {
1395         my $list = ref($self->{PL_FILES}->{$plfile})
1396                 ? $self->{PL_FILES}->{$plfile}
1397                 : [$self->{PL_FILES}->{$plfile}];
1398         foreach $target (@$list) {
1399             my $vmsplfile = vmsify($plfile);
1400             my $vmsfile = vmsify($target);
1401             push @m, "
1402 all :: $vmsfile
1403         \$(NOECHO) \$(NOOP)
1404
1405 $vmsfile :: $vmsplfile
1406 ",'     $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $vmsplfile $vmsfile
1407 ";
1408         }
1409     }
1410     join "", @m;
1411 }
1412
1413 =item installbin (override)
1414
1415 Stay under DCL's 255 character command line limit once again by
1416 splitting potentially long list of files across multiple lines
1417 in C<realclean> target.
1418
1419 =cut
1420
1421 sub installbin {
1422     my($self) = @_;
1423     return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
1424     return '' unless @{$self->{EXE_FILES}};
1425     my(@m, $from, $to, %fromto, @to, $line);
1426     my(@exefiles) = map { vmsify($_) } @{$self->{EXE_FILES}};
1427     for $from (@exefiles) {
1428         my($path) = '$(INST_SCRIPT)' . basename($from);
1429         local($_) = $path;  # backward compatibility
1430         $to = $self->libscan($path);
1431         print "libscan($from) => '$to'\n" if ($Verbose >=2);
1432         $fromto{$from} = vmsify($to);
1433     }
1434     @to = values %fromto;
1435     push @m, "
1436 EXE_FILES = @exefiles
1437
1438 all :: @to
1439         \$(NOECHO) \$(NOOP)
1440
1441 realclean ::
1442 ";
1443     $line = '';  #avoid unitialized var warning
1444     foreach $to (@to) {
1445         if (length($line) + length($to) > 80) {
1446             push @m, "\t\$(RM_F) $line\n";
1447             $line = $to;
1448         }
1449         else { $line .= " $to"; }
1450     }
1451     push @m, "\t\$(RM_F) $line\n\n" if $line;
1452
1453     while (($from,$to) = each %fromto) {
1454         last unless defined $from;
1455         my $todir;
1456         if ($to =~ m#[/>:\]]#) { $todir = dirname($to); }
1457         else                   { ($todir = $to) =~ s/[^\)]+$//; }
1458         $todir = $self->fixpath($todir,1);
1459         push @m, "
1460 $to : $from \$(MAKEFILE) ${todir}.exists
1461         \$(CP) $from $to
1462
1463 ", $self->dir_target($todir);
1464     }
1465     join "", @m;
1466 }
1467
1468 =item subdir_x (override)
1469
1470 Use VMS commands to change default directory.
1471
1472 =cut
1473
1474 sub subdir_x {
1475     my($self, $subdir) = @_;
1476     my(@m,$key);
1477     $subdir = $self->fixpath($subdir,1);
1478     push @m, '
1479
1480 subdirs ::
1481         olddef = F$Environment("Default")
1482         Set Default ',$subdir,'
1483         - $(MMS)$(MMSQUALIFIERS) all $(USEMACROS)$(PASTHRU)$(MACROEND)
1484         Set Default \'olddef\'
1485 ';
1486     join('',@m);
1487 }
1488
1489 =item clean (override)
1490
1491 Split potentially long list of files across multiple commands (in
1492 order to stay under the magic command line limit).  Also use MM[SK]
1493 commands for handling subdirectories.
1494
1495 =cut
1496
1497 sub clean {
1498     my($self, %attribs) = @_;
1499     my(@m,$dir);
1500     push @m, '
1501 # Delete temporary files but do not touch installed files. We don\'t delete
1502 # the Descrip.MMS here so that a later make realclean still has it to use.
1503 clean ::
1504 ';
1505     foreach $dir (@{$self->{DIR}}) { # clean subdirectories first
1506         my($vmsdir) = $self->fixpath($dir,1);
1507         push( @m, '     If F$Search("'.$vmsdir.'$(MAKEFILE)").nes."" Then \\',"\n\t",
1508               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS)$(MMSQUALIFIERS) clean`;"',"\n");
1509     }
1510     push @m, '  $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp
1511 ';
1512
1513     my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
1514     # Unlink realclean, $attribs{FILES} is a string here; it may contain
1515     # a list or a macro that expands to a list.
1516     if ($attribs{FILES}) {
1517         my($word,$key,@filist);
1518         if (ref $attribs{FILES} eq 'ARRAY') { @filist = @{$attribs{FILES}}; }
1519         else { @filist = split /\s+/, $attribs{FILES}; }
1520         foreach $word (@filist) {
1521             if (($key) = $word =~ m#^\$\((.*)\)$# and ref $self->{$key} eq 'ARRAY') {
1522                 push(@otherfiles, @{$self->{$key}});
1523             }
1524             else { push(@otherfiles, $word); }
1525         }
1526     }
1527     push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld perlmain.c pm_to_blib.ts ]);
1528     push(@otherfiles,$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'));
1529     my($file,$line);
1530     $line = '';  #avoid unitialized var warning
1531     # Occasionally files are repeated several times from different sources
1532     { my(%of) = map { ($_,1) } @otherfiles; @otherfiles = keys %of; }
1533     
1534     foreach $file (@otherfiles) {
1535         $file = $self->fixpath($file);
1536         if (length($line) + length($file) > 80) {
1537             push @m, "\t\$(RM_RF) $line\n";
1538             $line = "$file";
1539         }
1540         else { $line .= " $file"; }
1541     }
1542     push @m, "\t\$(RM_RF) $line\n" if $line;
1543     push(@m, "  $attribs{POSTOP}\n") if $attribs{POSTOP};
1544     join('', @m);
1545 }
1546
1547 =item realclean (override)
1548
1549 Guess what we're working around?  Also, use MM[SK] for subdirectories.
1550
1551 =cut
1552
1553 sub realclean {
1554     my($self, %attribs) = @_;
1555     my(@m);
1556     push(@m,'
1557 # Delete temporary files (via clean) and also delete installed files
1558 realclean :: clean
1559 ');
1560     foreach(@{$self->{DIR}}){
1561         my($vmsdir) = $self->fixpath($_,1);
1562         push(@m, '      If F$Search("'."$vmsdir".'$(MAKEFILE)").nes."" Then \\',"\n\t",
1563               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS)$(MMSQUALIFIERS) realclean`;"',"\n");
1564     }
1565     push @m,'   $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
1566 ';
1567     # We can't expand several of the MMS macros here, since they don't have
1568     # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a
1569     # combination of macros).  In order to stay below DCL's 255 char limit,
1570     # we put only 2 on a line.
1571     my($file,$line,$fcnt);
1572     my(@files) = qw{ $(MAKEFILE) $(MAKEFILE)_old };
1573     if ($self->has_link_code) {
1574         push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) });
1575     }
1576     push(@files, values %{$self->{PM}});
1577     $line = '';  #avoid unitialized var warning
1578     # Occasionally files are repeated several times from different sources
1579     { my(%f) = map { ($_,1) } @files; @files = keys %f; }
1580     foreach $file (@files) {
1581         $file = $self->fixpath($file);
1582         if (length($line) + length($file) > 80 || ++$fcnt >= 2) {
1583             push @m, "\t\$(RM_F) $line\n";
1584             $line = "$file";
1585             $fcnt = 0;
1586         }
1587         else { $line .= " $file"; }
1588     }
1589     push @m, "\t\$(RM_F) $line\n" if $line;
1590     if ($attribs{FILES}) {
1591         my($word,$key,@filist,@allfiles);
1592         if (ref $attribs{FILES} eq 'ARRAY') { @filist = @{$attribs{FILES}}; }
1593         else { @filist = split /\s+/, $attribs{FILES}; }
1594         foreach $word (@filist) {
1595             if (($key) = $word =~ m#^\$\((.*)\)$# and ref $self->{$key} eq 'ARRAY') {
1596                 push(@allfiles, @{$self->{$key}});
1597             }
1598             else { push(@allfiles, $word); }
1599         }
1600         $line = '';
1601         # Occasionally files are repeated several times from different sources
1602         { my(%af) = map { ($_,1) } @allfiles; @allfiles = keys %af; }
1603         foreach $file (@allfiles) {
1604             $file = $self->fixpath($file);
1605             if (length($line) + length($file) > 80) {
1606                 push @m, "\t\$(RM_RF) $line\n";
1607                 $line = "$file";
1608             }
1609             else { $line .= " $file"; }
1610         }
1611         push @m, "\t\$(RM_RF) $line\n" if $line;
1612     }
1613     push(@m, "  $attribs{POSTOP}\n")                     if $attribs{POSTOP};
1614     join('', @m);
1615 }
1616
1617 =item dist_basics (override)
1618
1619 Use VMS-style quoting on command line.
1620
1621 =cut
1622
1623 sub dist_basics {
1624     my($self) = @_;
1625 '
1626 distclean :: realclean distcheck
1627         $(NOECHO) $(NOOP)
1628
1629 distcheck :
1630         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()"
1631
1632 skipcheck :
1633         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&skipcheck\'; skipcheck()"
1634
1635 manifest :
1636         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&mkmanifest\'; mkmanifest()"
1637 ';
1638 }
1639
1640 =item dist_core (override)
1641
1642 Syntax for invoking F<VMS_Share> differs from that for Unix F<shar>,
1643 so C<shdist> target actions are VMS-specific.
1644
1645 =cut
1646
1647 sub dist_core {
1648     my($self) = @_;
1649 q[
1650 dist : $(DIST_DEFAULT)
1651         $(NOECHO) $(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)')"
1652
1653 zipdist : $(DISTVNAME).zip
1654         $(NOECHO) $(NOOP)
1655
1656 $(DISTVNAME).zip : distdir
1657         $(PREOP)
1658         $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) [.$(DISTVNAME)...]*.*;
1659         $(RM_RF) $(DISTVNAME)
1660         $(POSTOP)
1661
1662 $(DISTVNAME).tar$(SUFFIX) : distdir
1663         $(PREOP)
1664         $(TO_UNIX)
1665         $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar [.$(DISTVNAME)]
1666         $(RM_RF) $(DISTVNAME)
1667         $(COMPRESS) $(DISTVNAME).tar
1668         $(POSTOP)
1669
1670 shdist : distdir
1671         $(PREOP)
1672         $(SHAR) [.$(DISTVNAME...]*.*; $(DISTVNAME).share
1673         $(RM_RF) $(DISTVNAME)
1674         $(POSTOP)
1675 ];
1676 }
1677
1678 =item dist_dir (override)
1679
1680 Use VMS-style quoting on command line.
1681
1682 =cut
1683
1684 sub dist_dir {
1685     my($self) = @_;
1686 q{
1687 distdir :
1688         $(RM_RF) $(DISTVNAME)
1689         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest '/mani/';" \\
1690         -e "manicopy(maniread(),'$(DISTVNAME)','$(DIST_CP)');"
1691 };
1692 }
1693
1694 =item dist_test (override)
1695
1696 Use VMS commands to change default directory, and use VMS-style
1697 quoting on command line.
1698
1699 =cut
1700
1701 sub dist_test {
1702     my($self) = @_;
1703 q{
1704 disttest : distdir
1705         startdir = F$Environment("Default")
1706         Set Default [.$(DISTVNAME)]
1707         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL
1708         $(MMS)$(MMSQUALIFIERS)
1709         $(MMS)$(MMSQUALIFIERS) test
1710         Set Default 'startdir'
1711 };
1712 }
1713
1714 # --- Test and Installation Sections ---
1715
1716 =item install (override)
1717
1718 Work around DCL's 255 character limit several times,and use
1719 VMS-style command line quoting in a few cases.
1720
1721 =cut
1722
1723 sub install {
1724     my($self, %attribs) = @_;
1725     my(@m,@docfiles);
1726
1727     if ($self->{EXE_FILES}) {
1728         my($line,$file) = ('','');
1729         foreach $file (@{$self->{EXE_FILES}}) {
1730             $line .= "$file ";
1731             if (length($line) > 128) {
1732                 push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]);
1733                 $line = '';
1734             }
1735         }
1736         push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]) if $line;
1737     }
1738
1739     push @m, q[
1740 install :: all pure_install doc_install
1741         $(NOECHO) $(NOOP)
1742
1743 install_perl :: all pure_perl_install doc_perl_install
1744         $(NOECHO) $(NOOP)
1745
1746 install_site :: all pure_site_install doc_site_install
1747         $(NOECHO) $(NOOP)
1748
1749 install_ :: install_site
1750         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1751
1752 pure_install :: pure_$(INSTALLDIRS)_install
1753         $(NOECHO) $(NOOP)
1754
1755 doc_install :: doc_$(INSTALLDIRS)_install
1756         $(NOECHO) $(SAY) "Appending installation info to $(INSTALLARCHLIB)perllocal.pod"
1757
1758 pure__install : pure_site_install
1759         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1760
1761 doc__install : doc_site_install
1762         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1763
1764 # This hack brought to you by DCL's 255-character command line limit
1765 pure_perl_install ::
1766         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1767         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1768         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp
1769         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp
1770         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1771         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1772         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1773         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1774         $(MOD_INSTALL) <.MM_tmp
1775         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1776         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[
1777
1778 # Likewise
1779 pure_site_install ::
1780         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1781         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1782         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp
1783         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp
1784         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1785         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1786         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1787         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1788         $(MOD_INSTALL) <.MM_tmp
1789         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1790         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1791
1792 # Ditto
1793 doc_perl_install ::
1794         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp
1795         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES)|'" >>.MM_tmp
1796 ],@docfiles,
1797 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1798         $(NOECHO) $(PERL) -e "print q[print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1799         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1800         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1801         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1802         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1803
1804 # And again
1805 doc_site_install ::
1806         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp
1807         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES)|'" >>.MM_tmp
1808 ],@docfiles,
1809 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1810         $(NOECHO) $(PERL) -e "print q[print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1811         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1812         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1813         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1814         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1815
1816 ];
1817
1818     push @m, q[
1819 uninstall :: uninstall_from_$(INSTALLDIRS)dirs
1820         $(NOECHO) $(NOOP)
1821
1822 uninstall_from_perldirs ::
1823         $(NOECHO) $(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1824         $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes."
1825         $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove"
1826         $(NOECHO) $(SAY) "the appropriate files.  Sorry for the inconvenience."
1827
1828 uninstall_from_sitedirs ::
1829         $(NOECHO) $(UNINSTALL) ],$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist'),"\n",q[
1830         $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes."
1831         $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove"
1832         $(NOECHO) $(SAY) "the appropriate files.  Sorry for the inconvenience."
1833 ];
1834
1835     join('',@m);
1836 }
1837
1838 =item perldepend (override)
1839
1840 Use VMS-style syntax for files; it's cheaper to just do it directly here
1841 than to have the MM_Unix method call C<catfile> repeatedly.  Also, if
1842 we have to rebuild Config.pm, use MM[SK] to do it.
1843
1844 =cut
1845
1846 sub perldepend {
1847     my($self) = @_;
1848     my(@m);
1849
1850     push @m, '
1851 $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
1852 $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
1853 $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
1854 $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
1855 $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
1856 $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
1857 $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
1858 $(OBJECT) : $(PERL_INC)iperlsys.h
1859
1860 ' if $self->{OBJECT}; 
1861
1862     if ($self->{PERL_SRC}) {
1863         my(@macros);
1864         my($mmsquals) = '$(USEMAKEFILE)[.vms]$(MAKEFILE)';
1865         push(@macros,'__AXP__=1') if $Config{'arch'} eq 'VMS_AXP';
1866         push(@macros,'DECC=1')    if $Config{'vms_cc_type'} eq 'decc';
1867         push(@macros,'GNUC=1')    if $Config{'vms_cc_type'} eq 'gcc';
1868         push(@macros,'SOCKET=1')  if $Config{'d_has_sockets'};
1869         push(@macros,qq["CC=$Config{'cc'}"])  if $Config{'cc'} =~ m!/!;
1870         $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1871         push(@m,q[
1872 # Check for unpropagated config.sh changes. Should never happen.
1873 # We do NOT just update config.h because that is not sufficient.
1874 # An out of date config.h is not fatal but complains loudly!
1875 $(PERL_INC)config.h : $(PERL_SRC)config.sh
1876
1877 $(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1878         $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.h or genconfig.pl"
1879         olddef = F$Environment("Default")
1880         Set Default $(PERL_SRC)
1881         $(MMS)],$mmsquals,);
1882         if ($self->{PERL_ARCHLIB} =~ m|\[-| && $self->{PERL_SRC} =~ m|(\[-+)|) {
1883             my($prefix,$target) = ($1,$self->fixpath('$(PERL_ARCHLIB)Config.pm',0));
1884             $target =~ s/\Q$prefix/[/;
1885             push(@m," $target");
1886         }
1887         else { push(@m,' $(MMS$TARGET)'); }
1888         push(@m,q[
1889         Set Default 'olddef'
1890 ]);
1891     }
1892
1893     push(@m, join(" ", map($self->fixpath($_,0),values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1894       if %{$self->{XS}};
1895
1896     join('',@m);
1897 }
1898
1899 =item makefile (override)
1900
1901 Use VMS commands and quoting.
1902
1903 =cut
1904
1905 sub makefile {
1906     my($self) = @_;
1907     my(@m,@cmd);
1908     # We do not know what target was originally specified so we
1909     # must force a manual rerun to be sure. But as it should only
1910     # happen very rarely it is not a significant problem.
1911     push @m, q[
1912 $(OBJECT) : $(FIRST_MAKEFILE)
1913 ] if $self->{OBJECT};
1914
1915     push @m,q[
1916 # We take a very conservative approach here, but it\'s worth it.
1917 # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
1918 $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
1919         $(NOECHO) $(SAY) "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)"
1920         $(NOECHO) $(SAY) "Cleaning current config before rebuilding $(MAKEFILE) ..."
1921         - $(MV) $(MAKEFILE) $(MAKEFILE)_old
1922         - $(MMS)$(MMSQUALIFIERS) $(USEMAKEFILE)$(MAKEFILE)_old clean
1923         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[
1924         $(NOECHO) $(SAY) "$(MAKEFILE) has been rebuilt."
1925         $(NOECHO) $(SAY) "Please run $(MMS) to build the extension."
1926 ];
1927
1928     join('',@m);
1929 }
1930
1931 =item test (override)
1932
1933 Use VMS commands for handling subdirectories.
1934
1935 =cut
1936
1937 sub test {
1938     my($self, %attribs) = @_;
1939     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
1940     my(@m);
1941     push @m,"
1942 TEST_VERBOSE = 0
1943 TEST_TYPE = test_\$(LINKTYPE)
1944 TEST_FILE = test.pl
1945 TESTDB_SW = -d
1946
1947 test :: \$(TEST_TYPE)
1948         \$(NOECHO) \$(NOOP)
1949
1950 testdb :: testdb_\$(LINKTYPE)
1951         \$(NOECHO) \$(NOOP)
1952
1953 ";
1954     foreach(@{$self->{DIR}}){
1955       my($vmsdir) = $self->fixpath($_,1);
1956       push(@m, '        If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'",
1957            '; print `$(MMS)$(MMSQUALIFIERS) $(PASTHRU2) test`'."\n");
1958     }
1959     push(@m, "\t\$(NOECHO) \$(SAY) \"No tests defined for \$(NAME) extension.\"\n")
1960         unless $tests or -f "test.pl" or @{$self->{DIR}};
1961     push(@m, "\n");
1962
1963     push(@m, "test_dynamic :: pure_all\n");
1964     push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests;
1965     push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl";
1966     push(@m, "\t\$(NOECHO) \$(NOOP)\n") if (!$tests && ! -f "test.pl");
1967     push(@m, "\n");
1968
1969     push(@m, "testdb_dynamic :: pure_all\n");
1970     push(@m, $self->test_via_script('$(FULLPERL) "$(TESTDB_SW)"', '$(TEST_FILE)'));
1971     push(@m, "\n");
1972
1973     # Occasionally we may face this degenerate target:
1974     push @m, "test_ : test_dynamic\n\n";
1975  
1976     if ($self->needs_linking()) {
1977         push(@m, "test_static :: pure_all \$(MAP_TARGET)\n");
1978         push(@m, $self->test_via_harness('$(MAP_TARGET)', $tests)) if $tests;
1979         push(@m, $self->test_via_script('$(MAP_TARGET)', 'test.pl')) if -f 'test.pl';
1980         push(@m, "\n");
1981         push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n");
1982         push(@m, $self->test_via_script('$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)'));
1983         push(@m, "\n");
1984     }
1985     else {
1986         push @m, "test_static :: test_dynamic\n\t\$(NOECHO) \$(NOOP)\n\n";
1987         push @m, "testdb_static :: testdb_dynamic\n\t\$(NOECHO) \$(NOOP)\n";
1988     }
1989
1990     join('',@m);
1991 }
1992
1993 =item test_via_harness (override)
1994
1995 Use VMS-style quoting on command line.
1996
1997 =cut
1998
1999 sub test_via_harness {
2000     my($self,$perl,$tests) = @_;
2001     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" \\'."\n\t".
2002     '-e "use Test::Harness qw(&runtests $verbose); $verbose=$(TEST_VERBOSE); runtests @ARGV;" \\'."\n\t$tests\n";
2003 }
2004
2005 =item test_via_script (override)
2006
2007 Use VMS-style quoting on command line.
2008
2009 =cut
2010
2011 sub test_via_script {
2012     my($self,$perl,$script) = @_;
2013     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '.$script.'
2014 ';
2015 }
2016
2017 =item makeaperl (override)
2018
2019 Undertake to build a new set of Perl images using VMS commands.  Since
2020 VMS does dynamic loading, it's not necessary to statically link each
2021 extension into the Perl image, so this isn't the normal build path.
2022 Consequently, it hasn't really been tested, and may well be incomplete.
2023
2024 =cut
2025
2026 sub makeaperl {
2027     my($self, %attribs) = @_;
2028     my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
2029       @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
2030     my(@m);
2031     push @m, "
2032 # --- MakeMaker makeaperl section ---
2033 MAP_TARGET    = $target
2034 ";
2035     return join '', @m if $self->{PARENT};
2036
2037     my($dir) = join ":", @{$self->{DIR}};
2038
2039     unless ($self->{MAKEAPERL}) {
2040         push @m, q{
2041 $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
2042         $(NOECHO) $(SAY) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
2043         $(NOECHO) $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \
2044                 Makefile.PL DIR=}, $dir, q{ \
2045                 MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
2046                 MAKEAPERL=1 NORECURS=1 };
2047
2048         push @m, map(q[ \\\n\t\t"$_"], @ARGV),q{
2049
2050 $(MAP_TARGET) :: $(MAKE_APERL_FILE)
2051         $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
2052 };
2053         push @m, "\n";
2054
2055         return join '', @m;
2056     }
2057
2058
2059     my($linkcmd,@optlibs,@staticpkgs,$extralist,$targdir,$libperldir,%libseen);
2060     local($_);
2061
2062     # The front matter of the linkcommand...
2063     $linkcmd = join ' ', $Config{'ld'},
2064             grep($_, @Config{qw(large split ldflags ccdlflags)});
2065     $linkcmd =~ s/\s+/ /g;
2066
2067     # Which *.olb files could we make use of...
2068     local(%olbs);
2069     $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
2070     require File::Find;
2071     File::Find::find(sub {
2072         return unless m/\Q$self->{LIB_EXT}\E$/;
2073         return if m/^libperl/;
2074
2075         if( exists $self->{INCLUDE_EXT} ){
2076                 my $found = 0;
2077                 my $incl;
2078                 my $xx;
2079
2080                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2081                 $xx =~ s,/?$_,,;
2082                 $xx =~ s,/,::,g;
2083
2084                 # Throw away anything not explicitly marked for inclusion.
2085                 # DynaLoader is implied.
2086                 foreach $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
2087                         if( $xx eq $incl ){
2088                                 $found++;
2089                                 last;
2090                         }
2091                 }
2092                 return unless $found;
2093         }
2094         elsif( exists $self->{EXCLUDE_EXT} ){
2095                 my $excl;
2096                 my $xx;
2097
2098                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2099                 $xx =~ s,/?$_,,;
2100                 $xx =~ s,/,::,g;
2101
2102                 # Throw away anything explicitly marked for exclusion
2103                 foreach $excl (@{$self->{EXCLUDE_EXT}}){
2104                         return if( $xx eq $excl );
2105                 }
2106         }
2107
2108         $olbs{$ENV{DEFAULT}} = $_;
2109     }, grep( -d $_, @{$searchdirs || []}));
2110
2111     # We trust that what has been handed in as argument will be buildable
2112     $static = [] unless $static;
2113     @olbs{@{$static}} = (1) x @{$static};
2114  
2115     $extra = [] unless $extra && ref $extra eq 'ARRAY';
2116     # Sort the object libraries in inverse order of
2117     # filespec length to try to insure that dependent extensions
2118     # will appear before their parents, so the linker will
2119     # search the parent library to resolve references.
2120     # (e.g. Intuit::DWIM will precede Intuit, so unresolved
2121     # references from [.intuit.dwim]dwim.obj can be found
2122     # in [.intuit]intuit.olb).
2123     for (sort { length($a) <=> length($b) } keys %olbs) {
2124         next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
2125         my($dir) = $self->fixpath($_,1);
2126         my($extralibs) = $dir . "extralibs.ld";
2127         my($extopt) = $dir . $olbs{$_};
2128         $extopt =~ s/$self->{LIB_EXT}$/.opt/;
2129         push @optlibs, "$dir$olbs{$_}";
2130         # Get external libraries this extension will need
2131         if (-f $extralibs ) {
2132             my %seenthis;
2133             open LIST,$extralibs or warn $!,next;
2134             while (<LIST>) {
2135                 chomp;
2136                 # Include a library in the link only once, unless it's mentioned
2137                 # multiple times within a single extension's options file, in which
2138                 # case we assume the builder needed to search it again later in the
2139                 # link.
2140                 my $skip = exists($libseen{$_}) && !exists($seenthis{$_});
2141                 $libseen{$_}++;  $seenthis{$_}++;
2142                 next if $skip;
2143                 push @$extra,$_;
2144             }
2145             close LIST;
2146         }
2147         # Get full name of extension for ExtUtils::Miniperl
2148         if (-f $extopt) {
2149             open OPT,$extopt or die $!;
2150             while (<OPT>) {
2151                 next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
2152                 my $pkg = $1;
2153                 $pkg =~ s#__*#::#g;
2154                 push @staticpkgs,$pkg;
2155             }
2156         }
2157     }
2158     # Place all of the external libraries after all of the Perl extension
2159     # libraries in the final link, in order to maximize the opportunity
2160     # for XS code from multiple extensions to resolve symbols against the
2161     # same external library while only including that library once.
2162     push @optlibs, @$extra;
2163
2164     $target = "Perl$Config{'exe_ext'}" unless $target;
2165     ($shrtarget,$targdir) = fileparse($target);
2166     $shrtarget =~ s/^([^.]*)/$1Shr/;
2167     $shrtarget = $targdir . $shrtarget;
2168     $target = "Perlshr.$Config{'dlext'}" unless $target;
2169     $tmp = "[]" unless $tmp;
2170     $tmp = $self->fixpath($tmp,1);
2171     if (@optlibs) { $extralist = join(' ',@optlibs); }
2172     else          { $extralist = ''; }
2173     # Let ExtUtils::Liblist find the necessary libs for us (but skip PerlShr)
2174     # that's what we're building here).
2175     push @optlibs, grep { !/PerlShr/i } split ' ', +($self->ext())[2];
2176     if ($libperl) {
2177         unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
2178             print STDOUT "Warning: $libperl not found\n";
2179             undef $libperl;
2180         }
2181     }
2182     unless ($libperl) {
2183         if (defined $self->{PERL_SRC}) {
2184             $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
2185         } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
2186         } else {
2187             print STDOUT "Warning: $libperl not found
2188     If you're going to build a static perl binary, make sure perl is installed
2189     otherwise ignore this warning\n";
2190         }
2191     }
2192     $libperldir = $self->fixpath((fileparse($libperl))[1],1);
2193
2194     push @m, '
2195 # Fill in the target you want to produce if it\'s not perl
2196 MAP_TARGET    = ',$self->fixpath($target,0),'
2197 MAP_SHRTARGET = ',$self->fixpath($shrtarget,0),"
2198 MAP_LINKCMD   = $linkcmd
2199 MAP_PERLINC   = ", $perlinc ? map('"$_" ',@{$perlinc}) : '',"
2200 MAP_EXTRA     = $extralist
2201 MAP_LIBPERL = ",$self->fixpath($libperl,0),'
2202 ';
2203
2204
2205     push @m,"\n${tmp}Makeaperl.Opt : \$(MAP_EXTRA)\n";
2206     foreach (@optlibs) {
2207         push @m,'       $(NOECHO) $(PERL) -e "print q{',$_,'}" >>$(MMS$TARGET)',"\n";
2208     }
2209     push @m,"\n${tmp}PerlShr.Opt :\n\t";
2210     push @m,'$(NOECHO) $(PERL) -e "print q{$(MAP_SHRTARGET)}" >$(MMS$TARGET)',"\n";
2211
2212 push @m,'
2213 $(MAP_SHRTARGET) : $(MAP_LIBPERL) Makeaperl.Opt ',"${libperldir}Perlshr_Attr.Opt",'
2214         $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_LIBPERL), Makeaperl.Opt/Option ',"${libperldir}Perlshr_Attr.Opt/Option",'
2215 $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",'
2216         $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
2217         $(NOECHO) $(SAY) "To install the new ""$(MAP_TARGET)"" binary, say"
2218         $(NOECHO) $(SAY) "    $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
2219         $(NOECHO) $(SAY) "To remove the intermediate files, say
2220         $(NOECHO) $(SAY) "    $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(MAKEFILE) map_clean"
2221 ';
2222     push @m,"\n${tmp}perlmain.c : \$(MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmp}Writemain.tmp\n";
2223     push @m, "# More from the 255-char line length limit\n";
2224     foreach (@staticpkgs) {
2225         push @m,'       $(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmp}Writemain.tmp\n];
2226     }
2227         push @m,'
2228         $(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" ',$tmp,'Writemain.tmp >$(MMS$TARGET)
2229         $(NOECHO) $(RM_F) ',"${tmp}Writemain.tmp\n";
2230
2231     push @m, q[
2232 # Still more from the 255-char line length limit
2233 doc_inst_perl :
2234         $(NOECHO) $(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp
2235         $(NOECHO) $(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp
2236         $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
2237         $(NOECHO) $(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp
2238         $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
2239         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
2240 ];
2241
2242     push @m, "
2243 inst_perl : pure_inst_perl doc_inst_perl
2244         \$(NOECHO) \$(NOOP)
2245
2246 pure_inst_perl : \$(MAP_TARGET)
2247         $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
2248         $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
2249
2250 clean :: map_clean
2251         \$(NOECHO) \$(NOOP)
2252
2253 map_clean :
2254         \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE)
2255         \$(RM_F) ${tmp}Makeaperl.Opt ${tmp}PerlShr.Opt \$(MAP_TARGET)
2256 ";
2257
2258     join '', @m;
2259 }
2260   
2261 # --- Output postprocessing section ---
2262
2263 =item nicetext (override)
2264
2265 Insure that colons marking targets are preceded by space, in order
2266 to distinguish the target delimiter from a colon appearing as
2267 part of a filespec.
2268
2269 =cut
2270
2271 sub nicetext {
2272
2273     my($self,$text) = @_;
2274     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
2275     $text;
2276 }
2277
2278 1;
2279
2280 =back
2281
2282 =cut
2283
2284 __END__
2285