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