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