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