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