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