xref: /openbsd-src/gnu/usr.bin/perl/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_VMS.pm (revision e068048151d29f2562a32185e21a8ba885482260)
1b39c5158Smillertpackage ExtUtils::MM_VMS;
2b39c5158Smillert
3b39c5158Smillertuse strict;
4eac174f2Safresh1use warnings;
5b39c5158Smillert
6b39c5158Smillertuse ExtUtils::MakeMaker::Config;
7b39c5158Smillertrequire Exporter;
8b39c5158Smillert
9b39c5158SmillertBEGIN {
10b39c5158Smillert    # so we can compile the thing on non-VMS platforms.
11b39c5158Smillert    if( $^O eq 'VMS' ) {
12b39c5158Smillert        require VMS::Filespec;
13b39c5158Smillert        VMS::Filespec->import;
14b39c5158Smillert    }
15b39c5158Smillert}
16b39c5158Smillert
17b39c5158Smillertuse File::Basename;
18b39c5158Smillert
19*e0680481Safresh1our $VERSION = '7.70';
2056d68f1eSafresh1$VERSION =~ tr/_//d;
21b39c5158Smillert
22b39c5158Smillertrequire ExtUtils::MM_Any;
23b39c5158Smillertrequire ExtUtils::MM_Unix;
24b39c5158Smillertour @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
25b39c5158Smillert
269f11ffb7Safresh1use ExtUtils::MakeMaker qw($Verbose neatvalue _sprintf562);
27b39c5158Smillertour $Revision = $ExtUtils::MakeMaker::Revision;
28b39c5158Smillert
29b39c5158Smillert
30b39c5158Smillert=head1 NAME
31b39c5158Smillert
32b39c5158SmillertExtUtils::MM_VMS - methods to override UN*X behaviour in ExtUtils::MakeMaker
33b39c5158Smillert
34b39c5158Smillert=head1 SYNOPSIS
35b39c5158Smillert
36b39c5158Smillert  Do not use this directly.
37b39c5158Smillert  Instead, use ExtUtils::MM and it will figure out which MM_*
38b39c5158Smillert  class to use for you.
39b39c5158Smillert
40b39c5158Smillert=head1 DESCRIPTION
41b39c5158Smillert
4256d68f1eSafresh1See L<ExtUtils::MM_Unix> for a documentation of the methods provided
43b39c5158Smillertthere. This package overrides the implementation of these methods, not
44b39c5158Smillertthe semantics.
45b39c5158Smillert
46b39c5158Smillert=head2 Methods always loaded
47b39c5158Smillert
48b39c5158Smillert=over 4
49b39c5158Smillert
50b39c5158Smillert=item wraplist
51b39c5158Smillert
52b39c5158SmillertConverts a list into a string wrapped at approximately 80 columns.
53b39c5158Smillert
54b39c5158Smillert=cut
55b39c5158Smillert
56b39c5158Smillertsub wraplist {
57b39c5158Smillert    my($self) = shift;
58b39c5158Smillert    my($line,$hlen) = ('',0);
59b39c5158Smillert
60b39c5158Smillert    foreach my $word (@_) {
61b39c5158Smillert      # Perl bug -- seems to occasionally insert extra elements when
62b39c5158Smillert      # traversing array (scalar(@array) doesn't show them, but
63b39c5158Smillert      # foreach(@array) does) (5.00307)
64b39c5158Smillert      next unless $word =~ /\w/;
65b39c5158Smillert      $line .= ' ' if length($line);
66b39c5158Smillert      if ($hlen > 80) { $line .= "\\\n\t"; $hlen = 0; }
67b39c5158Smillert      $line .= $word;
68b39c5158Smillert      $hlen += length($word) + 2;
69b39c5158Smillert    }
70b39c5158Smillert    $line;
71b39c5158Smillert}
72b39c5158Smillert
73b39c5158Smillert
74b39c5158Smillert# This isn't really an override.  It's just here because ExtUtils::MM_VMS
75b39c5158Smillert# appears in @MM::ISA before ExtUtils::Liblist::Kid, so if there isn't an ext()
76b39c5158Smillert# in MM_VMS, then AUTOLOAD is called, and bad things happen.  So, we just
77b39c5158Smillert# mimic inheritance here and hand off to ExtUtils::Liblist::Kid.
78b39c5158Smillert# XXX This hackery will die soon. --Schwern
79b39c5158Smillertsub ext {
80b39c5158Smillert    require ExtUtils::Liblist::Kid;
81b39c5158Smillert    goto &ExtUtils::Liblist::Kid::ext;
82b39c5158Smillert}
83b39c5158Smillert
84b39c5158Smillert=back
85b39c5158Smillert
86b39c5158Smillert=head2 Methods
87b39c5158Smillert
88b39c5158SmillertThose methods which override default MM_Unix methods are marked
89b39c5158Smillert"(override)", while methods unique to MM_VMS are marked "(specific)".
90b39c5158SmillertFor overridden methods, documentation is limited to an explanation
9156d68f1eSafresh1of why this method overrides the MM_Unix method; see the L<ExtUtils::MM_Unix>
92b39c5158Smillertdocumentation for more details.
93b39c5158Smillert
94b39c5158Smillert=over 4
95b39c5158Smillert
96b39c5158Smillert=item guess_name (override)
97b39c5158Smillert
98b39c5158SmillertTry to determine name of extension being built.  We begin with the name
99b39c5158Smillertof the current directory.  Since VMS filenames are case-insensitive,
100b39c5158Smillerthowever, we look for a F<.pm> file whose name matches that of the current
101b39c5158Smillertdirectory (presumably the 'main' F<.pm> file for this extension), and try
102b39c5158Smillertto find a C<package> statement from which to obtain the Mixed::Case
103b39c5158Smillertpackage name.
104b39c5158Smillert
105b39c5158Smillert=cut
106b39c5158Smillert
107b39c5158Smillertsub guess_name {
108b39c5158Smillert    my($self) = @_;
109b39c5158Smillert    my($defname,$defpm,@pm,%xs);
110b39c5158Smillert    local *PM;
111b39c5158Smillert
112b39c5158Smillert    $defname = basename(fileify($ENV{'DEFAULT'}));
113b39c5158Smillert    $defname =~ s![\d\-_]*\.dir.*$!!;  # Clip off .dir;1 suffix, and package version
114b39c5158Smillert    $defpm = $defname;
115b39c5158Smillert    # Fallback in case for some reason a user has copied the files for an
116b39c5158Smillert    # extension into a working directory whose name doesn't reflect the
117b39c5158Smillert    # extension's name.  We'll use the name of a unique .pm file, or the
118b39c5158Smillert    # first .pm file with a matching .xs file.
119b39c5158Smillert    if (not -e "${defpm}.pm") {
120b39c5158Smillert      @pm = glob('*.pm');
121b39c5158Smillert      s/.pm$// for @pm;
122b39c5158Smillert      if (@pm == 1) { ($defpm = $pm[0]) =~ s/.pm$//; }
123b39c5158Smillert      elsif (@pm) {
124b39c5158Smillert        %xs = map { s/.xs$//; ($_,1) } glob('*.xs');  ## no critic
125b39c5158Smillert        if (keys %xs) {
126b39c5158Smillert            foreach my $pm (@pm) {
127b39c5158Smillert                $defpm = $pm, last if exists $xs{$pm};
128b39c5158Smillert            }
129b39c5158Smillert        }
130b39c5158Smillert      }
131b39c5158Smillert    }
132b39c5158Smillert    if (open(my $pm, '<', "${defpm}.pm")){
133b39c5158Smillert        while (<$pm>) {
134b39c5158Smillert            if (/^\s*package\s+([^;]+)/i) {
135b39c5158Smillert                $defname = $1;
136b39c5158Smillert                last;
137b39c5158Smillert            }
138b39c5158Smillert        }
13991f110e0Safresh1        print "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t",
140b39c5158Smillert                     "defaulting package name to $defname\n"
141b39c5158Smillert            if eof($pm);
142b39c5158Smillert        close $pm;
143b39c5158Smillert    }
144b39c5158Smillert    else {
14591f110e0Safresh1        print "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t",
146b39c5158Smillert                     "defaulting package name to $defname\n";
147b39c5158Smillert    }
148b39c5158Smillert    $defname =~ s#[\d.\-_]+$##;
149b39c5158Smillert    $defname;
150b39c5158Smillert}
151b39c5158Smillert
152b39c5158Smillert=item find_perl (override)
153b39c5158Smillert
154b39c5158SmillertUse VMS file specification syntax and CLI commands to find and
155b39c5158Smillertinvoke Perl images.
156b39c5158Smillert
157b39c5158Smillert=cut
158b39c5158Smillert
159b39c5158Smillertsub find_perl {
160b39c5158Smillert    my($self, $ver, $names, $dirs, $trace) = @_;
161b39c5158Smillert    my($vmsfile,@sdirs,@snames,@cand);
162b39c5158Smillert    my($rslt);
163b39c5158Smillert    my($inabs) = 0;
164b39c5158Smillert    local *TCF;
165b39c5158Smillert
166b39c5158Smillert    if( $self->{PERL_CORE} ) {
167b39c5158Smillert        # Check in relative directories first, so we pick up the current
168b39c5158Smillert        # version of Perl if we're running MakeMaker as part of the main build.
169b39c5158Smillert        @sdirs = sort { my($absa) = $self->file_name_is_absolute($a);
170b39c5158Smillert                        my($absb) = $self->file_name_is_absolute($b);
171b39c5158Smillert                        if ($absa && $absb) { return $a cmp $b }
172b39c5158Smillert                        else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); }
173b39c5158Smillert                      } @$dirs;
174b39c5158Smillert        # Check miniperl before perl, and check names likely to contain
175b39c5158Smillert        # version numbers before "generic" names, so we pick up an
176b39c5158Smillert        # executable that's less likely to be from an old installation.
177b39c5158Smillert        @snames = sort { my($ba) = $a =~ m!([^:>\]/]+)$!;  # basename
178b39c5158Smillert                         my($bb) = $b =~ m!([^:>\]/]+)$!;
179b39c5158Smillert                         my($ahasdir) = (length($a) - length($ba) > 0);
180b39c5158Smillert                         my($bhasdir) = (length($b) - length($bb) > 0);
181b39c5158Smillert                         if    ($ahasdir and not $bhasdir) { return 1; }
182b39c5158Smillert                         elsif ($bhasdir and not $ahasdir) { return -1; }
183b39c5158Smillert                         else { $bb =~ /\d/ <=> $ba =~ /\d/
184b39c5158Smillert                                  or substr($ba,0,1) cmp substr($bb,0,1)
185b39c5158Smillert                                  or length($bb) <=> length($ba) } } @$names;
186b39c5158Smillert    }
187b39c5158Smillert    else {
188b39c5158Smillert        @sdirs  = @$dirs;
189b39c5158Smillert        @snames = @$names;
190b39c5158Smillert    }
191b39c5158Smillert
192b39c5158Smillert    # Image names containing Perl version use '_' instead of '.' under VMS
193b39c5158Smillert    s/\.(\d+)$/_$1/ for @snames;
194b39c5158Smillert    if ($trace >= 2){
195b39c5158Smillert        print "Looking for perl $ver by these names:\n";
196b39c5158Smillert        print "\t@snames,\n";
197b39c5158Smillert        print "in these dirs:\n";
198b39c5158Smillert        print "\t@sdirs\n";
199b39c5158Smillert    }
200b39c5158Smillert    foreach my $dir (@sdirs){
201b39c5158Smillert        next unless defined $dir; # $self->{PERL_SRC} may be undefined
202b39c5158Smillert        $inabs++ if $self->file_name_is_absolute($dir);
203b39c5158Smillert        if ($inabs == 1) {
204b39c5158Smillert            # We've covered relative dirs; everything else is an absolute
205b39c5158Smillert            # dir (probably an installed location).  First, we'll try
206b39c5158Smillert            # potential command names, to see whether we can avoid a long
207b39c5158Smillert            # MCR expression.
208b39c5158Smillert            foreach my $name (@snames) {
209b39c5158Smillert                push(@cand,$name) if $name =~ /^[\w\-\$]+$/;
210b39c5158Smillert            }
211b39c5158Smillert            $inabs++; # Should happen above in next $dir, but just in case...
212b39c5158Smillert        }
213b39c5158Smillert        foreach my $name (@snames){
214b39c5158Smillert            push @cand, ($name !~ m![/:>\]]!) ? $self->catfile($dir,$name)
215b39c5158Smillert                                              : $self->fixpath($name,0);
216b39c5158Smillert        }
217b39c5158Smillert    }
218b39c5158Smillert    foreach my $name (@cand) {
219b39c5158Smillert        print "Checking $name\n" if $trace >= 2;
220b39c5158Smillert        # If it looks like a potential command, try it without the MCR
221b39c5158Smillert        if ($name =~ /^[\w\-\$]+$/) {
222b39c5158Smillert            open(my $tcf, ">", "temp_mmvms.com")
223b39c5158Smillert                or die('unable to open temp file');
224b39c5158Smillert            print $tcf "\$ set message/nofacil/nosever/noident/notext\n";
225b39c5158Smillert            print $tcf "\$ $name -e \"require $ver; print \"\"VER_OK\\n\"\"\"\n";
226b39c5158Smillert            close $tcf;
227b39c5158Smillert            $rslt = `\@temp_mmvms.com` ;
228b39c5158Smillert            unlink('temp_mmvms.com');
229b39c5158Smillert            if ($rslt =~ /VER_OK/) {
230b39c5158Smillert                print "Using PERL=$name\n" if $trace;
231b39c5158Smillert                return $name;
232b39c5158Smillert            }
233b39c5158Smillert        }
234b39c5158Smillert        next unless $vmsfile = $self->maybe_command($name);
235b39c5158Smillert        $vmsfile =~ s/;[\d\-]*$//;  # Clip off version number; we can use a newer version as well
236b39c5158Smillert        print "Executing $vmsfile\n" if ($trace >= 2);
237b39c5158Smillert        open(my $tcf, '>', "temp_mmvms.com")
238b39c5158Smillert                or die('unable to open temp file');
239b39c5158Smillert        print $tcf "\$ set message/nofacil/nosever/noident/notext\n";
240b39c5158Smillert        print $tcf "\$ mcr $vmsfile -e \"require $ver; print \"\"VER_OK\\n\"\"\" \n";
241b39c5158Smillert        close $tcf;
242b39c5158Smillert        $rslt = `\@temp_mmvms.com`;
243b39c5158Smillert        unlink('temp_mmvms.com');
244b39c5158Smillert        if ($rslt =~ /VER_OK/) {
245b39c5158Smillert            print "Using PERL=MCR $vmsfile\n" if $trace;
246b39c5158Smillert            return "MCR $vmsfile";
247b39c5158Smillert        }
248b39c5158Smillert    }
24991f110e0Safresh1    print "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
250b39c5158Smillert    0; # false and not empty
251b39c5158Smillert}
252b39c5158Smillert
253898184e3Ssthen=item _fixin_replace_shebang (override)
254898184e3Ssthen
25556d68f1eSafresh1Helper routine for L<< MM->fixin()|ExtUtils::MM_Unix/fixin >>, overridden
25656d68f1eSafresh1because there's no such thing as an
2576fb12b70Safresh1actual shebang line that will be interpreted by the shell, so we just prepend
258898184e3Ssthen$Config{startperl} and preserve the shebang line argument for any switches it
259898184e3Ssthenmay contain.
260898184e3Ssthen
261898184e3Ssthen=cut
262898184e3Ssthen
263898184e3Ssthensub _fixin_replace_shebang {
264898184e3Ssthen    my ( $self, $file, $line ) = @_;
265898184e3Ssthen
266898184e3Ssthen    my ( undef, $arg ) = split ' ', $line, 2;
267898184e3Ssthen
268898184e3Ssthen    return $Config{startperl} . "\n" . $Config{sharpbang} . "perl $arg\n";
269898184e3Ssthen}
270898184e3Ssthen
271b39c5158Smillert=item maybe_command (override)
272b39c5158Smillert
273b39c5158SmillertFollows VMS naming conventions for executable files.
274b39c5158SmillertIf the name passed in doesn't exactly match an executable file,
275b39c5158Smillertappends F<.Exe> (or equivalent) to check for executable image, and F<.Com>
276b39c5158Smillertto check for DCL procedure.  If this fails, checks directories in DCL$PATH
277b39c5158Smillertand finally F<Sys$System:> for an executable file having the name specified,
278b39c5158Smillertwith or without the F<.Exe>-equivalent suffix.
279b39c5158Smillert
280b39c5158Smillert=cut
281b39c5158Smillert
282b39c5158Smillertsub maybe_command {
283b39c5158Smillert    my($self,$file) = @_;
284b39c5158Smillert    return $file if -x $file && ! -d _;
285b39c5158Smillert    my(@dirs) = ('');
286b39c5158Smillert    my(@exts) = ('',$Config{'exe_ext'},'.exe','.com');
287b39c5158Smillert
288b39c5158Smillert    if ($file !~ m![/:>\]]!) {
289b39c5158Smillert        for (my $i = 0; defined $ENV{"DCL\$PATH;$i"}; $i++) {
290b39c5158Smillert            my $dir = $ENV{"DCL\$PATH;$i"};
291b39c5158Smillert            $dir .= ':' unless $dir =~ m%[\]:]$%;
292b39c5158Smillert            push(@dirs,$dir);
293b39c5158Smillert        }
294b39c5158Smillert        push(@dirs,'Sys$System:');
295b39c5158Smillert        foreach my $dir (@dirs) {
296b39c5158Smillert            my $sysfile = "$dir$file";
297b39c5158Smillert            foreach my $ext (@exts) {
298b39c5158Smillert                return $file if -x "$sysfile$ext" && ! -d _;
299b39c5158Smillert            }
300b39c5158Smillert        }
301b39c5158Smillert    }
302b39c5158Smillert    return 0;
303b39c5158Smillert}
304b39c5158Smillert
305b39c5158Smillert
306b39c5158Smillert=item pasthru (override)
307b39c5158Smillert
3089f11ffb7Safresh1The list of macro definitions to be passed through must be specified using
3099f11ffb7Safresh1the /MACRO qualifier and must not add another /DEFINE qualifier.  We prepend
3109f11ffb7Safresh1our own comma here to the contents of $(PASTHRU_DEFINE) because it is often
3119f11ffb7Safresh1empty and a comma always present in CCFLAGS would generate a missing
3129f11ffb7Safresh1qualifier value error.
313b39c5158Smillert
314b39c5158Smillert=cut
315b39c5158Smillert
316b39c5158Smillertsub pasthru {
3179f11ffb7Safresh1    my($self) = shift;
3189f11ffb7Safresh1    my $pasthru = $self->SUPER::pasthru;
3199f11ffb7Safresh1    $pasthru =~ s|(PASTHRU\s*=\s*)|$1/MACRO=(|;
3209f11ffb7Safresh1    $pasthru =~ s|\n\z|)\n|m;
3219f11ffb7Safresh1    $pasthru =~ s|/defi?n?e?=\(?([^\),]+)\)?|,$1|ig;
3229f11ffb7Safresh1
3239f11ffb7Safresh1    return $pasthru;
324b39c5158Smillert}
325b39c5158Smillert
326b39c5158Smillert
327b39c5158Smillert=item pm_to_blib (override)
328b39c5158Smillert
329b39c5158SmillertVMS wants a dot in every file so we can't have one called 'pm_to_blib',
330b39c5158Smillertit becomes 'pm_to_blib.' and MMS/K isn't smart enough to know that when
331b39c5158Smillertyou have a target called 'pm_to_blib' it should look for 'pm_to_blib.'.
332b39c5158Smillert
333b39c5158SmillertSo in VMS its pm_to_blib.ts.
334b39c5158Smillert
335b39c5158Smillert=cut
336b39c5158Smillert
337b39c5158Smillertsub pm_to_blib {
338b39c5158Smillert    my $self = shift;
339b39c5158Smillert
340b39c5158Smillert    my $make = $self->SUPER::pm_to_blib;
341b39c5158Smillert
342b39c5158Smillert    $make =~ s{^pm_to_blib :}{pm_to_blib.ts :}m;
343b39c5158Smillert    $make =~ s{\$\(TOUCH\) pm_to_blib}{\$(TOUCH) pm_to_blib.ts};
344b39c5158Smillert
345b39c5158Smillert    $make = <<'MAKE' . $make;
346b39c5158Smillert# Dummy target to match Unix target name; we use pm_to_blib.ts as
347b39c5158Smillert# timestamp file to avoid repeated invocations under VMS
348b39c5158Smillertpm_to_blib : pm_to_blib.ts
349b39c5158Smillert	$(NOECHO) $(NOOP)
350b39c5158Smillert
351b39c5158SmillertMAKE
352b39c5158Smillert
353b39c5158Smillert    return $make;
354b39c5158Smillert}
355b39c5158Smillert
356b39c5158Smillert
357b39c5158Smillert=item perl_script (override)
358b39c5158Smillert
359b39c5158SmillertIf name passed in doesn't specify a readable file, appends F<.com> or
360b39c5158SmillertF<.pl> and tries again, since it's customary to have file types on all files
361b39c5158Smillertunder VMS.
362b39c5158Smillert
363b39c5158Smillert=cut
364b39c5158Smillert
365b39c5158Smillertsub perl_script {
366b39c5158Smillert    my($self,$file) = @_;
367b39c5158Smillert    return $file if -r $file && ! -d _;
368b39c5158Smillert    return "$file.com" if -r "$file.com";
369b39c5158Smillert    return "$file.pl" if -r "$file.pl";
370b39c5158Smillert    return '';
371b39c5158Smillert}
372b39c5158Smillert
373b39c5158Smillert
374b39c5158Smillert=item replace_manpage_separator
375b39c5158Smillert
376b39c5158SmillertUse as separator a character which is legal in a VMS-syntax file name.
377b39c5158Smillert
378b39c5158Smillert=cut
379b39c5158Smillert
380b39c5158Smillertsub replace_manpage_separator {
381b39c5158Smillert    my($self,$man) = @_;
382b39c5158Smillert    $man = unixify($man);
383b39c5158Smillert    $man =~ s#/+#__#g;
384b39c5158Smillert    $man;
385b39c5158Smillert}
386b39c5158Smillert
387b39c5158Smillert=item init_DEST
388b39c5158Smillert
389b39c5158Smillert(override) Because of the difficulty concatenating VMS filepaths we
390b39c5158Smillertmust pre-expand the DEST* variables.
391b39c5158Smillert
392b39c5158Smillert=cut
393b39c5158Smillert
394b39c5158Smillertsub init_DEST {
395b39c5158Smillert    my $self = shift;
396b39c5158Smillert
397b39c5158Smillert    $self->SUPER::init_DEST;
398b39c5158Smillert
399b39c5158Smillert    # Expand DEST variables.
400b39c5158Smillert    foreach my $var ($self->installvars) {
401b39c5158Smillert        my $destvar = 'DESTINSTALL'.$var;
402b39c5158Smillert        $self->{$destvar} = $self->eliminate_macros($self->{$destvar});
403b39c5158Smillert    }
404b39c5158Smillert}
405b39c5158Smillert
406b39c5158Smillert
407b39c5158Smillert=item init_DIRFILESEP
408b39c5158Smillert
4096fb12b70Safresh1No separator between a directory path and a filename on VMS.
410b39c5158Smillert
411b39c5158Smillert=cut
412b39c5158Smillert
413b39c5158Smillertsub init_DIRFILESEP {
414b39c5158Smillert    my($self) = shift;
415b39c5158Smillert
416b39c5158Smillert    $self->{DIRFILESEP} = '';
417b39c5158Smillert    return 1;
418b39c5158Smillert}
419b39c5158Smillert
420b39c5158Smillert
421b39c5158Smillert=item init_main (override)
422b39c5158Smillert
423b39c5158Smillert
424b39c5158Smillert=cut
425b39c5158Smillert
426b39c5158Smillertsub init_main {
427b39c5158Smillert    my($self) = shift;
428b39c5158Smillert
429b39c5158Smillert    $self->SUPER::init_main;
430b39c5158Smillert
431b39c5158Smillert    $self->{DEFINE} ||= '';
432b39c5158Smillert    if ($self->{DEFINE} ne '') {
433b39c5158Smillert        my(@terms) = split(/\s+/,$self->{DEFINE});
434b39c5158Smillert        my(@defs,@udefs);
435b39c5158Smillert        foreach my $def (@terms) {
436b39c5158Smillert            next unless $def;
437b39c5158Smillert            my $targ = \@defs;
438b39c5158Smillert            if ($def =~ s/^-([DU])//) {    # If it was a Unix-style definition
439b39c5158Smillert                $targ = \@udefs if $1 eq 'U';
440b39c5158Smillert                $def =~ s/='(.*)'$/=$1/;  # then remove shell-protection ''
441b39c5158Smillert                $def =~ s/^'(.*)'$/$1/;   # from entire term or argument
442b39c5158Smillert            }
443b39c5158Smillert            if ($def =~ /=/) {
444b39c5158Smillert                $def =~ s/"/""/g;  # Protect existing " from DCL
445b39c5158Smillert                $def = qq["$def"]; # and quote to prevent parsing of =
446b39c5158Smillert            }
447b39c5158Smillert            push @$targ, $def;
448b39c5158Smillert        }
449b39c5158Smillert
450b39c5158Smillert        $self->{DEFINE} = '';
451b39c5158Smillert        if (@defs)  {
452b39c5158Smillert            $self->{DEFINE}  = '/Define=(' . join(',',@defs)  . ')';
453b39c5158Smillert        }
454b39c5158Smillert        if (@udefs) {
455b39c5158Smillert            $self->{DEFINE} .= '/Undef=('  . join(',',@udefs) . ')';
456b39c5158Smillert        }
457b39c5158Smillert    }
458b39c5158Smillert}
459b39c5158Smillert
460898184e3Ssthen=item init_tools (override)
461b39c5158Smillert
462898184e3SsthenProvide VMS-specific forms of various utility commands.
463b39c5158Smillert
464898184e3SsthenSets DEV_NULL to nothing because I don't know how to do it on VMS.
465b39c5158Smillert
466898184e3SsthenChanges EQUALIZE_TIMESTAMP to set revision date of target file to
467b39c5158Smillertone second later than source file, since MMK interprets precisely
468b39c5158Smillertequal revision dates for a source and target file as a sign that the
469b39c5158Smillerttarget needs to be updated.
470b39c5158Smillert
471b39c5158Smillert=cut
472b39c5158Smillert
473898184e3Ssthensub init_tools {
474b39c5158Smillert    my($self) = @_;
475b39c5158Smillert
476b39c5158Smillert    $self->{NOOP}               = 'Continue';
477b39c5158Smillert    $self->{NOECHO}             ||= '@ ';
478b39c5158Smillert
479b39c5158Smillert    $self->{MAKEFILE}           ||= $self->{FIRST_MAKEFILE} || 'Descrip.MMS';
480b39c5158Smillert    $self->{FIRST_MAKEFILE}     ||= $self->{MAKEFILE};
481b39c5158Smillert    $self->{MAKE_APERL_FILE}    ||= 'Makeaperl.MMS';
482b39c5158Smillert    $self->{MAKEFILE_OLD}       ||= $self->eliminate_macros('$(FIRST_MAKEFILE)_old');
483b39c5158Smillert#
484b39c5158Smillert#   If an extension is not specified, then MMS/MMK assumes an
485b39c5158Smillert#   an extension of .MMS.  If there really is no extension,
486b39c5158Smillert#   then a trailing "." needs to be appended to specify a
487b39c5158Smillert#   a null extension.
488b39c5158Smillert#
489b39c5158Smillert    $self->{MAKEFILE} .= '.' unless $self->{MAKEFILE} =~ m/\./;
490b39c5158Smillert    $self->{FIRST_MAKEFILE} .= '.' unless $self->{FIRST_MAKEFILE} =~ m/\./;
491b39c5158Smillert    $self->{MAKE_APERL_FILE} .= '.' unless $self->{MAKE_APERL_FILE} =~ m/\./;
492b39c5158Smillert    $self->{MAKEFILE_OLD} .= '.' unless $self->{MAKEFILE_OLD} =~ m/\./;
493b39c5158Smillert
494b39c5158Smillert    $self->{MACROSTART}         ||= '/Macro=(';
495b39c5158Smillert    $self->{MACROEND}           ||= ')';
496b39c5158Smillert    $self->{USEMAKEFILE}        ||= '/Descrip=';
497b39c5158Smillert
498b39c5158Smillert    $self->{EQUALIZE_TIMESTAMP} ||= '$(ABSPERLRUN) -we "open F,qq{>>$ARGV[1]};close F;utime(0,(stat($ARGV[0]))[9]+1,$ARGV[1])"';
499b39c5158Smillert
500b39c5158Smillert    $self->{MOD_INSTALL} ||=
501b39c5158Smillert      $self->oneliner(<<'CODE', ['-MExtUtils::Install']);
502b8851fccSafresh1install([ from_to => {split('\|', <STDIN>)}, verbose => '$(VERBINST)', uninstall_shadows => '$(UNINST)', dir_mode => '$(PERM_DIR)' ]);
503b39c5158SmillertCODE
504b39c5158Smillert
505b39c5158Smillert    $self->{UMASK_NULL} = '! ';
506b39c5158Smillert
507898184e3Ssthen    $self->SUPER::init_tools;
508898184e3Ssthen
509898184e3Ssthen    # Use the default shell
510898184e3Ssthen    $self->{SHELL}    ||= 'Posix';
511898184e3Ssthen
512b39c5158Smillert    # Redirection on VMS goes before the command, not after as on Unix.
513b39c5158Smillert    # $(DEV_NULL) is used once and its not worth going nuts over making
514b39c5158Smillert    # it work.  However, Unix's DEV_NULL is quite wrong for VMS.
515b39c5158Smillert    $self->{DEV_NULL}   = '';
516b39c5158Smillert
517898184e3Ssthen    return;
518898184e3Ssthen}
519898184e3Ssthen
520b39c5158Smillert=item init_platform (override)
521b39c5158Smillert
522b39c5158SmillertAdd PERL_VMS, MM_VMS_REVISION and MM_VMS_VERSION.
523b39c5158Smillert
524b39c5158SmillertMM_VMS_REVISION is for backwards compatibility before MM_VMS had a
525b39c5158Smillert$VERSION.
526b39c5158Smillert
527b39c5158Smillert=cut
528b39c5158Smillert
529b39c5158Smillertsub init_platform {
530b39c5158Smillert    my($self) = shift;
531b39c5158Smillert
532b39c5158Smillert    $self->{MM_VMS_REVISION} = $Revision;
533b39c5158Smillert    $self->{MM_VMS_VERSION}  = $VERSION;
534b39c5158Smillert    $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC}, 'VMS')
535b39c5158Smillert      if $self->{PERL_SRC};
536b39c5158Smillert}
537b39c5158Smillert
538b39c5158Smillert
539b39c5158Smillert=item platform_constants
540b39c5158Smillert
541b39c5158Smillert=cut
542b39c5158Smillert
543b39c5158Smillertsub platform_constants {
544b39c5158Smillert    my($self) = shift;
545b39c5158Smillert    my $make_frag = '';
546b39c5158Smillert
547b39c5158Smillert    foreach my $macro (qw(PERL_VMS MM_VMS_REVISION MM_VMS_VERSION))
548b39c5158Smillert    {
549b39c5158Smillert        next unless defined $self->{$macro};
550b39c5158Smillert        $make_frag .= "$macro = $self->{$macro}\n";
551b39c5158Smillert    }
552b39c5158Smillert
553b39c5158Smillert    return $make_frag;
554b39c5158Smillert}
555b39c5158Smillert
556b39c5158Smillert
557b39c5158Smillert=item init_VERSION (override)
558b39c5158Smillert
559b39c5158SmillertOverride the *DEFINE_VERSION macros with VMS semantics.  Translate the
560b39c5158SmillertMAKEMAKER filepath to VMS style.
561b39c5158Smillert
562b39c5158Smillert=cut
563b39c5158Smillert
564b39c5158Smillertsub init_VERSION {
565b39c5158Smillert    my $self = shift;
566b39c5158Smillert
567b39c5158Smillert    $self->SUPER::init_VERSION;
568b39c5158Smillert
569b39c5158Smillert    $self->{DEFINE_VERSION}    = '"$(VERSION_MACRO)=""$(VERSION)"""';
570b39c5158Smillert    $self->{XS_DEFINE_VERSION} = '"$(XS_VERSION_MACRO)=""$(XS_VERSION)"""';
571b39c5158Smillert    $self->{MAKEMAKER} = vmsify($INC{'ExtUtils/MakeMaker.pm'});
572b39c5158Smillert}
573b39c5158Smillert
574b39c5158Smillert
575b39c5158Smillert=item constants (override)
576b39c5158Smillert
577b39c5158SmillertFixes up numerous file and directory macros to insure VMS syntax
578b39c5158Smillertregardless of input syntax.  Also makes lists of files
579b39c5158Smillertcomma-separated.
580b39c5158Smillert
581b39c5158Smillert=cut
582b39c5158Smillert
583b39c5158Smillertsub constants {
584b39c5158Smillert    my($self) = @_;
585b39c5158Smillert
586b39c5158Smillert    # Be kind about case for pollution
587b39c5158Smillert    for (@ARGV) { $_ = uc($_) if /POLLUTE/i; }
588b39c5158Smillert
589b39c5158Smillert    # Cleanup paths for directories in MMS macros.
590b39c5158Smillert    foreach my $macro ( qw [
591b39c5158Smillert            INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB
59256d68f1eSafresh1            PERL_LIB PERL_ARCHLIB PERL_ARCHLIBDEP
593b39c5158Smillert            PERL_INC PERL_SRC ],
59456d68f1eSafresh1                        (map { 'INSTALL'.$_ } $self->installvars),
59556d68f1eSafresh1                        (map { 'DESTINSTALL'.$_ } $self->installvars)
596b39c5158Smillert                      )
597b39c5158Smillert    {
598b39c5158Smillert        next unless defined $self->{$macro};
599b39c5158Smillert        next if $macro =~ /MAN/ && $self->{$macro} eq 'none';
600b39c5158Smillert        $self->{$macro} = $self->fixpath($self->{$macro},1);
601b39c5158Smillert    }
602b39c5158Smillert
603b39c5158Smillert    # Cleanup paths for files in MMS macros.
604b39c5158Smillert    foreach my $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKEFILE_OLD
605b39c5158Smillert                           MAKE_APERL_FILE MYEXTLIB] )
606b39c5158Smillert    {
607b39c5158Smillert        next unless defined $self->{$macro};
608b39c5158Smillert        $self->{$macro} = $self->fixpath($self->{$macro},0);
609b39c5158Smillert    }
610b39c5158Smillert
611b39c5158Smillert    # Fixup files for MMS macros
612b39c5158Smillert    # XXX is this list complete?
613b39c5158Smillert    for my $macro (qw/
61491f110e0Safresh1                   FULLEXT VERSION_FROM
615b39c5158Smillert	      /	) {
616b39c5158Smillert        next unless defined $self->{$macro};
617b39c5158Smillert        $self->{$macro} = $self->fixpath($self->{$macro},0);
618b39c5158Smillert    }
619b39c5158Smillert
620b39c5158Smillert
62191f110e0Safresh1    for my $macro (qw/
62291f110e0Safresh1                   OBJECT LDFROM
62391f110e0Safresh1	      /	) {
62491f110e0Safresh1        next unless defined $self->{$macro};
62591f110e0Safresh1
62691f110e0Safresh1        # Must expand macros before splitting on unescaped whitespace.
62791f110e0Safresh1        $self->{$macro} = $self->eliminate_macros($self->{$macro});
62891f110e0Safresh1        if ($self->{$macro} =~ /(?<!\^)\s/) {
62991f110e0Safresh1            $self->{$macro} =~ s/(\\)?\n+\s+/ /g;
63091f110e0Safresh1            $self->{$macro} = $self->wraplist(
63191f110e0Safresh1                map $self->fixpath($_,0), split /,?(?<!\^)\s+/, $self->{$macro}
63291f110e0Safresh1            );
63391f110e0Safresh1        }
63491f110e0Safresh1        else {
63591f110e0Safresh1            $self->{$macro} = $self->fixpath($self->{$macro},0);
63691f110e0Safresh1        }
63791f110e0Safresh1    }
63891f110e0Safresh1
639b39c5158Smillert    for my $macro (qw/ XS MAN1PODS MAN3PODS PM /) {
640b39c5158Smillert        # Where is the space coming from? --jhi
641b39c5158Smillert        next unless $self ne " " && defined $self->{$macro};
642b39c5158Smillert        my %tmp = ();
643b39c5158Smillert        for my $key (keys %{$self->{$macro}}) {
644b39c5158Smillert            $tmp{$self->fixpath($key,0)} =
645b39c5158Smillert                                     $self->fixpath($self->{$macro}{$key},0);
646b39c5158Smillert        }
647b39c5158Smillert        $self->{$macro} = \%tmp;
648b39c5158Smillert    }
649b39c5158Smillert
650b39c5158Smillert    for my $macro (qw/ C O_FILES H /) {
651b39c5158Smillert        next unless defined $self->{$macro};
652b39c5158Smillert        my @tmp = ();
653b39c5158Smillert        for my $val (@{$self->{$macro}}) {
654b39c5158Smillert            push(@tmp,$self->fixpath($val,0));
655b39c5158Smillert        }
656b39c5158Smillert        $self->{$macro} = \@tmp;
657b39c5158Smillert    }
658b39c5158Smillert
659b39c5158Smillert    # mms/k does not define a $(MAKE) macro.
660b39c5158Smillert    $self->{MAKE} = '$(MMS)$(MMSQUALIFIERS)';
661b39c5158Smillert
662b39c5158Smillert    return $self->SUPER::constants;
663b39c5158Smillert}
664b39c5158Smillert
665b39c5158Smillert
666b39c5158Smillert=item special_targets
667b39c5158Smillert
668b39c5158SmillertClear the default .SUFFIXES and put in our own list.
669b39c5158Smillert
670b39c5158Smillert=cut
671b39c5158Smillert
672b39c5158Smillertsub special_targets {
673b39c5158Smillert    my $self = shift;
674b39c5158Smillert
675b39c5158Smillert    my $make_frag .= <<'MAKE_FRAG';
676b39c5158Smillert.SUFFIXES :
677b39c5158Smillert.SUFFIXES : $(OBJ_EXT) .c .cpp .cxx .xs
678b39c5158Smillert
679b39c5158SmillertMAKE_FRAG
680b39c5158Smillert
681b39c5158Smillert    return $make_frag;
682b39c5158Smillert}
683b39c5158Smillert
684b39c5158Smillert=item cflags (override)
685b39c5158Smillert
686b39c5158SmillertBypass shell script and produce qualifiers for CC directly (but warn
687b39c5158Smillertuser if a shell script for this extension exists).  Fold multiple
688b39c5158Smillert/Defines into one, since some C compilers pay attention to only one
689b39c5158Smillertinstance of this qualifier on the command line.
690b39c5158Smillert
691b39c5158Smillert=cut
692b39c5158Smillert
693b39c5158Smillertsub cflags {
694b39c5158Smillert    my($self,$libperl) = @_;
695b39c5158Smillert    my($quals) = $self->{CCFLAGS} || $Config{'ccflags'};
696b39c5158Smillert    my($definestr,$undefstr,$flagoptstr) = ('','','');
697b39c5158Smillert    my($incstr) = '/Include=($(PERL_INC)';
698b39c5158Smillert    my($name,$sys,@m);
699b39c5158Smillert
700b39c5158Smillert    ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
70191f110e0Safresh1    print "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
702b39c5158Smillert         " required to modify CC command for $self->{'BASEEXT'}\n"
703b39c5158Smillert    if ($Config{$name});
704b39c5158Smillert
705b39c5158Smillert    if ($quals =~ / -[DIUOg]/) {
706b39c5158Smillert	while ($quals =~ / -([Og])(\d*)\b/) {
707b39c5158Smillert	    my($type,$lvl) = ($1,$2);
708b39c5158Smillert	    $quals =~ s/ -$type$lvl\b\s*//;
709b39c5158Smillert	    if ($type eq 'g') { $flagoptstr = '/NoOptimize'; }
710b39c5158Smillert	    else { $flagoptstr = '/Optimize' . (defined($lvl) ? "=$lvl" : ''); }
711b39c5158Smillert	}
712b39c5158Smillert	while ($quals =~ / -([DIU])(\S+)/) {
713b39c5158Smillert	    my($type,$def) = ($1,$2);
714b39c5158Smillert	    $quals =~ s/ -$type$def\s*//;
715b39c5158Smillert	    $def =~ s/"/""/g;
716b39c5158Smillert	    if    ($type eq 'D') { $definestr .= qq["$def",]; }
717b39c5158Smillert	    elsif ($type eq 'I') { $incstr .= ',' . $self->fixpath($def,1); }
718b39c5158Smillert	    else                 { $undefstr  .= qq["$def",]; }
719b39c5158Smillert	}
720b39c5158Smillert    }
721b39c5158Smillert    if (length $quals and $quals !~ m!/!) {
722b39c5158Smillert	warn "MM_VMS: Ignoring unrecognized CCFLAGS elements \"$quals\"\n";
723b39c5158Smillert	$quals = '';
724b39c5158Smillert    }
725b39c5158Smillert    $definestr .= q["PERL_POLLUTE",] if $self->{POLLUTE};
726b39c5158Smillert    if (length $definestr) { chop($definestr); $quals .= "/Define=($definestr)"; }
727b39c5158Smillert    if (length $undefstr)  { chop($undefstr);  $quals .= "/Undef=($undefstr)";   }
728b39c5158Smillert    # Deal with $self->{DEFINE} here since some C compilers pay attention
729b39c5158Smillert    # to only one /Define clause on command line, so we have to
730b39c5158Smillert    # conflate the ones from $Config{'ccflags'} and $self->{DEFINE}
731b39c5158Smillert    # ($self->{DEFINE} has already been VMSified in constants() above)
732b39c5158Smillert    if ($self->{DEFINE}) { $quals .= $self->{DEFINE}; }
733b39c5158Smillert    for my $type (qw(Def Undef)) {
734b39c5158Smillert	my(@terms);
735b39c5158Smillert	while ($quals =~ m:/${type}i?n?e?=([^/]+):ig) {
736b39c5158Smillert		my $term = $1;
737b39c5158Smillert		$term =~ s:^\((.+)\)$:$1:;
738b39c5158Smillert		push @terms, $term;
739b39c5158Smillert	}
740b39c5158Smillert	if ($type eq 'Def') {
741b39c5158Smillert	    push @terms, qw[ $(DEFINE_VERSION) $(XS_DEFINE_VERSION) ];
742b39c5158Smillert	}
743b39c5158Smillert	if (@terms) {
744b39c5158Smillert	    $quals =~ s:/${type}i?n?e?=[^/]+::ig;
7459f11ffb7Safresh1            # PASTHRU_DEFINE will have its own comma
7469f11ffb7Safresh1	    $quals .= "/${type}ine=(" . join(',',@terms) . ($type eq 'Def' ? '$(PASTHRU_DEFINE)' : '') . ')';
747b39c5158Smillert	}
748b39c5158Smillert    }
749b39c5158Smillert
750b39c5158Smillert    $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
751b39c5158Smillert
752b39c5158Smillert    # Likewise with $self->{INC} and /Include
753b39c5158Smillert    if ($self->{'INC'}) {
754b39c5158Smillert	my(@includes) = split(/\s+/,$self->{INC});
755b39c5158Smillert	foreach (@includes) {
756b39c5158Smillert	    s/^-I//;
757b39c5158Smillert	    $incstr .= ','.$self->fixpath($_,1);
758b39c5158Smillert	}
759b39c5158Smillert    }
760b39c5158Smillert    $quals .= "$incstr)";
761b39c5158Smillert#    $quals =~ s/,,/,/g; $quals =~ s/\(,/(/g;
762b39c5158Smillert    $self->{CCFLAGS} = $quals;
763b39c5158Smillert
764b39c5158Smillert    $self->{PERLTYPE} ||= '';
765b39c5158Smillert
766b39c5158Smillert    $self->{OPTIMIZE} ||= $flagoptstr || $Config{'optimize'};
767b39c5158Smillert    if ($self->{OPTIMIZE} !~ m!/!) {
768b39c5158Smillert	if    ($self->{OPTIMIZE} =~ m!-g!) { $self->{OPTIMIZE} = '/Debug/NoOptimize' }
769b39c5158Smillert	elsif ($self->{OPTIMIZE} =~ /-O(\d*)/) {
770b39c5158Smillert	    $self->{OPTIMIZE} = '/Optimize' . (defined($1) ? "=$1" : '');
771b39c5158Smillert	}
772b39c5158Smillert	else {
773b39c5158Smillert	    warn "MM_VMS: Can't parse OPTIMIZE \"$self->{OPTIMIZE}\"; using default\n" if length $self->{OPTIMIZE};
774b39c5158Smillert	    $self->{OPTIMIZE} = '/Optimize';
775b39c5158Smillert	}
776b39c5158Smillert    }
777b39c5158Smillert
778b39c5158Smillert    return $self->{CFLAGS} = qq{
779b39c5158SmillertCCFLAGS = $self->{CCFLAGS}
780b39c5158SmillertOPTIMIZE = $self->{OPTIMIZE}
781b39c5158SmillertPERLTYPE = $self->{PERLTYPE}
782b39c5158Smillert};
783b39c5158Smillert}
784b39c5158Smillert
785b39c5158Smillert=item const_cccmd (override)
786b39c5158Smillert
787b39c5158SmillertAdds directives to point C preprocessor to the right place when
788b39c5158Smillerthandling #include E<lt>sys/foo.hE<gt> directives.  Also constructs CC
789b39c5158Smillertcommand line a bit differently than MM_Unix method.
790b39c5158Smillert
791b39c5158Smillert=cut
792b39c5158Smillert
793b39c5158Smillertsub const_cccmd {
794b39c5158Smillert    my($self,$libperl) = @_;
795b39c5158Smillert    my(@m);
796b39c5158Smillert
797b39c5158Smillert    return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
798b39c5158Smillert    return '' unless $self->needs_linking();
799b39c5158Smillert    if ($Config{'vms_cc_type'} eq 'gcc') {
800b39c5158Smillert        push @m,'
801b39c5158Smillert.FIRST
802b39c5158Smillert	',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
803b39c5158Smillert    }
804b39c5158Smillert    elsif ($Config{'vms_cc_type'} eq 'vaxc') {
805b39c5158Smillert        push @m,'
806b39c5158Smillert.FIRST
807b39c5158Smillert	',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
808b39c5158Smillert	',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
809b39c5158Smillert    }
810b39c5158Smillert    else {
811b39c5158Smillert        push @m,'
812b39c5158Smillert.FIRST
813b39c5158Smillert	',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
814b39c5158Smillert		($Config{'archname'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
815b39c5158Smillert	',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
816b39c5158Smillert    }
817b39c5158Smillert
818b39c5158Smillert    push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
819b39c5158Smillert
820b39c5158Smillert    $self->{CONST_CCCMD} = join('',@m);
821b39c5158Smillert}
822b39c5158Smillert
823b39c5158Smillert
824b39c5158Smillert=item tools_other (override)
825b39c5158Smillert
826b39c5158SmillertThrow in some dubious extra macros for Makefile args.
827b39c5158Smillert
828b39c5158SmillertAlso keep around the old $(SAY) macro in case somebody's using it.
829b39c5158Smillert
830b39c5158Smillert=cut
831b39c5158Smillert
832b39c5158Smillertsub tools_other {
833b39c5158Smillert    my($self) = @_;
834b39c5158Smillert
835b39c5158Smillert    # XXX Are these necessary?  Does anyone override them?  They're longer
836b39c5158Smillert    # than just typing the literal string.
837b39c5158Smillert    my $extra_tools = <<'EXTRA_TOOLS';
838b39c5158Smillert
839b39c5158Smillert# Just in case anyone is using the old macro.
840b39c5158SmillertUSEMACROS = $(MACROSTART)
841b39c5158SmillertSAY = $(ECHO)
842b39c5158Smillert
843b39c5158SmillertEXTRA_TOOLS
844b39c5158Smillert
845b39c5158Smillert    return $self->SUPER::tools_other . $extra_tools;
846b39c5158Smillert}
847b39c5158Smillert
848b39c5158Smillert=item init_dist (override)
849b39c5158Smillert
850b39c5158SmillertVMSish defaults for some values.
851b39c5158Smillert
852b39c5158Smillert  macro         description                     default
853b39c5158Smillert
854b39c5158Smillert  ZIPFLAGS      flags to pass to ZIP            -Vu
855b39c5158Smillert
856b39c5158Smillert  COMPRESS      compression command to          gzip
857b39c5158Smillert                use for tarfiles
858b39c5158Smillert  SUFFIX        suffix to put on                -gz
859b39c5158Smillert                compressed files
860b39c5158Smillert
861b39c5158Smillert  SHAR          shar command to use             vms_share
862b39c5158Smillert
863b39c5158Smillert  DIST_DEFAULT  default target to use to        tardist
864b39c5158Smillert                create a distribution
865b39c5158Smillert
866b39c5158Smillert  DISTVNAME     Use VERSION_SYM instead of      $(DISTNAME)-$(VERSION_SYM)
867b39c5158Smillert                VERSION for the name
868b39c5158Smillert
869b39c5158Smillert=cut
870b39c5158Smillert
871b39c5158Smillertsub init_dist {
872b39c5158Smillert    my($self) = @_;
873b39c5158Smillert    $self->{ZIPFLAGS}     ||= '-Vu';
874b39c5158Smillert    $self->{COMPRESS}     ||= 'gzip';
875b39c5158Smillert    $self->{SUFFIX}       ||= '-gz';
876b39c5158Smillert    $self->{SHAR}         ||= 'vms_share';
877b39c5158Smillert    $self->{DIST_DEFAULT} ||= 'zipdist';
878b39c5158Smillert
879b39c5158Smillert    $self->SUPER::init_dist;
880b39c5158Smillert
881b39c5158Smillert    $self->{DISTVNAME} = "$self->{DISTNAME}-$self->{VERSION_SYM}"
882b39c5158Smillert      unless $self->{ARGS}{DISTVNAME};
883b39c5158Smillert
884b39c5158Smillert    return;
885b39c5158Smillert}
886b39c5158Smillert
887b39c5158Smillert=item c_o (override)
888b39c5158Smillert
889b39c5158SmillertUse VMS syntax on command line.  In particular, $(DEFINE) and
890b39c5158Smillert$(PERL_INC) have been pulled into $(CCCMD).  Also use MM[SK] macros.
891b39c5158Smillert
892b39c5158Smillert=cut
893b39c5158Smillert
894b39c5158Smillertsub c_o {
895b39c5158Smillert    my($self) = @_;
896b39c5158Smillert    return '' unless $self->needs_linking();
897b39c5158Smillert    '
898b39c5158Smillert.c$(OBJ_EXT) :
8999f11ffb7Safresh1	$(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
900b39c5158Smillert
901b39c5158Smillert.cpp$(OBJ_EXT) :
9029f11ffb7Safresh1	$(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
903b39c5158Smillert
904b39c5158Smillert.cxx$(OBJ_EXT) :
9059f11ffb7Safresh1	$(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
906b39c5158Smillert
907b39c5158Smillert';
908b39c5158Smillert}
909b39c5158Smillert
910b39c5158Smillert=item xs_c (override)
911b39c5158Smillert
912b39c5158SmillertUse MM[SK] macros.
913b39c5158Smillert
914b39c5158Smillert=cut
915b39c5158Smillert
916b39c5158Smillertsub xs_c {
917b39c5158Smillert    my($self) = @_;
918b39c5158Smillert    return '' unless $self->needs_linking();
919b39c5158Smillert    '
920b39c5158Smillert.xs.c :
9219f11ffb7Safresh1	$(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).xsc
9229f11ffb7Safresh1	$(MV) $(MMS$TARGET_NAME).xsc $(MMS$TARGET_NAME).c
923b39c5158Smillert';
924b39c5158Smillert}
925b39c5158Smillert
926b39c5158Smillert=item xs_o (override)
927b39c5158Smillert
928b39c5158SmillertUse MM[SK] macros, and VMS command line for C compiler.
929b39c5158Smillert
930b39c5158Smillert=cut
931b39c5158Smillert
9329f11ffb7Safresh1sub xs_o {
933b39c5158Smillert    my ($self) = @_;
934b39c5158Smillert    return '' unless $self->needs_linking();
9359f11ffb7Safresh1    my $frag = '
936b39c5158Smillert.xs$(OBJ_EXT) :
9379f11ffb7Safresh1	$(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).xsc
9389f11ffb7Safresh1	$(MV) $(MMS$TARGET_NAME).xsc $(MMS$TARGET_NAME).c
9399f11ffb7Safresh1	$(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
940b39c5158Smillert';
9419f11ffb7Safresh1    if ($self->{XSMULTI}) {
9429f11ffb7Safresh1	for my $ext ($self->_xs_list_basenames) {
9439f11ffb7Safresh1	    my $version = $self->parse_version("$ext.pm");
9449f11ffb7Safresh1	    my $ccflags = $self->{CCFLAGS};
9459f11ffb7Safresh1	    $ccflags =~ s/\$\(DEFINE_VERSION\)/\"VERSION_MACRO=\\"\"$version\\"\"/;
9469f11ffb7Safresh1	    $ccflags =~ s/\$\(XS_DEFINE_VERSION\)/\"XS_VERSION_MACRO=\\"\"$version\\"\"/;
9479f11ffb7Safresh1	    $self->_xsbuild_replace_macro($ccflags, 'xs', $ext, 'INC');
9489f11ffb7Safresh1	    $self->_xsbuild_replace_macro($ccflags, 'xs', $ext, 'DEFINE');
9499f11ffb7Safresh1
9509f11ffb7Safresh1	    $frag .= _sprintf562 <<'EOF', $ext, $ccflags;
9519f11ffb7Safresh1
9529f11ffb7Safresh1%1$s$(OBJ_EXT) : %1$s.xs
9539f11ffb7Safresh1	$(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs > $(MMS$TARGET_NAME).xsc
9549f11ffb7Safresh1	$(MV) $(MMS$TARGET_NAME).xsc $(MMS$TARGET_NAME).c
9559f11ffb7Safresh1	$(CC)%2$s$(OPTIMIZE) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
9569f11ffb7Safresh1EOF
9579f11ffb7Safresh1	}
9589f11ffb7Safresh1    }
9599f11ffb7Safresh1    $frag;
960b39c5158Smillert}
961b39c5158Smillert
9629f11ffb7Safresh1=item _xsbuild_replace_macro (override)
9639f11ffb7Safresh1
9649f11ffb7Safresh1There is no simple replacement possible since a qualifier and all its
9659f11ffb7Safresh1subqualifiers must be considered together, so we use our own utility
9669f11ffb7Safresh1routine for the replacement.
9679f11ffb7Safresh1
9689f11ffb7Safresh1=cut
9699f11ffb7Safresh1
9709f11ffb7Safresh1sub _xsbuild_replace_macro {
9719f11ffb7Safresh1    my ($self, undef, $xstype, $ext, $varname) = @_;
9729f11ffb7Safresh1    my $value = $self->_xsbuild_value($xstype, $ext, $varname);
9739f11ffb7Safresh1    return unless defined $value;
9749f11ffb7Safresh1    $_[1] = _vms_replace_qualifier($self, $_[1], $value, $varname);
9759f11ffb7Safresh1}
9769f11ffb7Safresh1
9779f11ffb7Safresh1=item _xsbuild_value (override)
9789f11ffb7Safresh1
9799f11ffb7Safresh1Convert the extension spec to Unix format, as that's what will
9809f11ffb7Safresh1match what's in the XSBUILD data structure.
9819f11ffb7Safresh1
9829f11ffb7Safresh1=cut
9839f11ffb7Safresh1
9849f11ffb7Safresh1sub _xsbuild_value {
9859f11ffb7Safresh1    my ($self, $xstype, $ext, $varname) = @_;
9869f11ffb7Safresh1    $ext = unixify($ext);
9879f11ffb7Safresh1    return $self->SUPER::_xsbuild_value($xstype, $ext, $varname);
9889f11ffb7Safresh1}
9899f11ffb7Safresh1
9909f11ffb7Safresh1sub _vms_replace_qualifier {
9919f11ffb7Safresh1    my ($self, $flags, $newflag, $macro) = @_;
9929f11ffb7Safresh1    my $qual_type;
9939f11ffb7Safresh1    my $type_suffix;
9949f11ffb7Safresh1    my $quote_subquals = 0;
9959f11ffb7Safresh1    my @subquals_new = split /\s+/, $newflag;
9969f11ffb7Safresh1
9979f11ffb7Safresh1    if ($macro eq 'DEFINE') {
9989f11ffb7Safresh1        $qual_type = 'Def';
9999f11ffb7Safresh1        $type_suffix = 'ine';
10009f11ffb7Safresh1        map { $_ =~ s/^-D// } @subquals_new;
10019f11ffb7Safresh1        $quote_subquals = 1;
10029f11ffb7Safresh1    }
10039f11ffb7Safresh1    elsif ($macro eq 'INC') {
10049f11ffb7Safresh1        $qual_type = 'Inc';
10059f11ffb7Safresh1        $type_suffix = 'lude';
10069f11ffb7Safresh1        map { $_ =~ s/^-I//; $_ = $self->fixpath($_) } @subquals_new;
10079f11ffb7Safresh1    }
10089f11ffb7Safresh1
10099f11ffb7Safresh1    my @subquals = ();
10109f11ffb7Safresh1    while ($flags =~ m:/${qual_type}\S{0,4}=([^/]+):ig) {
10119f11ffb7Safresh1        my $term = $1;
10129f11ffb7Safresh1        $term =~ s/\"//g;
10139f11ffb7Safresh1        $term =~ s:^\((.+)\)$:$1:;
10149f11ffb7Safresh1        push @subquals, split /,/, $term;
10159f11ffb7Safresh1    }
10169f11ffb7Safresh1    for my $new (@subquals_new) {
10179f11ffb7Safresh1        my ($sq_new, $sqval_new) = split /=/, $new;
10189f11ffb7Safresh1        my $replaced_old = 0;
10199f11ffb7Safresh1        for my $old (@subquals) {
10209f11ffb7Safresh1            my ($sq, $sqval) = split /=/, $old;
10219f11ffb7Safresh1            if ($sq_new eq $sq) {
10229f11ffb7Safresh1                $old = $sq_new;
10239f11ffb7Safresh1                $old .= '=' . $sqval_new if defined($sqval_new) and length($sqval_new);
10249f11ffb7Safresh1                $replaced_old = 1;
10259f11ffb7Safresh1                last;
10269f11ffb7Safresh1            }
10279f11ffb7Safresh1        }
10289f11ffb7Safresh1        push @subquals, $new unless $replaced_old;
10299f11ffb7Safresh1    }
10309f11ffb7Safresh1
10319f11ffb7Safresh1    if (@subquals) {
10329f11ffb7Safresh1        $flags =~ s:/${qual_type}\S{0,4}=[^/]+::ig;
10339f11ffb7Safresh1        # add quotes if requested but not for unexpanded macros
10349f11ffb7Safresh1        map { $_ = qq/"$_"/ if $_ !~ m/^\$\(/ } @subquals if $quote_subquals;
10359f11ffb7Safresh1        $flags .= "/${qual_type}$type_suffix=(" . join(',',@subquals) . ')';
10369f11ffb7Safresh1    }
10379f11ffb7Safresh1
10389f11ffb7Safresh1    return $flags;
10399f11ffb7Safresh1}
10409f11ffb7Safresh1
10419f11ffb7Safresh1
10429f11ffb7Safresh1sub xs_dlsyms_ext {
10439f11ffb7Safresh1    '.opt';
10449f11ffb7Safresh1}
1045b39c5158Smillert
1046b39c5158Smillert=item dlsyms (override)
1047b39c5158Smillert
1048b39c5158SmillertCreate VMS linker options files specifying universal symbols for this
10499f11ffb7Safresh1extension's shareable image(s), and listing other shareable images or
1050b39c5158Smillertlibraries to which it should be linked.
1051b39c5158Smillert
1052b39c5158Smillert=cut
1053b39c5158Smillert
1054b39c5158Smillertsub dlsyms {
1055b39c5158Smillert    my ($self, %attribs) = @_;
10569f11ffb7Safresh1    return '' unless $self->needs_linking;
10579f11ffb7Safresh1    $self->xs_dlsyms_iterator;
1058b39c5158Smillert}
1059b39c5158Smillert
10609f11ffb7Safresh1sub xs_make_dlsyms {
10619f11ffb7Safresh1    my ($self, $attribs, $target, $dep, $name, $dlbase, $funcs, $funclist, $imports, $vars, $extra) = @_;
10629f11ffb7Safresh1    my @m;
10639f11ffb7Safresh1    my $instloc;
10649f11ffb7Safresh1    if ($self->{XSMULTI}) {
10659f11ffb7Safresh1	my ($v, $d, $f) = File::Spec->splitpath($target);
10669f11ffb7Safresh1	my @d = File::Spec->splitdir($d);
10679f11ffb7Safresh1	shift @d if $d[0] eq 'lib';
10689f11ffb7Safresh1	$instloc = $self->catfile('$(INST_ARCHLIB)', 'auto', @d, $f);
10699f11ffb7Safresh1	push @m,"\ndynamic :: $instloc\n\t\$(NOECHO) \$(NOOP)\n"
10709f11ffb7Safresh1	  unless $self->{SKIPHASH}{'dynamic'};
10719f11ffb7Safresh1	push @m,"\nstatic :: $instloc\n\t\$(NOECHO) \$(NOOP)\n"
10729f11ffb7Safresh1	  unless $self->{SKIPHASH}{'static'};
10739f11ffb7Safresh1	push @m, "\n", sprintf <<'EOF', $instloc, $target;
10749f11ffb7Safresh1%s : %s
1075b39c5158Smillert	$(CP) $(MMS$SOURCE) $(MMS$TARGET)
10769f11ffb7Safresh1EOF
10779f11ffb7Safresh1    }
10789f11ffb7Safresh1    else {
10799f11ffb7Safresh1	push @m,"\ndynamic :: \$(INST_ARCHAUTODIR)$self->{BASEEXT}.opt\n\t\$(NOECHO) \$(NOOP)\n"
10809f11ffb7Safresh1	  unless $self->{SKIPHASH}{'dynamic'};
10819f11ffb7Safresh1	push @m,"\nstatic :: \$(INST_ARCHAUTODIR)$self->{BASEEXT}.opt\n\t\$(NOECHO) \$(NOOP)\n"
10829f11ffb7Safresh1	  unless $self->{SKIPHASH}{'static'};
10839f11ffb7Safresh1	push @m, "\n", sprintf <<'EOF', $target;
10849f11ffb7Safresh1$(INST_ARCHAUTODIR)$(BASEEXT).opt : %s
10859f11ffb7Safresh1	$(CP) $(MMS$SOURCE) $(MMS$TARGET)
10869f11ffb7Safresh1EOF
10879f11ffb7Safresh1    }
10889f11ffb7Safresh1    push @m,
10899f11ffb7Safresh1     "\n$target : $dep\n\t",
10909f11ffb7Safresh1     q!$(PERLRUN) -MExtUtils::Mksymlists -e "Mksymlists('NAME'=>'!, $name,
10919f11ffb7Safresh1     q!', 'DLBASE' => '!,$dlbase,
10929f11ffb7Safresh1     q!', 'DL_FUNCS' => !,neatvalue($funcs),
10939f11ffb7Safresh1     q!, 'FUNCLIST' => !,neatvalue($funclist),
10949f11ffb7Safresh1     q!, 'IMPORTS' => !,neatvalue($imports),
10959f11ffb7Safresh1     q!, 'DL_VARS' => !, neatvalue($vars);
10969f11ffb7Safresh1    push @m, $extra if defined $extra;
10979f11ffb7Safresh1    push @m, qq!);"\n\t!;
10989f11ffb7Safresh1    # Can't use dlbase as it's been through mod2fname.
10999f11ffb7Safresh1    my $olb_base = basename($target, '.opt');
11009f11ffb7Safresh1    if ($self->{XSMULTI}) {
11019f11ffb7Safresh1        # We've been passed everything but the kitchen sink -- and the location of the
11029f11ffb7Safresh1        # static library we're using to build the dynamic library -- so concoct that
11039f11ffb7Safresh1        # location from what we do have.
11049f11ffb7Safresh1        my $olb_dir = $self->catdir(dirname($instloc), $olb_base);
11059f11ffb7Safresh1        push @m, qq!\$(PERL) -e "print ""${olb_dir}${olb_base}\$(LIB_EXT)/Include=!;
11069f11ffb7Safresh1        push @m, ($Config{d_vms_case_sensitive_symbols} ? uc($olb_base) : $olb_base);
11079f11ffb7Safresh1        push @m, '\n' . $olb_dir . $olb_base . '$(LIB_EXT)/Library\n"";" >>$(MMS$TARGET)',"\n";
11089f11ffb7Safresh1    }
11099f11ffb7Safresh1    else {
11109f11ffb7Safresh1        push @m, qq!\$(PERL) -e "print ""\$(INST_ARCHAUTODIR)${olb_base}\$(LIB_EXT)/Include=!;
1111b39c5158Smillert        if ($self->{OBJECT} =~ /\bBASEEXT\b/ or
1112b39c5158Smillert            $self->{OBJECT} =~ /\b$self->{BASEEXT}\b/i) {
1113b39c5158Smillert            push @m, ($Config{d_vms_case_sensitive_symbols}
1114b39c5158Smillert	              ? uc($self->{BASEEXT}) :'$(BASEEXT)');
1115b39c5158Smillert        }
1116b39c5158Smillert        else {  # We don't have a "main" object file, so pull 'em all in
1117b39c5158Smillert            # Upcase module names if linker is being case-sensitive
1118b39c5158Smillert            my($upcase) = $Config{d_vms_case_sensitive_symbols};
1119b39c5158Smillert            my(@omods) = split ' ', $self->eliminate_macros($self->{OBJECT});
1120b39c5158Smillert            for (@omods) {
1121b39c5158Smillert                s/\.[^.]*$//;         # Trim off file type
1122b39c5158Smillert                s[\$\(\w+_EXT\)][];   # even as a macro
1123b39c5158Smillert                s/.*[:>\/\]]//;       # Trim off dir spec
1124b39c5158Smillert                $_ = uc if $upcase;
1125b39c5158Smillert            };
1126b39c5158Smillert            my(@lines);
1127b39c5158Smillert            my $tmp = shift @omods;
1128b39c5158Smillert            foreach my $elt (@omods) {
1129b39c5158Smillert                $tmp .= ",$elt";
1130b39c5158Smillert                if (length($tmp) > 80) { push @lines, $tmp;  $tmp = ''; }
1131b39c5158Smillert            }
1132b39c5158Smillert            push @lines, $tmp;
1133b39c5158Smillert            push @m, '(', join( qq[, -\\n\\t"";" >>\$(MMS\$TARGET)\n\t\$(PERL) -e "print ""], @lines),')';
1134b39c5158Smillert        }
11359f11ffb7Safresh1        push @m, '\n$(INST_ARCHAUTODIR)' . $olb_base . '$(LIB_EXT)/Library\n"";" >>$(MMS$TARGET)',"\n";
11369f11ffb7Safresh1    }
1137b39c5158Smillert    if (length $self->{LDLOADLIBS}) {
1138b39c5158Smillert        my($line) = '';
1139b39c5158Smillert        foreach my $lib (split ' ', $self->{LDLOADLIBS}) {
1140b39c5158Smillert            $lib =~ s%\$%\\\$%g;  # Escape '$' in VMS filespecs
1141b39c5158Smillert            if (length($line) + length($lib) > 160) {
1142b39c5158Smillert                push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n";
1143b39c5158Smillert                $line = $lib . '\n';
1144b39c5158Smillert            }
1145b39c5158Smillert            else { $line .= $lib . '\n'; }
1146b39c5158Smillert        }
1147b39c5158Smillert        push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n" if $line;
1148b39c5158Smillert    }
11499f11ffb7Safresh1    join '', @m;
11509f11ffb7Safresh1}
1151b39c5158Smillert
1152b39c5158Smillert
11539f11ffb7Safresh1=item xs_obj_opt
11549f11ffb7Safresh1
11559f11ffb7Safresh1Override to fixup -o flags.
11569f11ffb7Safresh1
11579f11ffb7Safresh1=cut
11589f11ffb7Safresh1
11599f11ffb7Safresh1sub xs_obj_opt {
11609f11ffb7Safresh1    my ($self, $output_file) = @_;
11619f11ffb7Safresh1    "/OBJECT=$output_file";
1162b39c5158Smillert}
1163b39c5158Smillert
1164b39c5158Smillert=item dynamic_lib (override)
1165b39c5158Smillert
1166b39c5158SmillertUse VMS Link command.
1167b39c5158Smillert
1168b39c5158Smillert=cut
1169b39c5158Smillert
11709f11ffb7Safresh1sub xs_dynamic_lib_macros {
11719f11ffb7Safresh1    my ($self, $attribs) = @_;
11729f11ffb7Safresh1    my $otherldflags = $attribs->{OTHERLDFLAGS} || "";
11739f11ffb7Safresh1    my $inst_dynamic_dep = $attribs->{INST_DYNAMIC_DEP} || "";
11749f11ffb7Safresh1    sprintf <<'EOF', $otherldflags, $inst_dynamic_dep;
11759f11ffb7Safresh1# This section creates the dynamically loadable objects from relevant
11769f11ffb7Safresh1# objects and possibly $(MYEXTLIB).
11779f11ffb7Safresh1OTHERLDFLAGS = %s
11789f11ffb7Safresh1INST_DYNAMIC_DEP = %s
11799f11ffb7Safresh1EOF
1180b39c5158Smillert}
1181b39c5158Smillert
11829f11ffb7Safresh1sub xs_make_dynamic_lib {
11839f11ffb7Safresh1    my ($self, $attribs, $from, $to, $todir, $ldfrom, $exportlist) = @_;
11849f11ffb7Safresh1    my $shr = $Config{'dbgprefix'} . 'PerlShr';
11859f11ffb7Safresh1    $exportlist =~ s/.def$/.opt/;  # it's a linker options file
11869f11ffb7Safresh1    #                    1    2       3            4     5
11879f11ffb7Safresh1    _sprintf562 <<'EOF', $to, $todir, $exportlist, $shr, "$shr Sys\$Share:$shr.$Config{'dlext'}";
11889f11ffb7Safresh1%1$s : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt %2$s$(DFSEP).exists %3$s $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
11899f11ffb7Safresh1	If F$TrnLNm("%4$s").eqs."" Then Define/NoLog/User %5$s
11909f11ffb7Safresh1	Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) %3$s/Option,$(PERL_INC)perlshr_attr.opt/Option
11919f11ffb7Safresh1EOF
11929f11ffb7Safresh1}
1193b39c5158Smillert
11949f11ffb7Safresh1=item xs_make_static_lib (override)
1195b39c5158Smillert
1196b39c5158SmillertUse VMS commands to manipulate object library.
1197b39c5158Smillert
1198b39c5158Smillert=cut
1199b39c5158Smillert
12009f11ffb7Safresh1sub xs_make_static_lib {
12019f11ffb7Safresh1    my ($self, $object, $to, $todir) = @_;
1202b39c5158Smillert
12039f11ffb7Safresh1    my @objects;
12049f11ffb7Safresh1    if ($self->{XSMULTI}) {
12059f11ffb7Safresh1        # The extension name should be the main object file name minus file type.
12069f11ffb7Safresh1        my $lib = $object;
12079f11ffb7Safresh1        $lib =~ s/\$\(OBJ_EXT\)\z//;
12089f11ffb7Safresh1        my $override = $self->_xsbuild_value('xs', $lib, 'OBJECT');
12099f11ffb7Safresh1        $object = $override if defined $override;
12109f11ffb7Safresh1        @objects = map { $self->fixpath($_,0) } split /(?<!\^)\s+/, $object;
12119f11ffb7Safresh1    }
12129f11ffb7Safresh1    else {
12139f11ffb7Safresh1        push @objects, $object;
12149f11ffb7Safresh1    }
1215b39c5158Smillert
12169f11ffb7Safresh1    my @m;
12179f11ffb7Safresh1    for my $obj (@objects) {
12189f11ffb7Safresh1        push(@m, sprintf "\n%s : %s\$(DFSEP).exists", $obj, $todir);
12199f11ffb7Safresh1    }
12209f11ffb7Safresh1    push(@m, sprintf "\n\n%s : %s \$(MYEXTLIB)\n", $to, (join ' ', @objects));
1221b39c5158Smillert
1222b39c5158Smillert    # If this extension has its own library (eg SDBM_File)
1223b39c5158Smillert    # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1224b39c5158Smillert    push(@m, "\t",'$(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1225b39c5158Smillert
1226b39c5158Smillert    push(@m,"\t",'If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)',"\n");
1227b39c5158Smillert
1228b39c5158Smillert    # if there was a library to copy, then we can't use MMS$SOURCE_LIST,
1229b39c5158Smillert    # 'cause it's a library and you can't stick them in other libraries.
1230b39c5158Smillert    # In that case, we use $OBJECT instead and hope for the best
1231b39c5158Smillert    if ($self->{MYEXTLIB}) {
12329f11ffb7Safresh1        for my $obj (@objects) {
12339f11ffb7Safresh1            push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) ' . $obj,"\n");
12349f11ffb7Safresh1        }
12359f11ffb7Safresh1    }
12369f11ffb7Safresh1    else {
1237b39c5158Smillert      push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)',"\n");
1238b39c5158Smillert    }
1239b39c5158Smillert
1240b39c5158Smillert    push @m, "\t\$(NOECHO) \$(PERL) -e 1 >\$(INST_ARCHAUTODIR)extralibs.ld\n";
1241b39c5158Smillert    foreach my $lib (split ' ', $self->{EXTRALIBS}) {
1242b39c5158Smillert      push(@m,"\t",'$(NOECHO) $(PERL) -e "print qq{',$lib,'\n}" >>$(INST_ARCHAUTODIR)extralibs.ld',"\n");
1243b39c5158Smillert    }
1244b39c5158Smillert    join('',@m);
1245b39c5158Smillert}
1246b39c5158Smillert
1247b39c5158Smillert
12489f11ffb7Safresh1=item static_lib_pure_cmd (override)
12499f11ffb7Safresh1
12509f11ffb7Safresh1Use VMS commands to manipulate object library.
12519f11ffb7Safresh1
12529f11ffb7Safresh1=cut
12539f11ffb7Safresh1
12549f11ffb7Safresh1sub static_lib_pure_cmd {
12559f11ffb7Safresh1    my ($self, $from) = @_;
12569f11ffb7Safresh1
12579f11ffb7Safresh1    sprintf <<'MAKE_FRAG', $from;
12589f11ffb7Safresh1	If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
12599f11ffb7Safresh1	Library/Object/Replace $(MMS$TARGET) %s
12609f11ffb7Safresh1MAKE_FRAG
12619f11ffb7Safresh1}
12629f11ffb7Safresh1
12639f11ffb7Safresh1=item xs_static_lib_is_xs
12649f11ffb7Safresh1
12659f11ffb7Safresh1=cut
12669f11ffb7Safresh1
12679f11ffb7Safresh1sub xs_static_lib_is_xs {
12689f11ffb7Safresh1    return 1;
12699f11ffb7Safresh1}
12709f11ffb7Safresh1
1271b39c5158Smillert=item extra_clean_files
1272b39c5158Smillert
1273b39c5158SmillertClean up some OS specific files.  Plus the temp file used to shorten
1274898184e3Ssthena lot of commands.  And the name mangler database.
1275b39c5158Smillert
1276b39c5158Smillert=cut
1277b39c5158Smillert
1278b39c5158Smillertsub extra_clean_files {
1279b39c5158Smillert    return qw(
1280b39c5158Smillert              *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *.Opt $(BASEEXT).bso
1281898184e3Ssthen              .MM_Tmp cxx_repository
1282b39c5158Smillert             );
1283b39c5158Smillert}
1284b39c5158Smillert
1285b39c5158Smillert
1286b39c5158Smillert=item zipfile_target
1287b39c5158Smillert
1288b39c5158Smillert=item tarfile_target
1289b39c5158Smillert
1290b39c5158Smillert=item shdist_target
1291b39c5158Smillert
1292b39c5158SmillertSyntax for invoking shar, tar and zip differs from that for Unix.
1293b39c5158Smillert
1294b39c5158Smillert=cut
1295b39c5158Smillert
1296b39c5158Smillertsub zipfile_target {
1297b39c5158Smillert    my($self) = shift;
1298b39c5158Smillert
1299b39c5158Smillert    return <<'MAKE_FRAG';
1300b39c5158Smillert$(DISTVNAME).zip : distdir
1301b39c5158Smillert	$(PREOP)
1302b39c5158Smillert	$(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) [.$(DISTVNAME)...]*.*;
1303b39c5158Smillert	$(RM_RF) $(DISTVNAME)
1304b39c5158Smillert	$(POSTOP)
1305b39c5158SmillertMAKE_FRAG
1306b39c5158Smillert}
1307b39c5158Smillert
1308b39c5158Smillertsub tarfile_target {
1309b39c5158Smillert    my($self) = shift;
1310b39c5158Smillert
1311b39c5158Smillert    return <<'MAKE_FRAG';
1312b39c5158Smillert$(DISTVNAME).tar$(SUFFIX) : distdir
1313b39c5158Smillert	$(PREOP)
1314b39c5158Smillert	$(TO_UNIX)
1315b39c5158Smillert	$(TAR) "$(TARFLAGS)" $(DISTVNAME).tar [.$(DISTVNAME)...]
1316b39c5158Smillert	$(RM_RF) $(DISTVNAME)
1317b39c5158Smillert	$(COMPRESS) $(DISTVNAME).tar
1318b39c5158Smillert	$(POSTOP)
1319b39c5158SmillertMAKE_FRAG
1320b39c5158Smillert}
1321b39c5158Smillert
1322b39c5158Smillertsub shdist_target {
1323b39c5158Smillert    my($self) = shift;
1324b39c5158Smillert
1325b39c5158Smillert    return <<'MAKE_FRAG';
1326b39c5158Smillertshdist : distdir
1327b39c5158Smillert	$(PREOP)
1328b39c5158Smillert	$(SHAR) [.$(DISTVNAME)...]*.*; $(DISTVNAME).share
1329b39c5158Smillert	$(RM_RF) $(DISTVNAME)
1330b39c5158Smillert	$(POSTOP)
1331b39c5158SmillertMAKE_FRAG
1332b39c5158Smillert}
1333b39c5158Smillert
1334b39c5158Smillert
1335b39c5158Smillert# --- Test and Installation Sections ---
1336b39c5158Smillert
1337b39c5158Smillert=item install (override)
1338b39c5158Smillert
1339b39c5158SmillertWork around DCL's 255 character limit several times,and use
1340b39c5158SmillertVMS-style command line quoting in a few cases.
1341b39c5158Smillert
1342b39c5158Smillert=cut
1343b39c5158Smillert
1344b39c5158Smillertsub install {
1345b39c5158Smillert    my($self, %attribs) = @_;
1346b39c5158Smillert    my(@m);
1347b39c5158Smillert
1348b39c5158Smillert    push @m, q[
1349b39c5158Smillertinstall :: all pure_install doc_install
1350b39c5158Smillert	$(NOECHO) $(NOOP)
1351b39c5158Smillert
1352b39c5158Smillertinstall_perl :: all pure_perl_install doc_perl_install
1353b39c5158Smillert	$(NOECHO) $(NOOP)
1354b39c5158Smillert
1355b39c5158Smillertinstall_site :: all pure_site_install doc_site_install
1356b39c5158Smillert	$(NOECHO) $(NOOP)
1357b39c5158Smillert
1358b8851fccSafresh1install_vendor :: all pure_vendor_install doc_vendor_install
1359b8851fccSafresh1	$(NOECHO) $(NOOP)
1360b8851fccSafresh1
1361b39c5158Smillertpure_install :: pure_$(INSTALLDIRS)_install
1362b39c5158Smillert	$(NOECHO) $(NOOP)
1363b39c5158Smillert
1364b39c5158Smillertdoc_install :: doc_$(INSTALLDIRS)_install
1365b39c5158Smillert	$(NOECHO) $(NOOP)
1366b39c5158Smillert
1367b39c5158Smillertpure__install : pure_site_install
1368b39c5158Smillert	$(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1369b39c5158Smillert
1370b39c5158Smillertdoc__install : doc_site_install
1371b39c5158Smillert	$(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1372b39c5158Smillert
1373b39c5158Smillert# This hack brought to you by DCL's 255-character command line limit
1374b39c5158Smillertpure_perl_install ::
13756fb12b70Safresh1];
13766fb12b70Safresh1    push @m,
1377b8851fccSafresh1q[	$(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read|'.File::Spec->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').'|'" >.MM_tmp
1378b8851fccSafresh1	$(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write|'.File::Spec->catfile('$(DESTINSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').'|'" >>.MM_tmp
13796fb12b70Safresh1] unless $self->{NO_PACKLIST};
13806fb12b70Safresh1
13816fb12b70Safresh1    push @m,
1382b8851fccSafresh1q[	$(NOECHO) $(ECHO_N) "$(INST_LIB)|$(DESTINSTALLPRIVLIB)|" >>.MM_tmp
1383b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_ARCHLIB)|$(DESTINSTALLARCHLIB)|" >>.MM_tmp
1384b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_BIN)|$(DESTINSTALLBIN)|" >>.MM_tmp
1385b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_SCRIPT)|$(DESTINSTALLSCRIPT)|" >>.MM_tmp
1386b39c5158Smillert	$(NOECHO) $(ECHO_N) "$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) " >>.MM_tmp
1387b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_MAN3DIR)|$(DESTINSTALLMAN3DIR)" >>.MM_tmp
1388b39c5158Smillert	$(NOECHO) $(MOD_INSTALL) <.MM_tmp
1389b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1390b8851fccSafresh1	$(NOECHO) $(WARN_IF_OLD_PACKLIST) "].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q["
1391b39c5158Smillert
1392b39c5158Smillert# Likewise
1393b39c5158Smillertpure_site_install ::
13946fb12b70Safresh1];
13956fb12b70Safresh1    push @m,
1396b8851fccSafresh1q[	$(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read|'.File::Spec->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').'|'" >.MM_tmp
1397b8851fccSafresh1	$(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write|'.File::Spec->catfile('$(DESTINSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').'|'" >>.MM_tmp
13986fb12b70Safresh1] unless $self->{NO_PACKLIST};
13996fb12b70Safresh1
14006fb12b70Safresh1    push @m,
1401b8851fccSafresh1q[	$(NOECHO) $(ECHO_N) "$(INST_LIB)|$(DESTINSTALLSITELIB)|" >>.MM_tmp
1402b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_ARCHLIB)|$(DESTINSTALLSITEARCH)|" >>.MM_tmp
1403b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_BIN)|$(DESTINSTALLSITEBIN)|" >>.MM_tmp
1404b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_SCRIPT)|$(DESTINSTALLSCRIPT)|" >>.MM_tmp
1405b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_MAN1DIR)|$(DESTINSTALLSITEMAN1DIR)|" >>.MM_tmp
1406b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_MAN3DIR)|$(DESTINSTALLSITEMAN3DIR)" >>.MM_tmp
1407b39c5158Smillert	$(NOECHO) $(MOD_INSTALL) <.MM_tmp
1408b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1409b8851fccSafresh1	$(NOECHO) $(WARN_IF_OLD_PACKLIST) "].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q["
1410b39c5158Smillert
1411b39c5158Smillertpure_vendor_install ::
14126fb12b70Safresh1];
14136fb12b70Safresh1    push @m,
1414b8851fccSafresh1q[	$(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read|'.File::Spec->catfile('$(VENDORARCHEXP)','auto','$(FULLEXT)','.packlist').'|'" >.MM_tmp
1415b8851fccSafresh1	$(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write|'.File::Spec->catfile('$(DESTINSTALLVENDORARCH)','auto','$(FULLEXT)','.packlist').'|'" >>.MM_tmp
14166fb12b70Safresh1] unless $self->{NO_PACKLIST};
14176fb12b70Safresh1
14186fb12b70Safresh1    push @m,
1419b8851fccSafresh1q[	$(NOECHO) $(ECHO_N) "$(INST_LIB)|$(DESTINSTALLVENDORLIB)|" >>.MM_tmp
1420b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_ARCHLIB)|$(DESTINSTALLVENDORARCH)|" >>.MM_tmp
1421b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_BIN)|$(DESTINSTALLVENDORBIN)|" >>.MM_tmp
1422b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_SCRIPT)|$(DESTINSTALLSCRIPT)|" >>.MM_tmp
1423b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_MAN1DIR)|$(DESTINSTALLVENDORMAN1DIR)|" >>.MM_tmp
1424b8851fccSafresh1	$(NOECHO) $(ECHO_N) "$(INST_MAN3DIR)|$(DESTINSTALLVENDORMAN3DIR)" >>.MM_tmp
1425b39c5158Smillert	$(NOECHO) $(MOD_INSTALL) <.MM_tmp
1426b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1427b39c5158Smillert
14286fb12b70Safresh1];
14296fb12b70Safresh1
14306fb12b70Safresh1    push @m, q[
14316fb12b70Safresh1# Ditto
14326fb12b70Safresh1doc_perl_install ::
14336fb12b70Safresh1	$(NOECHO) $(NOOP)
14346fb12b70Safresh1
14356fb12b70Safresh1# And again
14366fb12b70Safresh1doc_site_install ::
14376fb12b70Safresh1	$(NOECHO) $(NOOP)
14386fb12b70Safresh1
14396fb12b70Safresh1doc_vendor_install ::
14406fb12b70Safresh1	$(NOECHO) $(NOOP)
14416fb12b70Safresh1
14426fb12b70Safresh1] if $self->{NO_PERLLOCAL};
14436fb12b70Safresh1
14446fb12b70Safresh1    push @m, q[
1445b39c5158Smillert# Ditto
1446b39c5158Smillertdoc_perl_install ::
1447b39c5158Smillert	$(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1448b39c5158Smillert	$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1449b39c5158Smillert	$(NOECHO) $(ECHO_N) "installed into|$(INSTALLPRIVLIB)|" >.MM_tmp
1450b39c5158Smillert	$(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1451b39c5158Smillert	$(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1452b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1453b39c5158Smillert
1454b39c5158Smillert# And again
1455b39c5158Smillertdoc_site_install ::
1456b39c5158Smillert	$(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1457b39c5158Smillert	$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1458b39c5158Smillert	$(NOECHO) $(ECHO_N) "installed into|$(INSTALLSITELIB)|" >.MM_tmp
1459b39c5158Smillert	$(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1460b39c5158Smillert	$(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1461b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1462b39c5158Smillert
1463b39c5158Smillertdoc_vendor_install ::
1464b39c5158Smillert	$(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1465b39c5158Smillert	$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1466b39c5158Smillert	$(NOECHO) $(ECHO_N) "installed into|$(INSTALLVENDORLIB)|" >.MM_tmp
1467b39c5158Smillert	$(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1468b39c5158Smillert	$(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1469b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1470b39c5158Smillert
14716fb12b70Safresh1] unless $self->{NO_PERLLOCAL};
1472b39c5158Smillert
1473b39c5158Smillert    push @m, q[
1474b39c5158Smillertuninstall :: uninstall_from_$(INSTALLDIRS)dirs
1475b39c5158Smillert	$(NOECHO) $(NOOP)
1476b39c5158Smillert
1477b39c5158Smillertuninstall_from_perldirs ::
1478b39c5158Smillert	$(NOECHO) $(UNINSTALL) ].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[
1479b39c5158Smillert
1480b39c5158Smillertuninstall_from_sitedirs ::
1481b39c5158Smillert	$(NOECHO) $(UNINSTALL) ].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[
1482b8851fccSafresh1
1483b8851fccSafresh1uninstall_from_vendordirs ::
1484b8851fccSafresh1	$(NOECHO) $(UNINSTALL) ].$self->catfile($self->{VENDORARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[
1485b39c5158Smillert];
1486b39c5158Smillert
1487b39c5158Smillert    join('',@m);
1488b39c5158Smillert}
1489b39c5158Smillert
1490b39c5158Smillert=item perldepend (override)
1491b39c5158Smillert
1492b39c5158SmillertUse VMS-style syntax for files; it's cheaper to just do it directly here
149356d68f1eSafresh1than to have the L<MM_Unix|ExtUtils::MM_Unix> method call C<catfile>
149456d68f1eSafresh1repeatedly.  Also, if we have to rebuild Config.pm, use MM[SK] to do it.
1495b39c5158Smillert
1496b39c5158Smillert=cut
1497b39c5158Smillert
1498b39c5158Smillertsub perldepend {
1499b39c5158Smillert    my($self) = @_;
1500b39c5158Smillert    my(@m);
1501b39c5158Smillert
150291f110e0Safresh1    if ($self->{OBJECT}) {
150391f110e0Safresh1        # Need to add an object file dependency on the perl headers.
150491f110e0Safresh1        # this is very important for XS modules in perl.git development.
1505b39c5158Smillert
150691f110e0Safresh1        push @m, $self->_perl_header_files_fragment(""); # empty separator on VMS as its in the $(PERL_INC)
150791f110e0Safresh1    }
1508b39c5158Smillert
1509b39c5158Smillert    if ($self->{PERL_SRC}) {
1510b39c5158Smillert	my(@macros);
1511b39c5158Smillert	my($mmsquals) = '$(USEMAKEFILE)[.vms]$(FIRST_MAKEFILE)';
1512b39c5158Smillert	push(@macros,'__AXP__=1') if $Config{'archname'} eq 'VMS_AXP';
1513b39c5158Smillert	push(@macros,'DECC=1')    if $Config{'vms_cc_type'} eq 'decc';
1514b39c5158Smillert	push(@macros,'GNUC=1')    if $Config{'vms_cc_type'} eq 'gcc';
1515b39c5158Smillert	push(@macros,'SOCKET=1')  if $Config{'d_has_sockets'};
1516b39c5158Smillert	push(@macros,qq["CC=$Config{'cc'}"])  if $Config{'cc'} =~ m!/!;
1517b39c5158Smillert	$mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1518b39c5158Smillert	push(@m,q[
1519b39c5158Smillert# Check for unpropagated config.sh changes. Should never happen.
1520b39c5158Smillert# We do NOT just update config.h because that is not sufficient.
1521b39c5158Smillert# An out of date config.h is not fatal but complains loudly!
1522b39c5158Smillert$(PERL_INC)config.h : $(PERL_SRC)config.sh
1523b39c5158Smillert	$(NOOP)
1524b39c5158Smillert
1525b39c5158Smillert$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1526b39c5158Smillert	$(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.h or genconfig.pl"
1527b39c5158Smillert	olddef = F$Environment("Default")
1528b39c5158Smillert	Set Default $(PERL_SRC)
1529b39c5158Smillert	$(MMS)],$mmsquals,);
1530b39c5158Smillert	if ($self->{PERL_ARCHLIB} =~ m|\[-| && $self->{PERL_SRC} =~ m|(\[-+)|) {
1531b39c5158Smillert	    my($prefix,$target) = ($1,$self->fixpath('$(PERL_ARCHLIB)Config.pm',0));
1532b39c5158Smillert	    $target =~ s/\Q$prefix/[/;
1533b39c5158Smillert	    push(@m," $target");
1534b39c5158Smillert	}
1535b39c5158Smillert	else { push(@m,' $(MMS$TARGET)'); }
1536b39c5158Smillert	push(@m,q[
1537b39c5158Smillert	Set Default 'olddef'
1538b39c5158Smillert]);
1539b39c5158Smillert    }
1540b39c5158Smillert
15419f11ffb7Safresh1    push(@m, join(" ", map($self->fixpath($_,0),sort values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1542b39c5158Smillert      if %{$self->{XS}};
1543b39c5158Smillert
1544b39c5158Smillert    join('',@m);
1545b39c5158Smillert}
1546b39c5158Smillert
1547b39c5158Smillert
1548b39c5158Smillert=item makeaperl (override)
1549b39c5158Smillert
1550b39c5158SmillertUndertake to build a new set of Perl images using VMS commands.  Since
1551b39c5158SmillertVMS does dynamic loading, it's not necessary to statically link each
1552b39c5158Smillertextension into the Perl image, so this isn't the normal build path.
1553b39c5158SmillertConsequently, it hasn't really been tested, and may well be incomplete.
1554b39c5158Smillert
1555b39c5158Smillert=cut
1556b39c5158Smillert
1557b39c5158Smillertour %olbs;  # needs to be localized
1558b39c5158Smillert
1559b39c5158Smillertsub makeaperl {
1560b39c5158Smillert    my($self, %attribs) = @_;
1561b39c5158Smillert    my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmpdir, $libperl) =
1562b39c5158Smillert      @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
1563b39c5158Smillert    my(@m);
1564b39c5158Smillert    push @m, "
1565b39c5158Smillert# --- MakeMaker makeaperl section ---
1566b39c5158SmillertMAP_TARGET    = $target
1567b39c5158Smillert";
1568b39c5158Smillert    return join '', @m if $self->{PARENT};
1569b39c5158Smillert
1570b39c5158Smillert    my($dir) = join ":", @{$self->{DIR}};
1571b39c5158Smillert
1572b39c5158Smillert    unless ($self->{MAKEAPERL}) {
1573b39c5158Smillert	push @m, q{
1574b39c5158Smillert$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
1575b39c5158Smillert	$(NOECHO) $(ECHO) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
1576b39c5158Smillert	$(NOECHO) $(PERLRUNINST) \
1577b39c5158Smillert		Makefile.PL DIR=}, $dir, q{ \
1578b39c5158Smillert		FIRST_MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
1579b39c5158Smillert		MAKEAPERL=1 NORECURS=1 };
1580b39c5158Smillert
1581b39c5158Smillert	push @m, map(q[ \\\n\t\t"$_"], @ARGV),q{
1582b39c5158Smillert
1583b39c5158Smillert$(MAP_TARGET) :: $(MAKE_APERL_FILE)
1584b39c5158Smillert	$(MAKE)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
1585b39c5158Smillert};
1586b39c5158Smillert	push @m, "\n";
1587b39c5158Smillert
1588b39c5158Smillert	return join '', @m;
1589b39c5158Smillert    }
1590b39c5158Smillert
1591b39c5158Smillert
1592b39c5158Smillert    my($linkcmd,@optlibs,@staticpkgs,$extralist,$targdir,$libperldir,%libseen);
1593b39c5158Smillert    local($_);
1594b39c5158Smillert
1595b39c5158Smillert    # The front matter of the linkcommand...
1596b39c5158Smillert    $linkcmd = join ' ', $Config{'ld'},
1597b39c5158Smillert	    grep($_, @Config{qw(large split ldflags ccdlflags)});
1598b39c5158Smillert    $linkcmd =~ s/\s+/ /g;
1599b39c5158Smillert
1600b39c5158Smillert    # Which *.olb files could we make use of...
1601b39c5158Smillert    local(%olbs);       # XXX can this be lexical?
1602b39c5158Smillert    $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
1603b39c5158Smillert    require File::Find;
1604b39c5158Smillert    File::Find::find(sub {
1605b39c5158Smillert	return unless m/\Q$self->{LIB_EXT}\E$/;
1606b39c5158Smillert	return if m/^libperl/;
1607b39c5158Smillert
1608b39c5158Smillert	if( exists $self->{INCLUDE_EXT} ){
1609b39c5158Smillert		my $found = 0;
1610b39c5158Smillert
1611b39c5158Smillert		(my $xx = $File::Find::name) =~ s,.*?/auto/,,;
1612b39c5158Smillert		$xx =~ s,/?$_,,;
1613b39c5158Smillert		$xx =~ s,/,::,g;
1614b39c5158Smillert
1615b39c5158Smillert		# Throw away anything not explicitly marked for inclusion.
1616b39c5158Smillert		# DynaLoader is implied.
1617b39c5158Smillert		foreach my $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
1618b39c5158Smillert			if( $xx eq $incl ){
1619b39c5158Smillert				$found++;
1620b39c5158Smillert				last;
1621b39c5158Smillert			}
1622b39c5158Smillert		}
1623b39c5158Smillert		return unless $found;
1624b39c5158Smillert	}
1625b39c5158Smillert	elsif( exists $self->{EXCLUDE_EXT} ){
1626b39c5158Smillert		(my $xx = $File::Find::name) =~ s,.*?/auto/,,;
1627b39c5158Smillert		$xx =~ s,/?$_,,;
1628b39c5158Smillert		$xx =~ s,/,::,g;
1629b39c5158Smillert
1630b39c5158Smillert		# Throw away anything explicitly marked for exclusion
1631b39c5158Smillert		foreach my $excl (@{$self->{EXCLUDE_EXT}}){
1632b39c5158Smillert			return if( $xx eq $excl );
1633b39c5158Smillert		}
1634b39c5158Smillert	}
1635b39c5158Smillert
1636b39c5158Smillert	$olbs{$ENV{DEFAULT}} = $_;
1637b39c5158Smillert    }, grep( -d $_, @{$searchdirs || []}));
1638b39c5158Smillert
1639b39c5158Smillert    # We trust that what has been handed in as argument will be buildable
1640b39c5158Smillert    $static = [] unless $static;
1641b39c5158Smillert    @olbs{@{$static}} = (1) x @{$static};
1642b39c5158Smillert
1643b39c5158Smillert    $extra = [] unless $extra && ref $extra eq 'ARRAY';
1644b39c5158Smillert    # Sort the object libraries in inverse order of
1645b39c5158Smillert    # filespec length to try to insure that dependent extensions
1646b39c5158Smillert    # will appear before their parents, so the linker will
1647b39c5158Smillert    # search the parent library to resolve references.
1648b39c5158Smillert    # (e.g. Intuit::DWIM will precede Intuit, so unresolved
1649b39c5158Smillert    # references from [.intuit.dwim]dwim.obj can be found
1650b39c5158Smillert    # in [.intuit]intuit.olb).
16519f11ffb7Safresh1    for (sort { length($a) <=> length($b) || $a cmp $b } keys %olbs) {
1652b39c5158Smillert	next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
1653b39c5158Smillert	my($dir) = $self->fixpath($_,1);
1654b39c5158Smillert	my($extralibs) = $dir . "extralibs.ld";
1655b39c5158Smillert	my($extopt) = $dir . $olbs{$_};
1656b39c5158Smillert	$extopt =~ s/$self->{LIB_EXT}$/.opt/;
1657b39c5158Smillert	push @optlibs, "$dir$olbs{$_}";
1658b39c5158Smillert	# Get external libraries this extension will need
1659b39c5158Smillert	if (-f $extralibs ) {
1660b39c5158Smillert	    my %seenthis;
1661b39c5158Smillert	    open my $list, "<", $extralibs or warn $!,next;
1662b39c5158Smillert	    while (<$list>) {
1663b39c5158Smillert		chomp;
1664b39c5158Smillert		# Include a library in the link only once, unless it's mentioned
1665b39c5158Smillert		# multiple times within a single extension's options file, in which
1666b39c5158Smillert		# case we assume the builder needed to search it again later in the
1667b39c5158Smillert		# link.
1668b39c5158Smillert		my $skip = exists($libseen{$_}) && !exists($seenthis{$_});
1669b39c5158Smillert		$libseen{$_}++;  $seenthis{$_}++;
1670b39c5158Smillert		next if $skip;
1671b39c5158Smillert		push @$extra,$_;
1672b39c5158Smillert	    }
1673b39c5158Smillert	}
1674b39c5158Smillert	# Get full name of extension for ExtUtils::Miniperl
1675b39c5158Smillert	if (-f $extopt) {
1676b39c5158Smillert	    open my $opt, '<', $extopt or die $!;
1677b39c5158Smillert	    while (<$opt>) {
1678b39c5158Smillert		next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
1679b39c5158Smillert		my $pkg = $1;
1680b39c5158Smillert		$pkg =~ s#__*#::#g;
1681b39c5158Smillert		push @staticpkgs,$pkg;
1682b39c5158Smillert	    }
1683b39c5158Smillert	}
1684b39c5158Smillert    }
1685b39c5158Smillert    # Place all of the external libraries after all of the Perl extension
1686b39c5158Smillert    # libraries in the final link, in order to maximize the opportunity
1687b39c5158Smillert    # for XS code from multiple extensions to resolve symbols against the
1688b39c5158Smillert    # same external library while only including that library once.
1689b39c5158Smillert    push @optlibs, @$extra;
1690b39c5158Smillert
1691b39c5158Smillert    $target = "Perl$Config{'exe_ext'}" unless $target;
1692b39c5158Smillert    my $shrtarget;
1693b39c5158Smillert    ($shrtarget,$targdir) = fileparse($target);
1694b39c5158Smillert    $shrtarget =~ s/^([^.]*)/$1Shr/;
1695b39c5158Smillert    $shrtarget = $targdir . $shrtarget;
1696b39c5158Smillert    $target = "Perlshr.$Config{'dlext'}" unless $target;
1697b39c5158Smillert    $tmpdir = "[]" unless $tmpdir;
1698b39c5158Smillert    $tmpdir = $self->fixpath($tmpdir,1);
1699b39c5158Smillert    if (@optlibs) { $extralist = join(' ',@optlibs); }
1700b39c5158Smillert    else          { $extralist = ''; }
1701b39c5158Smillert    # Let ExtUtils::Liblist find the necessary libs for us (but skip PerlShr)
1702b39c5158Smillert    # that's what we're building here).
1703b39c5158Smillert    push @optlibs, grep { !/PerlShr/i } split ' ', +($self->ext())[2];
1704b39c5158Smillert    if ($libperl) {
1705b39c5158Smillert	unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
170691f110e0Safresh1	    print "Warning: $libperl not found\n";
1707b39c5158Smillert	    undef $libperl;
1708b39c5158Smillert	}
1709b39c5158Smillert    }
1710b39c5158Smillert    unless ($libperl) {
1711b39c5158Smillert	if (defined $self->{PERL_SRC}) {
1712b39c5158Smillert	    $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
1713b39c5158Smillert	} elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
1714b39c5158Smillert	} else {
171591f110e0Safresh1	    print "Warning: $libperl not found
1716b39c5158Smillert    If you're going to build a static perl binary, make sure perl is installed
1717b39c5158Smillert    otherwise ignore this warning\n";
1718b39c5158Smillert	}
1719b39c5158Smillert    }
1720b39c5158Smillert    $libperldir = $self->fixpath((fileparse($libperl))[1],1);
1721b39c5158Smillert
1722b39c5158Smillert    push @m, '
1723b39c5158Smillert# Fill in the target you want to produce if it\'s not perl
1724b39c5158SmillertMAP_TARGET    = ',$self->fixpath($target,0),'
1725b39c5158SmillertMAP_SHRTARGET = ',$self->fixpath($shrtarget,0),"
1726b39c5158SmillertMAP_LINKCMD   = $linkcmd
1727b39c5158SmillertMAP_PERLINC   = ", $perlinc ? map('"$_" ',@{$perlinc}) : '',"
1728b39c5158SmillertMAP_EXTRA     = $extralist
1729b39c5158SmillertMAP_LIBPERL = ",$self->fixpath($libperl,0),'
1730b39c5158Smillert';
1731b39c5158Smillert
1732b39c5158Smillert
1733b39c5158Smillert    push @m,"\n${tmpdir}Makeaperl.Opt : \$(MAP_EXTRA)\n";
1734b39c5158Smillert    foreach (@optlibs) {
1735b39c5158Smillert	push @m,'	$(NOECHO) $(PERL) -e "print q{',$_,'}" >>$(MMS$TARGET)',"\n";
1736b39c5158Smillert    }
1737b39c5158Smillert    push @m,"\n${tmpdir}PerlShr.Opt :\n\t";
1738b39c5158Smillert    push @m,'$(NOECHO) $(PERL) -e "print q{$(MAP_SHRTARGET)}" >$(MMS$TARGET)',"\n";
1739b39c5158Smillert
1740b39c5158Smillert    push @m,'
1741b39c5158Smillert$(MAP_SHRTARGET) : $(MAP_LIBPERL) Makeaperl.Opt ',"${libperldir}Perlshr_Attr.Opt",'
1742b39c5158Smillert	$(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_LIBPERL), Makeaperl.Opt/Option ',"${libperldir}Perlshr_Attr.Opt/Option",'
1743b39c5158Smillert$(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}PerlShr.Opt",'
1744b39c5158Smillert	$(MAP_LINKCMD) ',"${tmpdir}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
1745b39c5158Smillert	$(NOECHO) $(ECHO) "To install the new ""$(MAP_TARGET)"" binary, say"
1746b39c5158Smillert	$(NOECHO) $(ECHO) "    $(MAKE)$(USEMAKEFILE)$(FIRST_MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
1747b39c5158Smillert	$(NOECHO) $(ECHO) "To remove the intermediate files, say
1748b39c5158Smillert	$(NOECHO) $(ECHO) "    $(MAKE)$(USEMAKEFILE)$(FIRST_MAKEFILE) map_clean"
1749b39c5158Smillert';
1750b39c5158Smillert    push @m,"\n${tmpdir}perlmain.c : \$(FIRST_MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmpdir}Writemain.tmp\n";
1751b39c5158Smillert    push @m, "# More from the 255-char line length limit\n";
1752b39c5158Smillert    foreach (@staticpkgs) {
1753b39c5158Smillert	push @m,'	$(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmpdir}Writemain.tmp\n];
1754b39c5158Smillert    }
1755b39c5158Smillert
1756b39c5158Smillert    push @m, sprintf <<'MAKE_FRAG', $tmpdir, $tmpdir;
1757b39c5158Smillert	$(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" %sWritemain.tmp >$(MMS$TARGET)
1758b39c5158Smillert	$(NOECHO) $(RM_F) %sWritemain.tmp
1759b39c5158SmillertMAKE_FRAG
1760b39c5158Smillert
1761b39c5158Smillert    push @m, q[
1762b39c5158Smillert# Still more from the 255-char line length limit
1763b39c5158Smillertdoc_inst_perl :
1764b39c5158Smillert	$(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1765b39c5158Smillert	$(NOECHO) $(ECHO) "Perl binary $(MAP_TARGET)|" >.MM_tmp
1766b39c5158Smillert	$(NOECHO) $(ECHO) "MAP_STATIC|$(MAP_STATIC)|" >>.MM_tmp
1767b39c5158Smillert	$(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
1768b39c5158Smillert	$(NOECHO) $(ECHO) -e "MAP_LIBPERL|$(MAP_LIBPERL)|" >>.MM_tmp
1769b39c5158Smillert	$(NOECHO) $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(DESTINSTALLARCHLIB)','perllocal.pod').q[
1770b39c5158Smillert	$(NOECHO) $(RM_F) .MM_tmp
1771b39c5158Smillert];
1772b39c5158Smillert
1773b39c5158Smillert    push @m, "
1774b39c5158Smillertinst_perl : pure_inst_perl doc_inst_perl
1775b39c5158Smillert	\$(NOECHO) \$(NOOP)
1776b39c5158Smillert
1777b39c5158Smillertpure_inst_perl : \$(MAP_TARGET)
1778b39c5158Smillert	$self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
1779b39c5158Smillert	$self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
1780b39c5158Smillert
1781b39c5158Smillertclean :: map_clean
1782b39c5158Smillert	\$(NOECHO) \$(NOOP)
1783b39c5158Smillert
1784b39c5158Smillertmap_clean :
1785b39c5158Smillert	\$(RM_F) ${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}perlmain.c \$(FIRST_MAKEFILE)
1786b39c5158Smillert	\$(RM_F) ${tmpdir}Makeaperl.Opt ${tmpdir}PerlShr.Opt \$(MAP_TARGET)
1787b39c5158Smillert";
1788b39c5158Smillert
1789b39c5158Smillert    join '', @m;
1790b39c5158Smillert}
1791b39c5158Smillert
1792b39c5158Smillert
1793b39c5158Smillert# --- Output postprocessing section ---
1794b39c5158Smillert
1795b39c5158Smillert=item maketext_filter (override)
1796b39c5158Smillert
17979f11ffb7Safresh1Ensure that colons marking targets are preceded by space, in order
1798b39c5158Smillertto distinguish the target delimiter from a colon appearing as
1799b39c5158Smillertpart of a filespec.
1800b39c5158Smillert
1801b39c5158Smillert=cut
1802b39c5158Smillert
1803b39c5158Smillertsub maketext_filter {
1804b39c5158Smillert    my($self, $text) = @_;
1805b39c5158Smillert
1806b39c5158Smillert    $text =~ s/^([^\s:=]+)(:+\s)/$1 $2/mg;
1807b39c5158Smillert    return $text;
1808b39c5158Smillert}
1809b39c5158Smillert
1810b39c5158Smillert=item prefixify (override)
1811b39c5158Smillert
1812b39c5158Smillertprefixifying on VMS is simple.  Each should simply be:
1813b39c5158Smillert
1814b39c5158Smillert    perl_root:[some.dir]
1815b39c5158Smillert
1816b39c5158Smillertwhich can just be converted to:
1817b39c5158Smillert
1818b39c5158Smillert    volume:[your.prefix.some.dir]
1819b39c5158Smillert
1820b39c5158Smillertotherwise you get the default layout.
1821b39c5158Smillert
1822b39c5158SmillertIn effect, your search prefix is ignored and $Config{vms_prefix} is
1823b39c5158Smillertused instead.
1824b39c5158Smillert
1825b39c5158Smillert=cut
1826b39c5158Smillert
1827b39c5158Smillertsub prefixify {
1828b39c5158Smillert    my($self, $var, $sprefix, $rprefix, $default) = @_;
1829b39c5158Smillert
1830b39c5158Smillert    # Translate $(PERLPREFIX) to a real path.
1831b39c5158Smillert    $rprefix = $self->eliminate_macros($rprefix);
1832b39c5158Smillert    $rprefix = vmspath($rprefix) if $rprefix;
1833b39c5158Smillert    $sprefix = vmspath($sprefix) if $sprefix;
1834b39c5158Smillert
1835b39c5158Smillert    $default = vmsify($default)
1836b39c5158Smillert      unless $default =~ /\[.*\]/;
1837b39c5158Smillert
1838b39c5158Smillert    (my $var_no_install = $var) =~ s/^install//;
1839b39c5158Smillert    my $path = $self->{uc $var} ||
1840b39c5158Smillert               $ExtUtils::MM_Unix::Config_Override{lc $var} ||
1841b39c5158Smillert               $Config{lc $var} || $Config{lc $var_no_install};
1842b39c5158Smillert
1843b39c5158Smillert    if( !$path ) {
184491f110e0Safresh1        warn "  no Config found for $var.\n" if $Verbose >= 2;
1845b39c5158Smillert        $path = $self->_prefixify_default($rprefix, $default);
1846b39c5158Smillert    }
1847b39c5158Smillert    elsif( !$self->{ARGS}{PREFIX} || !$self->file_name_is_absolute($path) ) {
1848b39c5158Smillert        # do nothing if there's no prefix or if its relative
1849b39c5158Smillert    }
1850b39c5158Smillert    elsif( $sprefix eq $rprefix ) {
185191f110e0Safresh1        warn "  no new prefix.\n" if $Verbose >= 2;
1852b39c5158Smillert    }
1853b39c5158Smillert    else {
1854b39c5158Smillert
185591f110e0Safresh1        warn "  prefixify $var => $path\n"     if $Verbose >= 2;
185691f110e0Safresh1        warn "    from $sprefix to $rprefix\n" if $Verbose >= 2;
1857b39c5158Smillert
1858b39c5158Smillert        my($path_vol, $path_dirs) = $self->splitpath( $path );
1859b39c5158Smillert        if( $path_vol eq $Config{vms_prefix}.':' ) {
186091f110e0Safresh1            warn "  $Config{vms_prefix}: seen\n" if $Verbose >= 2;
1861b39c5158Smillert
1862b39c5158Smillert            $path_dirs =~ s{^\[}{\[.} unless $path_dirs =~ m{^\[\.};
1863b39c5158Smillert            $path = $self->_catprefix($rprefix, $path_dirs);
1864b39c5158Smillert        }
1865b39c5158Smillert        else {
1866b39c5158Smillert            $path = $self->_prefixify_default($rprefix, $default);
1867b39c5158Smillert        }
1868b39c5158Smillert    }
1869b39c5158Smillert
1870b39c5158Smillert    print "    now $path\n" if $Verbose >= 2;
1871b39c5158Smillert    return $self->{uc $var} = $path;
1872b39c5158Smillert}
1873b39c5158Smillert
1874b39c5158Smillert
1875b39c5158Smillertsub _prefixify_default {
1876b39c5158Smillert    my($self, $rprefix, $default) = @_;
1877b39c5158Smillert
187891f110e0Safresh1    warn "  cannot prefix, using default.\n" if $Verbose >= 2;
1879b39c5158Smillert
1880b39c5158Smillert    if( !$default ) {
188191f110e0Safresh1        warn "No default!\n" if $Verbose >= 1;
1882b39c5158Smillert        return;
1883b39c5158Smillert    }
1884b39c5158Smillert    if( !$rprefix ) {
188591f110e0Safresh1        warn "No replacement prefix!\n" if $Verbose >= 1;
1886b39c5158Smillert        return '';
1887b39c5158Smillert    }
1888b39c5158Smillert
1889b39c5158Smillert    return $self->_catprefix($rprefix, $default);
1890b39c5158Smillert}
1891b39c5158Smillert
1892b39c5158Smillertsub _catprefix {
1893b39c5158Smillert    my($self, $rprefix, $default) = @_;
1894b39c5158Smillert
1895b39c5158Smillert    my($rvol, $rdirs) = $self->splitpath($rprefix);
1896b39c5158Smillert    if( $rvol ) {
1897b39c5158Smillert        return $self->catpath($rvol,
1898b39c5158Smillert                                   $self->catdir($rdirs, $default),
1899b39c5158Smillert                                   ''
1900b39c5158Smillert                                  )
1901b39c5158Smillert    }
1902b39c5158Smillert    else {
1903b39c5158Smillert        return $self->catdir($rdirs, $default);
1904b39c5158Smillert    }
1905b39c5158Smillert}
1906b39c5158Smillert
1907b39c5158Smillert
1908b39c5158Smillert=item cd
1909b39c5158Smillert
1910b39c5158Smillert=cut
1911b39c5158Smillert
1912b39c5158Smillertsub cd {
1913b39c5158Smillert    my($self, $dir, @cmds) = @_;
1914b39c5158Smillert
1915b39c5158Smillert    $dir = vmspath($dir);
1916b39c5158Smillert
1917b39c5158Smillert    my $cmd = join "\n\t", map "$_", @cmds;
1918b39c5158Smillert
1919b39c5158Smillert    # No leading tab makes it look right when embedded
1920b39c5158Smillert    my $make_frag = sprintf <<'MAKE_FRAG', $dir, $cmd;
1921b39c5158Smillertstartdir = F$Environment("Default")
1922b39c5158Smillert	Set Default %s
1923b39c5158Smillert	%s
1924b39c5158Smillert	Set Default 'startdir'
1925b39c5158SmillertMAKE_FRAG
1926b39c5158Smillert
1927b39c5158Smillert    # No trailing newline makes this easier to embed
1928b39c5158Smillert    chomp $make_frag;
1929b39c5158Smillert
1930b39c5158Smillert    return $make_frag;
1931b39c5158Smillert}
1932b39c5158Smillert
1933b39c5158Smillert
1934b39c5158Smillert=item oneliner
1935b39c5158Smillert
1936b39c5158Smillert=cut
1937b39c5158Smillert
1938b39c5158Smillertsub oneliner {
1939b39c5158Smillert    my($self, $cmd, $switches) = @_;
1940b39c5158Smillert    $switches = [] unless defined $switches;
1941b39c5158Smillert
1942b39c5158Smillert    # Strip leading and trailing newlines
1943b39c5158Smillert    $cmd =~ s{^\n+}{};
1944b39c5158Smillert    $cmd =~ s{\n+$}{};
1945b39c5158Smillert
1946b8851fccSafresh1    my @cmds = split /\n/, $cmd;
1947b8851fccSafresh1    $cmd = join " \n\t  -e ", map $self->quote_literal($_), @cmds;
1948b39c5158Smillert    $cmd = $self->escape_newlines($cmd);
1949b39c5158Smillert
1950b39c5158Smillert    # Switches must be quoted else they will be lowercased.
1951b39c5158Smillert    $switches = join ' ', map { qq{"$_"} } @$switches;
1952b39c5158Smillert
1953b39c5158Smillert    return qq{\$(ABSPERLRUN) $switches -e $cmd "--"};
1954b39c5158Smillert}
1955b39c5158Smillert
1956b39c5158Smillert
1957b39c5158Smillert=item B<echo>
1958b39c5158Smillert
1959b39c5158Smillertperl trips up on "<foo>" thinking it's an input redirect.  So we use the
19609f11ffb7Safresh1native Write command instead.  Besides, it's faster.
1961b39c5158Smillert
1962b39c5158Smillert=cut
1963b39c5158Smillert
1964b39c5158Smillertsub echo {
1965898184e3Ssthen    my($self, $text, $file, $opts) = @_;
1966b39c5158Smillert
1967898184e3Ssthen    # Compatibility with old options
1968898184e3Ssthen    if( !ref $opts ) {
1969898184e3Ssthen        my $append = $opts;
1970898184e3Ssthen        $opts = { append => $append || 0 };
1971898184e3Ssthen    }
1972898184e3Ssthen    my $opencmd = $opts->{append} ? 'Open/Append' : 'Open/Write';
1973898184e3Ssthen
1974898184e3Ssthen    $opts->{allow_variables} = 0 unless defined $opts->{allow_variables};
1975898184e3Ssthen
1976898184e3Ssthen    my $ql_opts = { allow_variables => $opts->{allow_variables} };
1977b39c5158Smillert
1978b39c5158Smillert    my @cmds = ("\$(NOECHO) $opencmd MMECHOFILE $file ");
1979898184e3Ssthen    push @cmds, map { '$(NOECHO) Write MMECHOFILE '.$self->quote_literal($_, $ql_opts) }
1980b39c5158Smillert                split /\n/, $text;
1981b39c5158Smillert    push @cmds, '$(NOECHO) Close MMECHOFILE';
1982b39c5158Smillert    return @cmds;
1983b39c5158Smillert}
1984b39c5158Smillert
1985b39c5158Smillert
1986b39c5158Smillert=item quote_literal
1987b39c5158Smillert
1988b39c5158Smillert=cut
1989b39c5158Smillert
1990b39c5158Smillertsub quote_literal {
1991898184e3Ssthen    my($self, $text, $opts) = @_;
1992898184e3Ssthen    $opts->{allow_variables} = 1 unless defined $opts->{allow_variables};
1993b39c5158Smillert
1994b39c5158Smillert    # I believe this is all we should need.
1995b39c5158Smillert    $text =~ s{"}{""}g;
1996b39c5158Smillert
1997898184e3Ssthen    $text = $opts->{allow_variables}
1998898184e3Ssthen      ? $self->escape_dollarsigns($text) : $self->escape_all_dollarsigns($text);
1999898184e3Ssthen
2000b39c5158Smillert    return qq{"$text"};
2001b39c5158Smillert}
2002b39c5158Smillert
2003898184e3Ssthen=item escape_dollarsigns
2004898184e3Ssthen
2005898184e3SsthenQuote, don't escape.
2006898184e3Ssthen
2007898184e3Ssthen=cut
2008898184e3Ssthen
2009898184e3Ssthensub escape_dollarsigns {
2010898184e3Ssthen    my($self, $text) = @_;
2011898184e3Ssthen
2012898184e3Ssthen    # Quote dollar signs which are not starting a variable
2013898184e3Ssthen    $text =~ s{\$ (?!\() }{"\$"}gx;
2014898184e3Ssthen
2015898184e3Ssthen    return $text;
2016898184e3Ssthen}
2017898184e3Ssthen
2018898184e3Ssthen
2019898184e3Ssthen=item escape_all_dollarsigns
2020898184e3Ssthen
2021898184e3SsthenQuote, don't escape.
2022898184e3Ssthen
2023898184e3Ssthen=cut
2024898184e3Ssthen
2025898184e3Ssthensub escape_all_dollarsigns {
2026898184e3Ssthen    my($self, $text) = @_;
2027898184e3Ssthen
2028898184e3Ssthen    # Quote dollar signs
2029898184e3Ssthen    $text =~ s{\$}{"\$\"}gx;
2030898184e3Ssthen
2031898184e3Ssthen    return $text;
2032898184e3Ssthen}
2033898184e3Ssthen
2034b39c5158Smillert=item escape_newlines
2035b39c5158Smillert
2036b39c5158Smillert=cut
2037b39c5158Smillert
2038b39c5158Smillertsub escape_newlines {
2039b39c5158Smillert    my($self, $text) = @_;
2040b39c5158Smillert
2041b39c5158Smillert    $text =~ s{\n}{-\n}g;
2042b39c5158Smillert
2043b39c5158Smillert    return $text;
2044b39c5158Smillert}
2045b39c5158Smillert
2046b39c5158Smillert=item max_exec_len
2047b39c5158Smillert
2048b39c5158Smillert256 characters.
2049b39c5158Smillert
2050b39c5158Smillert=cut
2051b39c5158Smillert
2052b39c5158Smillertsub max_exec_len {
2053b39c5158Smillert    my $self = shift;
2054b39c5158Smillert
2055b39c5158Smillert    return $self->{_MAX_EXEC_LEN} ||= 256;
2056b39c5158Smillert}
2057b39c5158Smillert
2058b39c5158Smillert=item init_linker
2059b39c5158Smillert
2060b39c5158Smillert=cut
2061b39c5158Smillert
2062b39c5158Smillertsub init_linker {
2063b39c5158Smillert    my $self = shift;
2064b39c5158Smillert    $self->{EXPORT_LIST} ||= '$(BASEEXT).opt';
2065b39c5158Smillert
2066b39c5158Smillert    my $shr = $Config{dbgprefix} . 'PERLSHR';
2067b39c5158Smillert    if ($self->{PERL_SRC}) {
2068b39c5158Smillert        $self->{PERL_ARCHIVE} ||=
2069b39c5158Smillert          $self->catfile($self->{PERL_SRC}, "$shr.$Config{'dlext'}");
2070b39c5158Smillert    }
2071b39c5158Smillert    else {
2072b39c5158Smillert        $self->{PERL_ARCHIVE} ||=
2073b39c5158Smillert          $ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}";
2074b39c5158Smillert    }
2075b39c5158Smillert
2076b8851fccSafresh1    $self->{PERL_ARCHIVEDEP} ||= '';
2077b39c5158Smillert    $self->{PERL_ARCHIVE_AFTER} ||= '';
2078b39c5158Smillert}
2079b39c5158Smillert
2080b39c5158Smillert
2081b39c5158Smillert=item catdir (override)
2082b39c5158Smillert
2083b39c5158Smillert=item catfile (override)
2084b39c5158Smillert
2085b39c5158SmillertEliminate the macros in the output to the MMS/MMK file.
2086b39c5158Smillert
208756d68f1eSafresh1(L<File::Spec::VMS> used to do this for us, but it's being removed)
2088b39c5158Smillert
2089b39c5158Smillert=cut
2090b39c5158Smillert
2091b39c5158Smillertsub catdir {
2092b39c5158Smillert    my $self = shift;
2093b39c5158Smillert
2094b39c5158Smillert    # Process the macros on VMS MMS/MMK
2095b39c5158Smillert    my @args = map { m{\$\(} ? $self->eliminate_macros($_) : $_  } @_;
2096b39c5158Smillert
2097b39c5158Smillert    my $dir = $self->SUPER::catdir(@args);
2098b39c5158Smillert
2099b39c5158Smillert    # Fix up the directory and force it to VMS format.
2100b39c5158Smillert    $dir = $self->fixpath($dir, 1);
2101b39c5158Smillert
2102b39c5158Smillert    return $dir;
2103b39c5158Smillert}
2104b39c5158Smillert
2105b39c5158Smillertsub catfile {
2106b39c5158Smillert    my $self = shift;
2107b39c5158Smillert
2108b39c5158Smillert    # Process the macros on VMS MMS/MMK
2109b39c5158Smillert    my @args = map { m{\$\(} ? $self->eliminate_macros($_) : $_  } @_;
2110b39c5158Smillert
2111b39c5158Smillert    my $file = $self->SUPER::catfile(@args);
2112b39c5158Smillert
2113b39c5158Smillert    $file = vmsify($file);
2114b39c5158Smillert
2115b39c5158Smillert    return $file
2116b39c5158Smillert}
2117b39c5158Smillert
2118b39c5158Smillert
2119b39c5158Smillert=item eliminate_macros
2120b39c5158Smillert
2121b39c5158SmillertExpands MM[KS]/Make macros in a text string, using the contents of
2122b39c5158Smillertidentically named elements of C<%$self>, and returns the result
2123b39c5158Smillertas a file specification in Unix syntax.
2124b39c5158Smillert
2125b39c5158SmillertNOTE:  This is the canonical version of the method.  The version in
212656d68f1eSafresh1L<File::Spec::VMS> is deprecated.
2127b39c5158Smillert
2128b39c5158Smillert=cut
2129b39c5158Smillert
2130b39c5158Smillertsub eliminate_macros {
2131b39c5158Smillert    my($self,$path) = @_;
2132b39c5158Smillert    return '' unless $path;
2133b39c5158Smillert    $self = {} unless ref $self;
2134b39c5158Smillert
2135b39c5158Smillert    my($npath) = unixify($path);
2136b39c5158Smillert    # sometimes unixify will return a string with an off-by-one trailing null
2137b39c5158Smillert    $npath =~ s{\0$}{};
2138b39c5158Smillert
2139b39c5158Smillert    my($complex) = 0;
2140b39c5158Smillert    my($head,$macro,$tail);
2141b39c5158Smillert
2142b39c5158Smillert    # perform m##g in scalar context so it acts as an iterator
2143b39c5158Smillert    while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#gs) {
2144b39c5158Smillert        if (defined $self->{$2}) {
2145b39c5158Smillert            ($head,$macro,$tail) = ($1,$2,$3);
2146b39c5158Smillert            if (ref $self->{$macro}) {
2147b39c5158Smillert                if (ref $self->{$macro} eq 'ARRAY') {
2148b39c5158Smillert                    $macro = join ' ', @{$self->{$macro}};
2149b39c5158Smillert                }
2150b39c5158Smillert                else {
2151b39c5158Smillert                    print "Note: can't expand macro \$($macro) containing ",ref($self->{$macro}),
2152b39c5158Smillert                          "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n";
2153b39c5158Smillert                    $macro = "\cB$macro\cB";
2154b39c5158Smillert                    $complex = 1;
2155b39c5158Smillert                }
2156b39c5158Smillert            }
21579f11ffb7Safresh1            else {
21589f11ffb7Safresh1                $macro = $self->{$macro};
21599f11ffb7Safresh1                # Don't unixify if there is unescaped whitespace
21609f11ffb7Safresh1                $macro = unixify($macro) unless ($macro =~ /(?<!\^)\s/);
21619f11ffb7Safresh1                $macro =~ s#/\Z(?!\n)##;
21629f11ffb7Safresh1            }
2163b39c5158Smillert            $npath = "$head$macro$tail";
2164b39c5158Smillert        }
2165b39c5158Smillert    }
2166b39c5158Smillert    if ($complex) { $npath =~ s#\cB(.*?)\cB#\${$1}#gs; }
2167b39c5158Smillert    $npath;
2168b39c5158Smillert}
2169b39c5158Smillert
2170b39c5158Smillert=item fixpath
2171b39c5158Smillert
2172b39c5158Smillert   my $path = $mm->fixpath($path);
2173b39c5158Smillert   my $path = $mm->fixpath($path, $is_dir);
2174b39c5158Smillert
2175b39c5158SmillertCatchall routine to clean up problem MM[SK]/Make macros.  Expands macros
2176b39c5158Smillertin any directory specification, in order to avoid juxtaposing two
2177b39c5158SmillertVMS-syntax directories when MM[SK] is run.  Also expands expressions which
2178b39c5158Smillertare all macro, so that we can tell how long the expansion is, and avoid
2179b39c5158Smillertoverrunning DCL's command buffer when MM[KS] is running.
2180b39c5158Smillert
2181b39c5158Smillertfixpath() checks to see whether the result matches the name of a
2182b39c5158Smillertdirectory in the current default directory and returns a directory or
2183b39c5158Smillertfile specification accordingly.  C<$is_dir> can be set to true to
2184b39c5158Smillertforce fixpath() to consider the path to be a directory or false to force
2185b39c5158Smillertit to be a file.
2186b39c5158Smillert
2187b39c5158SmillertNOTE:  This is the canonical version of the method.  The version in
218856d68f1eSafresh1L<File::Spec::VMS> is deprecated.
2189b39c5158Smillert
2190b39c5158Smillert=cut
2191b39c5158Smillert
2192b39c5158Smillertsub fixpath {
2193b39c5158Smillert    my($self,$path,$force_path) = @_;
2194b39c5158Smillert    return '' unless $path;
2195b39c5158Smillert    $self = bless {}, $self unless ref $self;
2196b39c5158Smillert    my($fixedpath,$prefix,$name);
2197b39c5158Smillert
2198b39c5158Smillert    if ($path =~ m#^\$\([^\)]+\)\Z(?!\n)#s || $path =~ m#[/:>\]]#) {
2199b39c5158Smillert        if ($force_path or $path =~ /(?:DIR\)|\])\Z(?!\n)/) {
2200b39c5158Smillert            $fixedpath = vmspath($self->eliminate_macros($path));
2201b39c5158Smillert        }
2202b39c5158Smillert        else {
2203b39c5158Smillert            $fixedpath = vmsify($self->eliminate_macros($path));
2204b39c5158Smillert        }
2205b39c5158Smillert    }
2206b39c5158Smillert    elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#s)) && $self->{$prefix}) {
2207b39c5158Smillert        my($vmspre) = $self->eliminate_macros("\$($prefix)");
2208b39c5158Smillert        # is it a dir or just a name?
2209b39c5158Smillert        $vmspre = ($vmspre =~ m|/| or $prefix =~ /DIR\Z(?!\n)/) ? vmspath($vmspre) : '';
2210b39c5158Smillert        $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name;
2211b39c5158Smillert        $fixedpath = vmspath($fixedpath) if $force_path;
2212b39c5158Smillert    }
2213b39c5158Smillert    else {
2214b39c5158Smillert        $fixedpath = $path;
2215b39c5158Smillert        $fixedpath = vmspath($fixedpath) if $force_path;
2216b39c5158Smillert    }
2217b39c5158Smillert    # No hints, so we try to guess
2218b39c5158Smillert    if (!defined($force_path) and $fixedpath !~ /[:>(.\]]/) {
2219b39c5158Smillert        $fixedpath = vmspath($fixedpath) if -d $fixedpath;
2220b39c5158Smillert    }
2221b39c5158Smillert
2222b39c5158Smillert    # Trim off root dirname if it's had other dirs inserted in front of it.
2223b39c5158Smillert    $fixedpath =~ s/\.000000([\]>])/$1/;
2224b39c5158Smillert    # Special case for VMS absolute directory specs: these will have had device
2225b39c5158Smillert    # prepended during trip through Unix syntax in eliminate_macros(), since
2226b39c5158Smillert    # Unix syntax has no way to express "absolute from the top of this device's
2227b39c5158Smillert    # directory tree".
2228b39c5158Smillert    if ($path =~ /^[\[>][^.\-]/) { $fixedpath =~ s/^[^\[<]+//; }
2229b39c5158Smillert
2230b39c5158Smillert    return $fixedpath;
2231b39c5158Smillert}
2232b39c5158Smillert
2233b39c5158Smillert
2234b39c5158Smillert=item os_flavor
2235b39c5158Smillert
2236b39c5158SmillertVMS is VMS.
2237b39c5158Smillert
2238b39c5158Smillert=cut
2239b39c5158Smillert
2240b39c5158Smillertsub os_flavor {
2241b39c5158Smillert    return('VMS');
2242b39c5158Smillert}
2243b39c5158Smillert
2244b8851fccSafresh1
2245b8851fccSafresh1=item is_make_type (override)
2246b8851fccSafresh1
2247b8851fccSafresh1None of the make types being checked for is viable on VMS,
2248b8851fccSafresh1plus our $self->{MAKE} is an unexpanded (and unexpandable)
2249b8851fccSafresh1macro whose value is known only to the make utility itself.
2250b8851fccSafresh1
2251b8851fccSafresh1=cut
2252b8851fccSafresh1
2253b8851fccSafresh1sub is_make_type {
2254b8851fccSafresh1    my($self, $type) = @_;
2255b8851fccSafresh1    return 0;
2256b8851fccSafresh1}
2257b8851fccSafresh1
2258b8851fccSafresh1
22599f11ffb7Safresh1=item make_type (override)
22609f11ffb7Safresh1
22619f11ffb7Safresh1Returns a suitable string describing the type of makefile being written.
22629f11ffb7Safresh1
22639f11ffb7Safresh1=cut
22649f11ffb7Safresh1
22659f11ffb7Safresh1sub make_type { "$Config{make}-style"; }
22669f11ffb7Safresh1
22679f11ffb7Safresh1
2268b39c5158Smillert=back
2269b39c5158Smillert
2270b39c5158Smillert
2271b39c5158Smillert=head1 AUTHOR
2272b39c5158Smillert
2273b39c5158SmillertOriginal author Charles Bailey F<bailey@newman.upenn.edu>
2274b39c5158Smillert
2275b39c5158SmillertMaintained by Michael G Schwern F<schwern@pobox.com>
2276b39c5158Smillert
2277b39c5158SmillertSee L<ExtUtils::MakeMaker> for patching and contact information.
2278b39c5158Smillert
2279b39c5158Smillert
2280b39c5158Smillert=cut
2281b39c5158Smillert
2282b39c5158Smillert1;
2283b39c5158Smillert
2284