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