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