1N/A# MM_VMS.pm
1N/A# MakeMaker default methods for VMS
1N/A#
1N/A# Author: Charles Bailey bailey@newman.upenn.edu
1N/A
1N/Apackage ExtUtils::MM_VMS;
1N/A
1N/Ause strict;
1N/A
1N/Ause Config;
1N/Arequire Exporter;
1N/A
1N/ABEGIN {
1N/A # so we can compile the thing on non-VMS platforms.
1N/A if( $^O eq 'VMS' ) {
1N/A require VMS::Filespec;
1N/A VMS::Filespec->import;
1N/A }
1N/A}
1N/A
1N/Ause File::Basename;
1N/Ause vars qw($Revision @ISA $VERSION);
1N/A($VERSION) = '5.70';
1N/A($Revision) = q$Revision: 1.110 $ =~ /Revision:\s+(\S+)/;
1N/A
1N/Arequire ExtUtils::MM_Any;
1N/Arequire ExtUtils::MM_Unix;
1N/A@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
1N/A
1N/Ause ExtUtils::MakeMaker qw($Verbose neatvalue);
1N/A
1N/A
1N/A=head1 NAME
1N/A
1N/AExtUtils::MM_VMS - methods to override UN*X behaviour in ExtUtils::MakeMaker
1N/A
1N/A=head1 SYNOPSIS
1N/A
1N/A Do not use this directly.
1N/A Instead, use ExtUtils::MM and it will figure out which MM_*
1N/A class to use for you.
1N/A
1N/A=head1 DESCRIPTION
1N/A
1N/ASee ExtUtils::MM_Unix for a documentation of the methods provided
1N/Athere. This package overrides the implementation of these methods, not
1N/Athe semantics.
1N/A
1N/A=head2 Methods always loaded
1N/A
1N/A=over 4
1N/A
1N/A=item wraplist
1N/A
1N/AConverts a list into a string wrapped at approximately 80 columns.
1N/A
1N/A=cut
1N/A
1N/Asub wraplist {
1N/A my($self) = shift;
1N/A my($line,$hlen) = ('',0);
1N/A
1N/A foreach my $word (@_) {
1N/A # Perl bug -- seems to occasionally insert extra elements when
1N/A # traversing array (scalar(@array) doesn't show them, but
1N/A # foreach(@array) does) (5.00307)
1N/A next unless $word =~ /\w/;
1N/A $line .= ' ' if length($line);
1N/A if ($hlen > 80) { $line .= "\\\n\t"; $hlen = 0; }
1N/A $line .= $word;
1N/A $hlen += length($word) + 2;
1N/A }
1N/A $line;
1N/A}
1N/A
1N/A
1N/A# This isn't really an override. It's just here because ExtUtils::MM_VMS
1N/A# appears in @MM::ISA before ExtUtils::Liblist::Kid, so if there isn't an ext()
1N/A# in MM_VMS, then AUTOLOAD is called, and bad things happen. So, we just
1N/A# mimic inheritance here and hand off to ExtUtils::Liblist::Kid.
1N/A# XXX This hackery will die soon. --Schwern
1N/Asub ext {
1N/A require ExtUtils::Liblist::Kid;
1N/A goto &ExtUtils::Liblist::Kid::ext;
1N/A}
1N/A
1N/A=back
1N/A
1N/A=head2 Methods
1N/A
1N/AThose methods which override default MM_Unix methods are marked
1N/A"(override)", while methods unique to MM_VMS are marked "(specific)".
1N/AFor overridden methods, documentation is limited to an explanation
1N/Aof why this method overrides the MM_Unix method; see the ExtUtils::MM_Unix
1N/Adocumentation for more details.
1N/A
1N/A=over 4
1N/A
1N/A=item guess_name (override)
1N/A
1N/ATry to determine name of extension being built. We begin with the name
1N/Aof the current directory. Since VMS filenames are case-insensitive,
1N/Ahowever, we look for a F<.pm> file whose name matches that of the current
1N/Adirectory (presumably the 'main' F<.pm> file for this extension), and try
1N/Ato find a C<package> statement from which to obtain the Mixed::Case
1N/Apackage name.
1N/A
1N/A=cut
1N/A
1N/Asub guess_name {
1N/A my($self) = @_;
1N/A my($defname,$defpm,@pm,%xs,$pm);
1N/A local *PM;
1N/A
1N/A $defname = basename(fileify($ENV{'DEFAULT'}));
1N/A $defname =~ s![\d\-_]*\.dir.*$!!; # Clip off .dir;1 suffix, and package version
1N/A $defpm = $defname;
1N/A # Fallback in case for some reason a user has copied the files for an
1N/A # extension into a working directory whose name doesn't reflect the
1N/A # extension's name. We'll use the name of a unique .pm file, or the
1N/A # first .pm file with a matching .xs file.
1N/A if (not -e "${defpm}.pm") {
1N/A @pm = map { s/.pm$//; $_ } glob('*.pm');
1N/A if (@pm == 1) { ($defpm = $pm[0]) =~ s/.pm$//; }
1N/A elsif (@pm) {
1N/A %xs = map { s/.xs$//; ($_,1) } glob('*.xs');
1N/A if (keys %xs) {
1N/A foreach $pm (@pm) {
1N/A $defpm = $pm, last if exists $xs{$pm};
1N/A }
1N/A }
1N/A }
1N/A }
1N/A if (open(PM,"${defpm}.pm")){
1N/A while (<PM>) {
1N/A if (/^\s*package\s+([^;]+)/i) {
1N/A $defname = $1;
1N/A last;
1N/A }
1N/A }
1N/A print STDOUT "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t",
1N/A "defaulting package name to $defname\n"
1N/A if eof(PM);
1N/A close PM;
1N/A }
1N/A else {
1N/A print STDOUT "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t",
1N/A "defaulting package name to $defname\n";
1N/A }
1N/A $defname =~ s#[\d.\-_]+$##;
1N/A $defname;
1N/A}
1N/A
1N/A=item find_perl (override)
1N/A
1N/AUse VMS file specification syntax and CLI commands to find and
1N/Ainvoke Perl images.
1N/A
1N/A=cut
1N/A
1N/Asub find_perl {
1N/A my($self, $ver, $names, $dirs, $trace) = @_;
1N/A my($name,$dir,$vmsfile,@sdirs,@snames,@cand);
1N/A my($rslt);
1N/A my($inabs) = 0;
1N/A local *TCF;
1N/A
1N/A if( $self->{PERL_CORE} ) {
1N/A # Check in relative directories first, so we pick up the current
1N/A # version of Perl if we're running MakeMaker as part of the main build.
1N/A @sdirs = sort { my($absa) = $self->file_name_is_absolute($a);
1N/A my($absb) = $self->file_name_is_absolute($b);
1N/A if ($absa && $absb) { return $a cmp $b }
1N/A else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); }
1N/A } @$dirs;
1N/A # Check miniperl before perl, and check names likely to contain
1N/A # version numbers before "generic" names, so we pick up an
1N/A # executable that's less likely to be from an old installation.
1N/A @snames = sort { my($ba) = $a =~ m!([^:>\]/]+)$!; # basename
1N/A my($bb) = $b =~ m!([^:>\]/]+)$!;
1N/A my($ahasdir) = (length($a) - length($ba) > 0);
1N/A my($bhasdir) = (length($b) - length($bb) > 0);
1N/A if ($ahasdir and not $bhasdir) { return 1; }
1N/A elsif ($bhasdir and not $ahasdir) { return -1; }
1N/A else { $bb =~ /\d/ <=> $ba =~ /\d/
1N/A or substr($ba,0,1) cmp substr($bb,0,1)
1N/A or length($bb) <=> length($ba) } } @$names;
1N/A }
1N/A else {
1N/A @sdirs = @$dirs;
1N/A @snames = @$names;
1N/A }
1N/A
1N/A # Image names containing Perl version use '_' instead of '.' under VMS
1N/A foreach $name (@snames) { $name =~ s/\.(\d+)$/_$1/; }
1N/A if ($trace >= 2){
1N/A print "Looking for perl $ver by these names:\n";
1N/A print "\t@snames,\n";
1N/A print "in these dirs:\n";
1N/A print "\t@sdirs\n";
1N/A }
1N/A foreach $dir (@sdirs){
1N/A next unless defined $dir; # $self->{PERL_SRC} may be undefined
1N/A $inabs++ if $self->file_name_is_absolute($dir);
1N/A if ($inabs == 1) {
1N/A # We've covered relative dirs; everything else is an absolute
1N/A # dir (probably an installed location). First, we'll try potential
1N/A # command names, to see whether we can avoid a long MCR expression.
1N/A foreach $name (@snames) { push(@cand,$name) if $name =~ /^[\w\-\$]+$/; }
1N/A $inabs++; # Should happen above in next $dir, but just in case . . .
1N/A }
1N/A foreach $name (@snames){
1N/A if ($name !~ m![/:>\]]!) { push(@cand,$self->catfile($dir,$name)); }
1N/A else { push(@cand,$self->fixpath($name,0)); }
1N/A }
1N/A }
1N/A foreach $name (@cand) {
1N/A print "Checking $name\n" if ($trace >= 2);
1N/A # If it looks like a potential command, try it without the MCR
1N/A if ($name =~ /^[\w\-\$]+$/) {
1N/A open(TCF,">temp_mmvms.com") || die('unable to open temp file');
1N/A print TCF "\$ set message/nofacil/nosever/noident/notext\n";
1N/A print TCF "\$ $name -e \"require $ver; print \"\"VER_OK\\n\"\"\"\n";
1N/A close TCF;
1N/A $rslt = `\@temp_mmvms.com` ;
1N/A unlink('temp_mmvms.com');
1N/A if ($rslt =~ /VER_OK/) {
1N/A print "Using PERL=$name\n" if $trace;
1N/A return $name;
1N/A }
1N/A }
1N/A next unless $vmsfile = $self->maybe_command($name);
1N/A $vmsfile =~ s/;[\d\-]*$//; # Clip off version number; we can use a newer version as well
1N/A print "Executing $vmsfile\n" if ($trace >= 2);
1N/A open(TCF,">temp_mmvms.com") || die('unable to open temp file');
1N/A print TCF "\$ set message/nofacil/nosever/noident/notext\n";
1N/A print TCF "\$ mcr $vmsfile -e \"require $ver; print \"\"VER_OK\\n\"\"\" \n";
1N/A close TCF;
1N/A $rslt = `\@temp_mmvms.com`;
1N/A unlink('temp_mmvms.com');
1N/A if ($rslt =~ /VER_OK/) {
1N/A print "Using PERL=MCR $vmsfile\n" if $trace;
1N/A return "MCR $vmsfile";
1N/A }
1N/A }
1N/A print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
1N/A 0; # false and not empty
1N/A}
1N/A
1N/A=item maybe_command (override)
1N/A
1N/AFollows VMS naming conventions for executable files.
1N/AIf the name passed in doesn't exactly match an executable file,
1N/Aappends F<.Exe> (or equivalent) to check for executable image, and F<.Com>
1N/Ato check for DCL procedure. If this fails, checks directories in DCL$PATH
1N/Aand finally F<Sys$System:> for an executable file having the name specified,
1N/Awith or without the F<.Exe>-equivalent suffix.
1N/A
1N/A=cut
1N/A
1N/Asub maybe_command {
1N/A my($self,$file) = @_;
1N/A return $file if -x $file && ! -d _;
1N/A my(@dirs) = ('');
1N/A my(@exts) = ('',$Config{'exe_ext'},'.exe','.com');
1N/A my($dir,$ext);
1N/A if ($file !~ m![/:>\]]!) {
1N/A for (my $i = 0; defined $ENV{"DCL\$PATH;$i"}; $i++) {
1N/A $dir = $ENV{"DCL\$PATH;$i"};
1N/A $dir .= ':' unless $dir =~ m%[\]:]$%;
1N/A push(@dirs,$dir);
1N/A }
1N/A push(@dirs,'Sys$System:');
1N/A foreach $dir (@dirs) {
1N/A my $sysfile = "$dir$file";
1N/A foreach $ext (@exts) {
1N/A return $file if -x "$sysfile$ext" && ! -d _;
1N/A }
1N/A }
1N/A }
1N/A return 0;
1N/A}
1N/A
1N/A=item perl_script (override)
1N/A
1N/AIf name passed in doesn't specify a readable file, appends F<.com> or
1N/AF<.pl> and tries again, since it's customary to have file types on all files
1N/Aunder VMS.
1N/A
1N/A=cut
1N/A
1N/Asub perl_script {
1N/A my($self,$file) = @_;
1N/A return $file if -r $file && ! -d _;
1N/A return "$file.com" if -r "$file.com";
1N/A return "$file.pl" if -r "$file.pl";
1N/A return '';
1N/A}
1N/A
1N/A=item replace_manpage_separator
1N/A
1N/AUse as separator a character which is legal in a VMS-syntax file name.
1N/A
1N/A=cut
1N/A
1N/Asub replace_manpage_separator {
1N/A my($self,$man) = @_;
1N/A $man = unixify($man);
1N/A $man =~ s#/+#__#g;
1N/A $man;
1N/A}
1N/A
1N/A=item init_DEST
1N/A
1N/A(override) Because of the difficulty concatenating VMS filepaths we
1N/Amust pre-expand the DEST* variables.
1N/A
1N/A=cut
1N/A
1N/Asub init_DEST {
1N/A my $self = shift;
1N/A
1N/A $self->SUPER::init_DEST;
1N/A
1N/A # Expand DEST variables.
1N/A foreach my $var ($self->installvars) {
1N/A my $destvar = 'DESTINSTALL'.$var;
1N/A $self->{$destvar} = File::Spec->eliminate_macros($self->{$destvar});
1N/A }
1N/A}
1N/A
1N/A
1N/A=item init_DIRFILESEP
1N/A
1N/ANo seperator between a directory path and a filename on VMS.
1N/A
1N/A=cut
1N/A
1N/Asub init_DIRFILESEP {
1N/A my($self) = shift;
1N/A
1N/A $self->{DIRFILESEP} = '';
1N/A return 1;
1N/A}
1N/A
1N/A
1N/A=item init_main (override)
1N/A
1N/A
1N/A=cut
1N/A
1N/Asub init_main {
1N/A my($self) = shift;
1N/A
1N/A $self->SUPER::init_main;
1N/A
1N/A $self->{DEFINE} ||= '';
1N/A if ($self->{DEFINE} ne '') {
1N/A my(@terms) = split(/\s+/,$self->{DEFINE});
1N/A my(@defs,@udefs);
1N/A foreach my $def (@terms) {
1N/A next unless $def;
1N/A my $targ = \@defs;
1N/A if ($def =~ s/^-([DU])//) { # If it was a Unix-style definition
1N/A $targ = \@udefs if $1 eq 'U';
1N/A $def =~ s/='(.*)'$/=$1/; # then remove shell-protection ''
1N/A $def =~ s/^'(.*)'$/$1/; # from entire term or argument
1N/A }
1N/A if ($def =~ /=/) {
1N/A $def =~ s/"/""/g; # Protect existing " from DCL
1N/A $def = qq["$def"]; # and quote to prevent parsing of =
1N/A }
1N/A push @$targ, $def;
1N/A }
1N/A
1N/A $self->{DEFINE} = '';
1N/A if (@defs) {
1N/A $self->{DEFINE} = '/Define=(' . join(',',@defs) . ')';
1N/A }
1N/A if (@udefs) {
1N/A $self->{DEFINE} .= '/Undef=(' . join(',',@udefs) . ')';
1N/A }
1N/A }
1N/A}
1N/A
1N/A=item init_others (override)
1N/A
1N/AProvide VMS-specific forms of various utility commands, then hand
1N/Aoff to the default MM_Unix method.
1N/A
1N/ADEV_NULL should probably be overriden with something.
1N/A
1N/AAlso changes EQUALIZE_TIMESTAMP to set revision date of target file to
1N/Aone second later than source file, since MMK interprets precisely
1N/Aequal revision dates for a source and target file as a sign that the
1N/Atarget needs to be updated.
1N/A
1N/A=cut
1N/A
1N/Asub init_others {
1N/A my($self) = @_;
1N/A
1N/A $self->{NOOP} = 'Continue';
1N/A $self->{NOECHO} ||= '@ ';
1N/A
1N/A $self->{MAKEFILE} ||= 'Descrip.MMS';
1N/A $self->{FIRST_MAKEFILE} ||= $self->{MAKEFILE};
1N/A $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS';
1N/A $self->{MAKEFILE_OLD} ||= '$(FIRST_MAKEFILE)_old';
1N/A
1N/A $self->{ECHO} ||= '$(PERLRUN) -le "print qq{@ARGV}"';
1N/A $self->{ECHO_N} ||= '$(PERLRUN) -e "print qq{@ARGV}"';
1N/A $self->{TOUCH} ||= '$(PERLRUN) "-MExtUtils::Command" -e touch';
1N/A $self->{CHMOD} ||= '$(PERLRUN) "-MExtUtils::Command" -e chmod';
1N/A $self->{RM_F} ||= '$(PERLRUN) "-MExtUtils::Command" -e rm_f';
1N/A $self->{RM_RF} ||= '$(PERLRUN) "-MExtUtils::Command" -e rm_rf';
1N/A $self->{TEST_F} ||= '$(PERLRUN) "-MExtUtils::Command" -e test_f';
1N/A $self->{EQUALIZE_TIMESTAMP} ||= '$(PERLRUN) -we "open F,qq{>>$ARGV[1]};close F;utime(0,(stat($ARGV[0]))[9]+1,$ARGV[1])"';
1N/A
1N/A $self->{MOD_INSTALL} ||=
1N/A $self->oneliner(<<'CODE', ['-MExtUtils::Install']);
1N/Ainstall({split(' ',<STDIN>)}, '$(VERBINST)', 0, '$(UNINST)');
1N/ACODE
1N/A
1N/A $self->{SHELL} ||= 'Posix';
1N/A
1N/A $self->{CP} = 'Copy/NoConfirm';
1N/A $self->{MV} = 'Rename/NoConfirm';
1N/A $self->{UMASK_NULL} = '! ';
1N/A
1N/A $self->SUPER::init_others;
1N/A
1N/A if ($self->{OBJECT} =~ /\s/) {
1N/A $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g;
1N/A $self->{OBJECT} = $self->wraplist(
1N/A map $self->fixpath($_,0), split /,?\s+/, $self->{OBJECT}
1N/A );
1N/A }
1N/A
1N/A $self->{LDFROM} = $self->wraplist(
1N/A map $self->fixpath($_,0), split /,?\s+/, $self->{LDFROM}
1N/A );
1N/A}
1N/A
1N/A
1N/A=item init_platform (override)
1N/A
1N/AAdd PERL_VMS, MM_VMS_REVISION and MM_VMS_VERSION.
1N/A
1N/AMM_VMS_REVISION is for backwards compatibility before MM_VMS had a
1N/A$VERSION.
1N/A
1N/A=cut
1N/A
1N/Asub init_platform {
1N/A my($self) = shift;
1N/A
1N/A $self->{MM_VMS_REVISION} = $Revision;
1N/A $self->{MM_VMS_VERSION} = $VERSION;
1N/A $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC}, 'VMS')
1N/A if $self->{PERL_SRC};
1N/A}
1N/A
1N/A
1N/A=item platform_constants
1N/A
1N/A=cut
1N/A
1N/Asub platform_constants {
1N/A my($self) = shift;
1N/A my $make_frag = '';
1N/A
1N/A foreach my $macro (qw(PERL_VMS MM_VMS_REVISION MM_VMS_VERSION))
1N/A {
1N/A next unless defined $self->{$macro};
1N/A $make_frag .= "$macro = $self->{$macro}\n";
1N/A }
1N/A
1N/A return $make_frag;
1N/A}
1N/A
1N/A
1N/A=item init_VERSION (override)
1N/A
1N/AOverride the *DEFINE_VERSION macros with VMS semantics. Translate the
1N/AMAKEMAKER filepath to VMS style.
1N/A
1N/A=cut
1N/A
1N/Asub init_VERSION {
1N/A my $self = shift;
1N/A
1N/A $self->SUPER::init_VERSION;
1N/A
1N/A $self->{DEFINE_VERSION} = '"$(VERSION_MACRO)=""$(VERSION)"""';
1N/A $self->{XS_DEFINE_VERSION} = '"$(XS_VERSION_MACRO)=""$(XS_VERSION)"""';
1N/A $self->{MAKEMAKER} = vmsify($INC{'ExtUtils/MakeMaker.pm'});
1N/A}
1N/A
1N/A
1N/A=item constants (override)
1N/A
1N/AFixes up numerous file and directory macros to insure VMS syntax
1N/Aregardless of input syntax. Also makes lists of files
1N/Acomma-separated.
1N/A
1N/A=cut
1N/A
1N/Asub constants {
1N/A my($self) = @_;
1N/A
1N/A # Be kind about case for pollution
1N/A for (@ARGV) { $_ = uc($_) if /POLLUTE/i; }
1N/A
1N/A # Cleanup paths for directories in MMS macros.
1N/A foreach my $macro ( qw [
1N/A INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB
1N/A PERL_LIB PERL_ARCHLIB
1N/A PERL_INC PERL_SRC ],
1N/A (map { 'INSTALL'.$_ } $self->installvars)
1N/A )
1N/A {
1N/A next unless defined $self->{$macro};
1N/A next if $macro =~ /MAN/ && $self->{$macro} eq 'none';
1N/A $self->{$macro} = $self->fixpath($self->{$macro},1);
1N/A }
1N/A
1N/A # Cleanup paths for files in MMS macros.
1N/A foreach my $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKEFILE_OLD
1N/A MAKE_APERL_FILE MYEXTLIB] )
1N/A {
1N/A next unless defined $self->{$macro};
1N/A $self->{$macro} = $self->fixpath($self->{$macro},0);
1N/A }
1N/A
1N/A # Fixup files for MMS macros
1N/A # XXX is this list complete?
1N/A for my $macro (qw/
1N/A FULLEXT VERSION_FROM OBJECT LDFROM
1N/A / ) {
1N/A next unless defined $self->{$macro};
1N/A $self->{$macro} = $self->fixpath($self->{$macro},0);
1N/A }
1N/A
1N/A
1N/A for my $macro (qw/ XS MAN1PODS MAN3PODS PM /) {
1N/A # Where is the space coming from? --jhi
1N/A next unless $self ne " " && defined $self->{$macro};
1N/A my %tmp = ();
1N/A for my $key (keys %{$self->{$macro}}) {
1N/A $tmp{$self->fixpath($key,0)} =
1N/A $self->fixpath($self->{$macro}{$key},0);
1N/A }
1N/A $self->{$macro} = \%tmp;
1N/A }
1N/A
1N/A for my $macro (qw/ C O_FILES H /) {
1N/A next unless defined $self->{$macro};
1N/A my @tmp = ();
1N/A for my $val (@{$self->{$macro}}) {
1N/A push(@tmp,$self->fixpath($val,0));
1N/A }
1N/A $self->{$macro} = \@tmp;
1N/A }
1N/A
1N/A return $self->SUPER::constants;
1N/A}
1N/A
1N/A
1N/A=item special_targets
1N/A
1N/AClear the default .SUFFIXES and put in our own list.
1N/A
1N/A=cut
1N/A
1N/Asub special_targets {
1N/A my $self = shift;
1N/A
1N/A my $make_frag .= <<'MAKE_FRAG';
1N/A.SUFFIXES :
1N/A.SUFFIXES : $(OBJ_EXT) .c .cpp .cxx .xs
1N/A
1N/AMAKE_FRAG
1N/A
1N/A return $make_frag;
1N/A}
1N/A
1N/A=item cflags (override)
1N/A
1N/ABypass shell script and produce qualifiers for CC directly (but warn
1N/Auser if a shell script for this extension exists). Fold multiple
1N/A/Defines into one, since some C compilers pay attention to only one
1N/Ainstance of this qualifier on the command line.
1N/A
1N/A=cut
1N/A
1N/Asub cflags {
1N/A my($self,$libperl) = @_;
1N/A my($quals) = $self->{CCFLAGS} || $Config{'ccflags'};
1N/A my($definestr,$undefstr,$flagoptstr) = ('','','');
1N/A my($incstr) = '/Include=($(PERL_INC)';
1N/A my($name,$sys,@m);
1N/A
1N/A ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
1N/A print STDOUT "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
1N/A " required to modify CC command for $self->{'BASEEXT'}\n"
1N/A if ($Config{$name});
1N/A
1N/A if ($quals =~ / -[DIUOg]/) {
1N/A while ($quals =~ / -([Og])(\d*)\b/) {
1N/A my($type,$lvl) = ($1,$2);
1N/A $quals =~ s/ -$type$lvl\b\s*//;
1N/A if ($type eq 'g') { $flagoptstr = '/NoOptimize'; }
1N/A else { $flagoptstr = '/Optimize' . (defined($lvl) ? "=$lvl" : ''); }
1N/A }
1N/A while ($quals =~ / -([DIU])(\S+)/) {
1N/A my($type,$def) = ($1,$2);
1N/A $quals =~ s/ -$type$def\s*//;
1N/A $def =~ s/"/""/g;
1N/A if ($type eq 'D') { $definestr .= qq["$def",]; }
1N/A elsif ($type eq 'I') { $incstr .= ',' . $self->fixpath($def,1); }
1N/A else { $undefstr .= qq["$def",]; }
1N/A }
1N/A }
1N/A if (length $quals and $quals !~ m!/!) {
1N/A warn "MM_VMS: Ignoring unrecognized CCFLAGS elements \"$quals\"\n";
1N/A $quals = '';
1N/A }
1N/A $definestr .= q["PERL_POLLUTE",] if $self->{POLLUTE};
1N/A if (length $definestr) { chop($definestr); $quals .= "/Define=($definestr)"; }
1N/A if (length $undefstr) { chop($undefstr); $quals .= "/Undef=($undefstr)"; }
1N/A # Deal with $self->{DEFINE} here since some C compilers pay attention
1N/A # to only one /Define clause on command line, so we have to
1N/A # conflate the ones from $Config{'ccflags'} and $self->{DEFINE}
1N/A # ($self->{DEFINE} has already been VMSified in constants() above)
1N/A if ($self->{DEFINE}) { $quals .= $self->{DEFINE}; }
1N/A for my $type (qw(Def Undef)) {
1N/A my(@terms);
1N/A while ($quals =~ m:/${type}i?n?e?=([^/]+):ig) {
1N/A my $term = $1;
1N/A $term =~ s:^\((.+)\)$:$1:;
1N/A push @terms, $term;
1N/A }
1N/A if ($type eq 'Def') {
1N/A push @terms, qw[ $(DEFINE_VERSION) $(XS_DEFINE_VERSION) ];
1N/A }
1N/A if (@terms) {
1N/A $quals =~ s:/${type}i?n?e?=[^/]+::ig;
1N/A $quals .= "/${type}ine=(" . join(',',@terms) . ')';
1N/A }
1N/A }
1N/A
1N/A $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
1N/A
1N/A # Likewise with $self->{INC} and /Include
1N/A if ($self->{'INC'}) {
1N/A my(@includes) = split(/\s+/,$self->{INC});
1N/A foreach (@includes) {
1N/A s/^-I//;
1N/A $incstr .= ','.$self->fixpath($_,1);
1N/A }
1N/A }
1N/A $quals .= "$incstr)";
1N/A# $quals =~ s/,,/,/g; $quals =~ s/\(,/(/g;
1N/A $self->{CCFLAGS} = $quals;
1N/A
1N/A $self->{PERLTYPE} ||= '';
1N/A
1N/A $self->{OPTIMIZE} ||= $flagoptstr || $Config{'optimize'};
1N/A if ($self->{OPTIMIZE} !~ m!/!) {
1N/A if ($self->{OPTIMIZE} =~ m!-g!) { $self->{OPTIMIZE} = '/Debug/NoOptimize' }
1N/A elsif ($self->{OPTIMIZE} =~ /-O(\d*)/) {
1N/A $self->{OPTIMIZE} = '/Optimize' . (defined($1) ? "=$1" : '');
1N/A }
1N/A else {
1N/A warn "MM_VMS: Can't parse OPTIMIZE \"$self->{OPTIMIZE}\"; using default\n" if length $self->{OPTIMIZE};
1N/A $self->{OPTIMIZE} = '/Optimize';
1N/A }
1N/A }
1N/A
1N/A return $self->{CFLAGS} = qq{
1N/ACCFLAGS = $self->{CCFLAGS}
1N/AOPTIMIZE = $self->{OPTIMIZE}
1N/APERLTYPE = $self->{PERLTYPE}
1N/A};
1N/A}
1N/A
1N/A=item const_cccmd (override)
1N/A
1N/AAdds directives to point C preprocessor to the right place when
1N/Ahandling #include E<lt>sys/foo.hE<gt> directives. Also constructs CC
1N/Acommand line a bit differently than MM_Unix method.
1N/A
1N/A=cut
1N/A
1N/Asub const_cccmd {
1N/A my($self,$libperl) = @_;
1N/A my(@m);
1N/A
1N/A return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
1N/A return '' unless $self->needs_linking();
1N/A if ($Config{'vms_cc_type'} eq 'gcc') {
1N/A push @m,'
1N/A.FIRST
1N/A ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
1N/A }
1N/A elsif ($Config{'vms_cc_type'} eq 'vaxc') {
1N/A push @m,'
1N/A.FIRST
1N/A ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
1N/A ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
1N/A }
1N/A else {
1N/A push @m,'
1N/A.FIRST
1N/A ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
1N/A ($Config{'archname'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
1N/A ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
1N/A }
1N/A
1N/A push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
1N/A
1N/A $self->{CONST_CCCMD} = join('',@m);
1N/A}
1N/A
1N/A
1N/A=item tool_sxubpp (override)
1N/A
1N/AUse VMS-style quoting on xsubpp command line.
1N/A
1N/A=cut
1N/A
1N/Asub tool_xsubpp {
1N/A my($self) = @_;
1N/A return '' unless $self->needs_linking;
1N/A
1N/A my $xsdir;
1N/A foreach my $dir (@INC) {
1N/A $xsdir = $self->catdir($dir, 'ExtUtils');
1N/A if( -r $self->catfile($xsdir, "xsubpp") ) {
1N/A last;
1N/A }
1N/A }
1N/A
1N/A my $tmdir = File::Spec->catdir($self->{PERL_LIB},"ExtUtils");
1N/A my(@tmdeps) = $self->catfile($tmdir,'typemap');
1N/A if( $self->{TYPEMAPS} ){
1N/A my $typemap;
1N/A foreach $typemap (@{$self->{TYPEMAPS}}){
1N/A if( ! -f $typemap ){
1N/A warn "Typemap $typemap not found.\n";
1N/A }
1N/A else{
1N/A push(@tmdeps, $self->fixpath($typemap,0));
1N/A }
1N/A }
1N/A }
1N/A push(@tmdeps, "typemap") if -f "typemap";
1N/A my(@tmargs) = map("-typemap $_", @tmdeps);
1N/A if( exists $self->{XSOPT} ){
1N/A unshift( @tmargs, $self->{XSOPT} );
1N/A }
1N/A
1N/A if ($Config{'ldflags'} &&
1N/A $Config{'ldflags'} =~ m!/Debug!i &&
1N/A (!exists($self->{XSOPT}) || $self->{XSOPT} !~ /linenumbers/)) {
1N/A unshift(@tmargs,'-nolinenumbers');
1N/A }
1N/A
1N/A
1N/A $self->{XSPROTOARG} = '' unless defined $self->{XSPROTOARG};
1N/A
1N/A return "
1N/AXSUBPPDIR = $xsdir
1N/AXSUBPP = \$(PERLRUN) \$(XSUBPPDIR)xsubpp
1N/AXSPROTOARG = $self->{XSPROTOARG}
1N/AXSUBPPDEPS = @tmdeps
1N/AXSUBPPARGS = @tmargs
1N/A";
1N/A}
1N/A
1N/A
1N/A=item tools_other (override)
1N/A
1N/AThrow in some dubious extra macros for Makefile args.
1N/A
1N/AAlso keep around the old $(SAY) macro in case somebody's using it.
1N/A
1N/A=cut
1N/A
1N/Asub tools_other {
1N/A my($self) = @_;
1N/A
1N/A # XXX Are these necessary? Does anyone override them? They're longer
1N/A # than just typing the literal string.
1N/A my $extra_tools = <<'EXTRA_TOOLS';
1N/A
1N/A# Assumes $(MMS) invokes MMS or MMK
1N/A# (It is assumed in some cases later that the default makefile name
1N/A# (Descrip.MMS for MM[SK]) is used.)
1N/AUSEMAKEFILE = /Descrip=
1N/AUSEMACROS = /Macro=(
1N/AMACROEND = )
1N/A
1N/A# Just in case anyone is using the old macro.
1N/ASAY = $(ECHO)
1N/A
1N/AEXTRA_TOOLS
1N/A
1N/A return $self->SUPER::tools_other . $extra_tools;
1N/A}
1N/A
1N/A=item init_dist (override)
1N/A
1N/AVMSish defaults for some values.
1N/A
1N/A macro description default
1N/A
1N/A ZIPFLAGS flags to pass to ZIP -Vu
1N/A
1N/A COMPRESS compression command to gzip
1N/A use for tarfiles
1N/A SUFFIX suffix to put on -gz
1N/A compressed files
1N/A
1N/A SHAR shar command to use vms_share
1N/A
1N/A DIST_DEFAULT default target to use to tardist
1N/A create a distribution
1N/A
1N/A DISTVNAME Use VERSION_SYM instead of $(DISTNAME)-$(VERSION_SYM)
1N/A VERSION for the name
1N/A
1N/A=cut
1N/A
1N/Asub init_dist {
1N/A my($self) = @_;
1N/A $self->{ZIPFLAGS} ||= '-Vu';
1N/A $self->{COMPRESS} ||= 'gzip';
1N/A $self->{SUFFIX} ||= '-gz';
1N/A $self->{SHAR} ||= 'vms_share';
1N/A $self->{DIST_DEFAULT} ||= 'zipdist';
1N/A
1N/A $self->SUPER::init_dist;
1N/A
1N/A $self->{DISTVNAME} = "$self->{DISTNAME}-$self->{VERSION_SYM}";
1N/A}
1N/A
1N/A=item c_o (override)
1N/A
1N/AUse VMS syntax on command line. In particular, $(DEFINE) and
1N/A$(PERL_INC) have been pulled into $(CCCMD). Also use MM[SK] macros.
1N/A
1N/A=cut
1N/A
1N/Asub c_o {
1N/A my($self) = @_;
1N/A return '' unless $self->needs_linking();
1N/A '
1N/A.c$(OBJ_EXT) :
1N/A $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1N/A
1N/A.cpp$(OBJ_EXT) :
1N/A $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp
1N/A
1N/A.cxx$(OBJ_EXT) :
1N/A $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx
1N/A
1N/A';
1N/A}
1N/A
1N/A=item xs_c (override)
1N/A
1N/AUse MM[SK] macros.
1N/A
1N/A=cut
1N/A
1N/Asub xs_c {
1N/A my($self) = @_;
1N/A return '' unless $self->needs_linking();
1N/A '
1N/A.xs.c :
1N/A $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
1N/A';
1N/A}
1N/A
1N/A=item xs_o (override)
1N/A
1N/AUse MM[SK] macros, and VMS command line for C compiler.
1N/A
1N/A=cut
1N/A
1N/Asub xs_o { # many makes are too dumb to use xs_c then c_o
1N/A my($self) = @_;
1N/A return '' unless $self->needs_linking();
1N/A '
1N/A.xs$(OBJ_EXT) :
1N/A $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
1N/A $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1N/A';
1N/A}
1N/A
1N/A
1N/A=item dlsyms (override)
1N/A
1N/ACreate VMS linker options files specifying universal symbols for this
1N/Aextension's shareable image, and listing other shareable images or
1N/Alibraries to which it should be linked.
1N/A
1N/A=cut
1N/A
1N/Asub dlsyms {
1N/A my($self,%attribs) = @_;
1N/A
1N/A return '' unless $self->needs_linking();
1N/A
1N/A my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
1N/A my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || [];
1N/A my($funclist) = $attribs{FUNCLIST} || $self->{FUNCLIST} || [];
1N/A my(@m);
1N/A
1N/A unless ($self->{SKIPHASH}{'dynamic'}) {
1N/A push(@m,'
1N/Adynamic :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1N/A $(NOECHO) $(NOOP)
1N/A');
1N/A }
1N/A
1N/A push(@m,'
1N/Astatic :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1N/A $(NOECHO) $(NOOP)
1N/A') unless $self->{SKIPHASH}{'static'};
1N/A
1N/A push @m,'
1N/A$(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt
1N/A $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1N/A
1N/A$(BASEEXT).opt : Makefile.PL
1N/A $(PERLRUN) -e "use ExtUtils::Mksymlists;" -
1N/A ',qq[-e "Mksymlists('NAME' => '$self->{NAME}', 'DL_FUNCS' => ],
1N/A neatvalue($funcs),q[, 'DL_VARS' => ],neatvalue($vars),
1N/A q[, 'FUNCLIST' => ],neatvalue($funclist),qq[)"\n];
1N/A
1N/A push @m, ' $(PERL) -e "print ""$(INST_STATIC)/Include=';
1N/A if ($self->{OBJECT} =~ /\bBASEEXT\b/ or
1N/A $self->{OBJECT} =~ /\b$self->{BASEEXT}\b/i) {
1N/A push @m, ($Config{d_vms_case_sensitive_symbols}
1N/A ? uc($self->{BASEEXT}) :'$(BASEEXT)');
1N/A }
1N/A else { # We don't have a "main" object file, so pull 'em all in
1N/A # Upcase module names if linker is being case-sensitive
1N/A my($upcase) = $Config{d_vms_case_sensitive_symbols};
1N/A my(@omods) = map { s/\.[^.]*$//; # Trim off file type
1N/A s[\$\(\w+_EXT\)][]; # even as a macro
1N/A s/.*[:>\/\]]//; # Trim off dir spec
1N/A $upcase ? uc($_) : $_;
1N/A } split ' ', $self->eliminate_macros($self->{OBJECT});
1N/A my($tmp,@lines,$elt) = '';
1N/A $tmp = shift @omods;
1N/A foreach $elt (@omods) {
1N/A $tmp .= ",$elt";
1N/A if (length($tmp) > 80) { push @lines, $tmp; $tmp = ''; }
1N/A }
1N/A push @lines, $tmp;
1N/A push @m, '(', join( qq[, -\\n\\t"";" >>\$(MMS\$TARGET)\n\t\$(PERL) -e "print ""], @lines),')';
1N/A }
1N/A push @m, '\n$(INST_STATIC)/Library\n"";" >>$(MMS$TARGET)',"\n";
1N/A
1N/A if (length $self->{LDLOADLIBS}) {
1N/A my($lib); my($line) = '';
1N/A foreach $lib (split ' ', $self->{LDLOADLIBS}) {
1N/A $lib =~ s%\$%\\\$%g; # Escape '$' in VMS filespecs
1N/A if (length($line) + length($lib) > 160) {
1N/A push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n";
1N/A $line = $lib . '\n';
1N/A }
1N/A else { $line .= $lib . '\n'; }
1N/A }
1N/A push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n" if $line;
1N/A }
1N/A
1N/A join('',@m);
1N/A
1N/A}
1N/A
1N/A=item dynamic_lib (override)
1N/A
1N/AUse VMS Link command.
1N/A
1N/A=cut
1N/A
1N/Asub dynamic_lib {
1N/A my($self, %attribs) = @_;
1N/A return '' unless $self->needs_linking(); #might be because of a subdir
1N/A
1N/A return '' unless $self->has_link_code();
1N/A
1N/A my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
1N/A my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
1N/A my $shr = $Config{'dbgprefix'} . 'PerlShr';
1N/A my(@m);
1N/A push @m,"
1N/A
1N/AOTHERLDFLAGS = $otherldflags
1N/AINST_DYNAMIC_DEP = $inst_dynamic_dep
1N/A
1N/A";
1N/A push @m, '
1N/A$(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1N/A $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
1N/A If F$TrnLNm("',$shr,'").eqs."" Then Define/NoLog/User ',"$shr Sys\$Share:$shr.$Config{'dlext'}",'
1N/A Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,$(PERL_INC)perlshr_attr.opt/Option
1N/A';
1N/A
1N/A push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1N/A join('',@m);
1N/A}
1N/A
1N/A=item dynamic_bs (override)
1N/A
1N/AUse VMS-style quoting on Mkbootstrap command line.
1N/A
1N/A=cut
1N/A
1N/Asub dynamic_bs {
1N/A my($self, %attribs) = @_;
1N/A return '
1N/ABOOTSTRAP =
1N/A' unless $self->has_link_code();
1N/A '
1N/ABOOTSTRAP = '."$self->{BASEEXT}.bs".'
1N/A
1N/A# As MakeMaker mkbootstrap might not write a file (if none is required)
1N/A# we use touch to prevent make continually trying to remake it.
1N/A# The DynaLoader only reads a non-empty file.
1N/A$(BOOTSTRAP) : $(FIRST_MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
1N/A $(NOECHO) $(ECHO) "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
1N/A $(NOECHO) $(PERLRUN) -
1N/A -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
1N/A $(NOECHO) $(TOUCH) $(MMS$TARGET)
1N/A
1N/A$(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
1N/A $(NOECHO) $(RM_RF) $(INST_BOOT)
1N/A - $(CP) $(BOOTSTRAP) $(INST_BOOT)
1N/A';
1N/A}
1N/A
1N/A=item static_lib (override)
1N/A
1N/AUse VMS commands to manipulate object library.
1N/A
1N/A=cut
1N/A
1N/Asub static_lib {
1N/A my($self) = @_;
1N/A return '' unless $self->needs_linking();
1N/A
1N/A return '
1N/A$(INST_STATIC) :
1N/A $(NOECHO) $(NOOP)
1N/A' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB});
1N/A
1N/A my(@m,$lib);
1N/A push @m,'
1N/A# Rely on suffix rule for update action
1N/A$(OBJECT) : $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
1N/A
1N/A$(INST_STATIC) : $(OBJECT) $(MYEXTLIB)
1N/A';
1N/A # If this extension has its own library (eg SDBM_File)
1N/A # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1N/A push(@m, "\t",'$(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1N/A
1N/A push(@m,"\t",'If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)',"\n");
1N/A
1N/A # if there was a library to copy, then we can't use MMS$SOURCE_LIST,
1N/A # 'cause it's a library and you can't stick them in other libraries.
1N/A # In that case, we use $OBJECT instead and hope for the best
1N/A if ($self->{MYEXTLIB}) {
1N/A push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) $(OBJECT)',"\n");
1N/A } else {
1N/A push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)',"\n");
1N/A }
1N/A
1N/A push @m, "\t\$(NOECHO) \$(PERL) -e 1 >\$(INST_ARCHAUTODIR)extralibs.ld\n";
1N/A foreach $lib (split ' ', $self->{EXTRALIBS}) {
1N/A push(@m,"\t",'$(NOECHO) $(PERL) -e "print qq{',$lib,'\n}" >>$(INST_ARCHAUTODIR)extralibs.ld',"\n");
1N/A }
1N/A push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1N/A join('',@m);
1N/A}
1N/A
1N/A
1N/A=item processPL (override)
1N/A
1N/AUse VMS-style quoting on command line.
1N/A
1N/A=cut
1N/A
1N/Asub processPL {
1N/A my($self) = @_;
1N/A return "" unless $self->{PL_FILES};
1N/A my(@m, $plfile);
1N/A foreach $plfile (sort keys %{$self->{PL_FILES}}) {
1N/A my $list = ref($self->{PL_FILES}->{$plfile})
1N/A ? $self->{PL_FILES}->{$plfile}
1N/A : [$self->{PL_FILES}->{$plfile}];
1N/A foreach my $target (@$list) {
1N/A my $vmsplfile = vmsify($plfile);
1N/A my $vmsfile = vmsify($target);
1N/A push @m, "
1N/Aall :: $vmsfile
1N/A \$(NOECHO) \$(NOOP)
1N/A
1N/A$vmsfile :: $vmsplfile
1N/A",' $(PERLRUNINST) '," $vmsplfile $vmsfile
1N/A";
1N/A }
1N/A }
1N/A join "", @m;
1N/A}
1N/A
1N/A=item installbin (override)
1N/A
1N/AStay under DCL's 255 character command line limit once again by
1N/Asplitting potentially long list of files across multiple lines
1N/Ain C<realclean> target.
1N/A
1N/A=cut
1N/A
1N/Asub installbin {
1N/A my($self) = @_;
1N/A return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
1N/A return '' unless @{$self->{EXE_FILES}};
1N/A my(@m, $from, $to, %fromto, @to);
1N/A my(@exefiles) = map { vmsify($_) } @{$self->{EXE_FILES}};
1N/A for $from (@exefiles) {
1N/A my($path) = '$(INST_SCRIPT)' . basename($from);
1N/A local($_) = $path; # backward compatibility
1N/A $to = $self->libscan($path);
1N/A print "libscan($from) => '$to'\n" if ($Verbose >=2);
1N/A $fromto{$from} = vmsify($to);
1N/A }
1N/A @to = values %fromto;
1N/A push @m, "
1N/AEXE_FILES = @exefiles
1N/A
1N/Apure_all :: @to
1N/A \$(NOECHO) \$(NOOP)
1N/A
1N/Arealclean ::
1N/A";
1N/A
1N/A my $line = '';
1N/A foreach $to (@to) {
1N/A if (length($line) + length($to) > 80) {
1N/A push @m, "\t\$(RM_F) $line\n";
1N/A $line = $to;
1N/A }
1N/A else { $line .= " $to"; }
1N/A }
1N/A push @m, "\t\$(RM_F) $line\n\n" if $line;
1N/A
1N/A while (($from,$to) = each %fromto) {
1N/A last unless defined $from;
1N/A my $todir;
1N/A if ($to =~ m#[/>:\]]#) {
1N/A $todir = dirname($to);
1N/A }
1N/A else {
1N/A ($todir = $to) =~ s/[^\)]+$//;
1N/A }
1N/A $todir = $self->fixpath($todir,1);
1N/A push @m, "
1N/A$to : $from \$(FIRST_MAKEFILE) ${todir}\$(DIRFILESEP).exists
1N/A \$(CP) $from $to
1N/A
1N/A", $self->dir_target($todir);
1N/A }
1N/A join "", @m;
1N/A}
1N/A
1N/A=item subdir_x (override)
1N/A
1N/AUse VMS commands to change default directory.
1N/A
1N/A=cut
1N/A
1N/Asub subdir_x {
1N/A my($self, $subdir) = @_;
1N/A my(@m,$key);
1N/A $subdir = $self->fixpath($subdir,1);
1N/A push @m, '
1N/A
1N/Asubdirs ::
1N/A olddef = F$Environment("Default")
1N/A Set Default ',$subdir,'
1N/A - $(MMS)$(MMSQUALIFIERS) all $(USEMACROS)$(PASTHRU)$(MACROEND)
1N/A Set Default \'olddef\'
1N/A';
1N/A join('',@m);
1N/A}
1N/A
1N/A=item clean (override)
1N/A
1N/ASplit potentially long list of files across multiple commands (in
1N/Aorder to stay under the magic command line limit). Also use MM[SK]
1N/Acommands for handling subdirectories.
1N/A
1N/A=cut
1N/A
1N/Asub clean {
1N/A my($self, %attribs) = @_;
1N/A my(@m,$dir);
1N/A push @m, '
1N/A# Delete temporary files but do not touch installed files. We don\'t delete
1N/A# the Descrip.MMS here so that a later make realclean still has it to use.
1N/Aclean :: clean_subdirs
1N/A';
1N/A push @m, ' $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp
1N/A';
1N/A
1N/A my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
1N/A # Unlink realclean, $attribs{FILES} is a string here; it may contain
1N/A # a list or a macro that expands to a list.
1N/A if ($attribs{FILES}) {
1N/A my @filelist = ref $attribs{FILES} eq 'ARRAY'
1N/A ? @{$attribs{FILES}}
1N/A : split /\s+/, $attribs{FILES};
1N/A
1N/A foreach my $word (@filelist) {
1N/A if ($word =~ m#^\$\((.*)\)$# and
1N/A ref $self->{$1} eq 'ARRAY')
1N/A {
1N/A push(@otherfiles, @{$self->{$1}});
1N/A }
1N/A else { push(@otherfiles, $word); }
1N/A }
1N/A }
1N/A push(@otherfiles, qw[ blib $(MAKE_APERL_FILE)
1N/A perlmain.c pm_to_blib pm_to_blib.ts ]);
1N/A push(@otherfiles, $self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'));
1N/A push(@otherfiles, $self->catfile('$(INST_ARCHAUTODIR)','extralibs.ld'));
1N/A
1N/A # Occasionally files are repeated several times from different sources
1N/A { my(%of) = map { ($_ => 1) } @otherfiles; @otherfiles = keys %of; }
1N/A
1N/A my $line = '';
1N/A foreach my $file (@otherfiles) {
1N/A $file = $self->fixpath($file);
1N/A if (length($line) + length($file) > 80) {
1N/A push @m, "\t\$(RM_RF) $line\n";
1N/A $line = "$file";
1N/A }
1N/A else { $line .= " $file"; }
1N/A }
1N/A push @m, "\t\$(RM_RF) $line\n" if $line;
1N/A push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP};
1N/A join('', @m);
1N/A}
1N/A
1N/A
1N/A=item clean_subdirs_target
1N/A
1N/A my $make_frag = $MM->clean_subdirs_target;
1N/A
1N/AVMS semantics for changing directories and rerunning make very different.
1N/A
1N/A=cut
1N/A
1N/Asub clean_subdirs_target {
1N/A my($self) = shift;
1N/A
1N/A # No subdirectories, no cleaning.
1N/A return <<'NOOP_FRAG' unless @{$self->{DIR}};
1N/Aclean_subdirs :
1N/A $(NOECHO) $(NOOP)
1N/ANOOP_FRAG
1N/A
1N/A
1N/A my $clean = "clean_subdirs :\n";
1N/A
1N/A foreach my $dir (@{$self->{DIR}}) { # clean subdirectories first
1N/A $dir = $self->fixpath($dir,1);
1N/A
1N/A $clean .= sprintf <<'MAKE_FRAG', $dir, $dir;
1N/A If F$Search("%s$(FIRST_MAKEFILE)").nes."" Then $(PERLRUN) -e "chdir '%s'; print `$(MMS)$(MMSQUALIFIERS) clean`;"
1N/AMAKE_FRAG
1N/A }
1N/A
1N/A return $clean;
1N/A}
1N/A
1N/A
1N/A=item realclean (override)
1N/A
1N/AGuess what we're working around? Also, use MM[SK] for subdirectories.
1N/A
1N/A=cut
1N/A
1N/Asub realclean {
1N/A my($self, %attribs) = @_;
1N/A my(@m);
1N/A push(@m,'
1N/A# Delete temporary files (via clean) and also delete installed files
1N/Arealclean :: clean
1N/A');
1N/A foreach(@{$self->{DIR}}){
1N/A my($vmsdir) = $self->fixpath($_,1);
1N/A push(@m, ' If F$Search("'."$vmsdir".'$(FIRST_MAKEFILE)").nes."" Then \\',"\n\t",
1N/A '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS)$(MMSQUALIFIERS) realclean`;"',"\n");
1N/A }
1N/A push @m, " \$(RM_RF) \$(INST_AUTODIR) \$(INST_ARCHAUTODIR)\n";
1N/A push @m, " \$(RM_RF) \$(DISTVNAME)\n";
1N/A # We can't expand several of the MMS macros here, since they don't have
1N/A # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a
1N/A # combination of macros). In order to stay below DCL's 255 char limit,
1N/A # we put only 2 on a line.
1N/A my($file,$fcnt);
1N/A my(@files) = values %{$self->{PM}};
1N/A push @files, qw{ $(FIRST_MAKEFILE) $(MAKEFILE_OLD) };
1N/A if ($self->has_link_code) {
1N/A push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) });
1N/A }
1N/A
1N/A # Occasionally files are repeated several times from different sources
1N/A { my(%f) = map { ($_,1) } @files; @files = keys %f; }
1N/A
1N/A my $line = '';
1N/A foreach $file (@files) {
1N/A if (length($line) + length($file) > 80 || ++$fcnt >= 2) {
1N/A push @m, "\t\$(RM_F) $line\n";
1N/A $line = "$file";
1N/A $fcnt = 0;
1N/A }
1N/A else { $line .= " $file"; }
1N/A }
1N/A push @m, "\t\$(RM_F) $line\n" if $line;
1N/A if ($attribs{FILES}) {
1N/A my($word,$key,@filist,@allfiles);
1N/A if (ref $attribs{FILES} eq 'ARRAY') { @filist = @{$attribs{FILES}}; }
1N/A else { @filist = split /\s+/, $attribs{FILES}; }
1N/A foreach $word (@filist) {
1N/A if (($key) = $word =~ m#^\$\((.*)\)$# and ref $self->{$key} eq 'ARRAY') {
1N/A push(@allfiles, @{$self->{$key}});
1N/A }
1N/A else { push(@allfiles, $word); }
1N/A }
1N/A $line = '';
1N/A # Occasionally files are repeated several times from different sources
1N/A { my(%af) = map { ($_,1) } @allfiles; @allfiles = keys %af; }
1N/A foreach $file (@allfiles) {
1N/A $file = $self->fixpath($file);
1N/A if (length($line) + length($file) > 80) {
1N/A push @m, "\t\$(RM_RF) $line\n";
1N/A $line = "$file";
1N/A }
1N/A else { $line .= " $file"; }
1N/A }
1N/A push @m, "\t\$(RM_RF) $line\n" if $line;
1N/A }
1N/A push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP};
1N/A join('', @m);
1N/A}
1N/A
1N/A=item zipfile_target (o)
1N/A
1N/A=item tarfile_target (o)
1N/A
1N/A=item shdist_target (o)
1N/A
1N/ASyntax for invoking shar, tar and zip differs from that for Unix.
1N/A
1N/A=cut
1N/A
1N/Asub zipfile_target {
1N/A my($self) = shift;
1N/A
1N/A return <<'MAKE_FRAG';
1N/A$(DISTVNAME).zip : distdir
1N/A $(PREOP)
1N/A $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) [.$(DISTVNAME)...]*.*;
1N/A $(RM_RF) $(DISTVNAME)
1N/A $(POSTOP)
1N/AMAKE_FRAG
1N/A}
1N/A
1N/Asub tarfile_target {
1N/A my($self) = shift;
1N/A
1N/A return <<'MAKE_FRAG';
1N/A$(DISTVNAME).tar$(SUFFIX) : distdir
1N/A $(PREOP)
1N/A $(TO_UNIX)
1N/A $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar [.$(DISTVNAME)...]
1N/A $(RM_RF) $(DISTVNAME)
1N/A $(COMPRESS) $(DISTVNAME).tar
1N/A $(POSTOP)
1N/AMAKE_FRAG
1N/A}
1N/A
1N/Asub shdist_target {
1N/A my($self) = shift;
1N/A
1N/A return <<'MAKE_FRAG';
1N/Ashdist : distdir
1N/A $(PREOP)
1N/A $(SHAR) [.$(DISTVNAME)...]*.*; $(DISTVNAME).share
1N/A $(RM_RF) $(DISTVNAME)
1N/A $(POSTOP)
1N/AMAKE_FRAG
1N/A}
1N/A
1N/A=item dist_test (override)
1N/A
1N/AUse VMS commands to change default directory, and use VMS-style
1N/Aquoting on command line.
1N/A
1N/A=cut
1N/A
1N/Asub dist_test {
1N/A my($self) = @_;
1N/Aq{
1N/Adisttest : distdir
1N/A startdir = F$Environment("Default")
1N/A Set Default [.$(DISTVNAME)]
1N/A $(ABSPERLRUN) Makefile.PL
1N/A $(MMS)$(MMSQUALIFIERS)
1N/A $(MMS)$(MMSQUALIFIERS) test
1N/A Set Default 'startdir'
1N/A};
1N/A}
1N/A
1N/A# --- Test and Installation Sections ---
1N/A
1N/A=item install (override)
1N/A
1N/AWork around DCL's 255 character limit several times,and use
1N/AVMS-style command line quoting in a few cases.
1N/A
1N/A=cut
1N/A
1N/Asub install {
1N/A my($self, %attribs) = @_;
1N/A my(@m,@exe_files);
1N/A
1N/A if ($self->{EXE_FILES}) {
1N/A my($line,$file) = ('','');
1N/A foreach $file (@{$self->{EXE_FILES}}) {
1N/A $line .= "$file ";
1N/A if (length($line) > 128) {
1N/A push(@exe_files,qq[\t\$(NOECHO) \$(ECHO) "$line" >>.MM_tmp\n]);
1N/A $line = '';
1N/A }
1N/A }
1N/A push(@exe_files,qq[\t\$(NOECHO) \$(ECHO) "$line" >>.MM_tmp\n]) if $line;
1N/A }
1N/A
1N/A push @m, q[
1N/Ainstall :: all pure_install doc_install
1N/A $(NOECHO) $(NOOP)
1N/A
1N/Ainstall_perl :: all pure_perl_install doc_perl_install
1N/A $(NOECHO) $(NOOP)
1N/A
1N/Ainstall_site :: all pure_site_install doc_site_install
1N/A $(NOECHO) $(NOOP)
1N/A
1N/Apure_install :: pure_$(INSTALLDIRS)_install
1N/A $(NOECHO) $(NOOP)
1N/A
1N/Adoc_install :: doc_$(INSTALLDIRS)_install
1N/A $(NOECHO) $(NOOP)
1N/A
1N/Apure__install : pure_site_install
1N/A $(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1N/A
1N/Adoc__install : doc_site_install
1N/A $(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1N/A
1N/A# This hack brought to you by DCL's 255-character command line limit
1N/Apure_perl_install ::
1N/A $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read '.File::Spec->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').' '" >.MM_tmp
1N/A $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write '.File::Spec->catfile('$(DESTINSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').' '" >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_LIB) $(DESTINSTALLPRIVLIB) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_ARCHLIB) $(DESTINSTALLARCHLIB) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_BIN) $(DESTINSTALLBIN) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_SCRIPT) $(DESTINSTALLSCRIPT) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_MAN3DIR) $(DESTINSTALLMAN3DIR) " >>.MM_tmp
1N/A $(NOECHO) $(MOD_INSTALL) <.MM_tmp
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[
1N/A
1N/A# Likewise
1N/Apure_site_install ::
1N/A $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read '.File::Spec->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').' '" >.MM_tmp
1N/A $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write '.File::Spec->catfile('$(DESTINSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').' '" >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_LIB) $(DESTINSTALLSITELIB) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_ARCHLIB) $(DESTINSTALLSITEARCH) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_BIN) $(DESTINSTALLSITEBIN) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_SCRIPT) $(DESTINSTALLSCRIPT) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR) " >>.MM_tmp
1N/A $(NOECHO) $(MOD_INSTALL) <.MM_tmp
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[
1N/A
1N/Apure_vendor_install ::
1N/A $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read '.File::Spec->catfile('$(VENDORARCHEXP)','auto','$(FULLEXT)','.packlist').' '" >.MM_tmp
1N/A $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write '.File::Spec->catfile('$(DESTINSTALLVENDORARCH)','auto','$(FULLEXT)','.packlist').' '" >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_LIB) $(DESTINSTALLVENDORLIB) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_BIN) $(DESTINSTALLVENDORBIN) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_SCRIPT) $(DESTINSTALLSCRIPT) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) " >>.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "$(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR) " >>.MM_tmp
1N/A $(NOECHO) $(MOD_INSTALL) <.MM_tmp
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A
1N/A# Ditto
1N/Adoc_perl_install ::
1N/A $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1N/A $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1N/A $(NOECHO) $(ECHO_N) "installed into|$(INSTALLPRIVLIB)|" >.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1N/A],@exe_files,
1N/Aq[ $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A
1N/A# And again
1N/Adoc_site_install ::
1N/A $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1N/A $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1N/A $(NOECHO) $(ECHO_N) "installed into|$(INSTALLSITELIB)|" >.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1N/A],@exe_files,
1N/Aq[ $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A
1N/Adoc_vendor_install ::
1N/A $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1N/A $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1N/A $(NOECHO) $(ECHO_N) "installed into|$(INSTALLVENDORLIB)|" >.MM_tmp
1N/A $(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1N/A],@exe_files,
1N/Aq[ $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A
1N/A];
1N/A
1N/A push @m, q[
1N/Auninstall :: uninstall_from_$(INSTALLDIRS)dirs
1N/A $(NOECHO) $(NOOP)
1N/A
1N/Auninstall_from_perldirs ::
1N/A $(NOECHO) $(UNINSTALL) ].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[
1N/A $(NOECHO) $(ECHO) "Uninstall is now deprecated and makes no actual changes."
1N/A $(NOECHO) $(ECHO) "Please check the list above carefully for errors, and manually remove"
1N/A $(NOECHO) $(ECHO) "the appropriate files. Sorry for the inconvenience."
1N/A
1N/Auninstall_from_sitedirs ::
1N/A $(NOECHO) $(UNINSTALL) ].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[
1N/A $(NOECHO) $(ECHO) "Uninstall is now deprecated and makes no actual changes."
1N/A $(NOECHO) $(ECHO) "Please check the list above carefully for errors, and manually remove"
1N/A $(NOECHO) $(ECHO) "the appropriate files. Sorry for the inconvenience."
1N/A];
1N/A
1N/A join('',@m);
1N/A}
1N/A
1N/A=item perldepend (override)
1N/A
1N/AUse VMS-style syntax for files; it's cheaper to just do it directly here
1N/Athan to have the MM_Unix method call C<catfile> repeatedly. Also, if
1N/Awe have to rebuild Config.pm, use MM[SK] to do it.
1N/A
1N/A=cut
1N/A
1N/Asub perldepend {
1N/A my($self) = @_;
1N/A my(@m);
1N/A
1N/A push @m, '
1N/A$(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h
1N/A$(OBJECT) : $(PERL_INC)av.h, $(PERL_INC)cc_runtime.h, $(PERL_INC)config.h
1N/A$(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h
1N/A$(OBJECT) : $(PERL_INC)embedvar.h, $(PERL_INC)form.h
1N/A$(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h
1N/A$(OBJECT) : $(PERL_INC)intrpvar.h, $(PERL_INC)iperlsys.h, $(PERL_INC)keywords.h
1N/A$(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)nostdio.h, $(PERL_INC)op.h
1N/A$(OBJECT) : $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
1N/A$(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perlio.h
1N/A$(OBJECT) : $(PERL_INC)perlsdio.h, $(PERL_INC)perlvars.h
1N/A$(OBJECT) : $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)pp_proto.h
1N/A$(OBJECT) : $(PERL_INC)proto.h, $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h
1N/A$(OBJECT) : $(PERL_INC)regnodes.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
1N/A$(OBJECT) : $(PERL_INC)thrdvar.h, $(PERL_INC)thread.h
1N/A$(OBJECT) : $(PERL_INC)util.h, $(PERL_INC)vmsish.h
1N/A
1N/A' if $self->{OBJECT};
1N/A
1N/A if ($self->{PERL_SRC}) {
1N/A my(@macros);
1N/A my($mmsquals) = '$(USEMAKEFILE)[.vms]$(FIRST_MAKEFILE)';
1N/A push(@macros,'__AXP__=1') if $Config{'archname'} eq 'VMS_AXP';
1N/A push(@macros,'DECC=1') if $Config{'vms_cc_type'} eq 'decc';
1N/A push(@macros,'GNUC=1') if $Config{'vms_cc_type'} eq 'gcc';
1N/A push(@macros,'SOCKET=1') if $Config{'d_has_sockets'};
1N/A push(@macros,qq["CC=$Config{'cc'}"]) if $Config{'cc'} =~ m!/!;
1N/A $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1N/A push(@m,q[
1N/A# Check for unpropagated config.sh changes. Should never happen.
1N/A# We do NOT just update config.h because that is not sufficient.
1N/A# An out of date config.h is not fatal but complains loudly!
1N/A$(PERL_INC)config.h : $(PERL_SRC)config.sh
1N/A $(NOOP)
1N/A
1N/A$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1N/A $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.h or genconfig.pl"
1N/A olddef = F$Environment("Default")
1N/A Set Default $(PERL_SRC)
1N/A $(MMS)],$mmsquals,);
1N/A if ($self->{PERL_ARCHLIB} =~ m|\[-| && $self->{PERL_SRC} =~ m|(\[-+)|) {
1N/A my($prefix,$target) = ($1,$self->fixpath('$(PERL_ARCHLIB)Config.pm',0));
1N/A $target =~ s/\Q$prefix/[/;
1N/A push(@m," $target");
1N/A }
1N/A else { push(@m,' $(MMS$TARGET)'); }
1N/A push(@m,q[
1N/A Set Default 'olddef'
1N/A]);
1N/A }
1N/A
1N/A push(@m, join(" ", map($self->fixpath($_,0),values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1N/A if %{$self->{XS}};
1N/A
1N/A join('',@m);
1N/A}
1N/A
1N/A=item makefile (override)
1N/A
1N/AUse VMS commands and quoting.
1N/A
1N/A=cut
1N/A
1N/Asub makefile {
1N/A my($self) = @_;
1N/A my(@m,@cmd);
1N/A # We do not know what target was originally specified so we
1N/A # must force a manual rerun to be sure. But as it should only
1N/A # happen very rarely it is not a significant problem.
1N/A push @m, q[
1N/A$(OBJECT) : $(FIRST_MAKEFILE)
1N/A] if $self->{OBJECT};
1N/A
1N/A push @m,q[
1N/A# We take a very conservative approach here, but it's worth it.
1N/A# We move $(FIRST_MAKEFILE) to $(MAKEFILE_OLD) here to avoid gnu make looping.
1N/A$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
1N/A $(NOECHO) $(ECHO) "$(FIRST_MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)"
1N/A $(NOECHO) $(ECHO) "Cleaning current config before rebuilding $(FIRST_MAKEFILE) ..."
1N/A - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
1N/A - $(MMS)$(MMSQUALIFIERS) $(USEMAKEFILE)$(MAKEFILE_OLD) clean
1N/A $(PERLRUN) Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[
1N/A $(NOECHO) $(ECHO) "$(FIRST_MAKEFILE) has been rebuilt."
1N/A $(NOECHO) $(ECHO) "Please run $(MMS) to build the extension."
1N/A];
1N/A
1N/A join('',@m);
1N/A}
1N/A
1N/A=item find_tests (override)
1N/A
1N/A=cut
1N/A
1N/Asub find_tests {
1N/A my $self = shift;
1N/A return -d 't' ? 't/*.t' : '';
1N/A}
1N/A
1N/A=item test (override)
1N/A
1N/AUse VMS commands for handling subdirectories.
1N/A
1N/A=cut
1N/A
1N/Asub test {
1N/A my($self, %attribs) = @_;
1N/A my($tests) = $attribs{TESTS} || $self->find_tests;
1N/A my(@m);
1N/A push @m,"
1N/ATEST_VERBOSE = 0
1N/ATEST_TYPE = test_\$(LINKTYPE)
1N/ATEST_FILE = test.pl
1N/ATESTDB_SW = -d
1N/A
1N/Atest :: \$(TEST_TYPE)
1N/A \$(NOECHO) \$(NOOP)
1N/A
1N/Atestdb :: testdb_\$(LINKTYPE)
1N/A \$(NOECHO) \$(NOOP)
1N/A
1N/A";
1N/A foreach(@{$self->{DIR}}){
1N/A my($vmsdir) = $self->fixpath($_,1);
1N/A push(@m, ' If F$Search("',$vmsdir,'$(FIRST_MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'",
1N/A '; print `$(MMS)$(MMSQUALIFIERS) $(PASTHRU2) test`'."\n");
1N/A }
1N/A push(@m, "\t\$(NOECHO) \$(ECHO) \"No tests defined for \$(NAME) extension.\"\n")
1N/A unless $tests or -f "test.pl" or @{$self->{DIR}};
1N/A push(@m, "\n");
1N/A
1N/A push(@m, "test_dynamic :: pure_all\n");
1N/A push(@m, $self->test_via_harness('$(FULLPERLRUN)', $tests)) if $tests;
1N/A push(@m, $self->test_via_script('$(FULLPERLRUN)', 'test.pl')) if -f "test.pl";
1N/A push(@m, "\t\$(NOECHO) \$(NOOP)\n") if (!$tests && ! -f "test.pl");
1N/A push(@m, "\n");
1N/A
1N/A push(@m, "testdb_dynamic :: pure_all\n");
1N/A push(@m, $self->test_via_script('$(FULLPERLRUN) "$(TESTDB_SW)"', '$(TEST_FILE)'));
1N/A push(@m, "\n");
1N/A
1N/A # Occasionally we may face this degenerate target:
1N/A push @m, "test_ : test_dynamic\n\n";
1N/A
1N/A if ($self->needs_linking()) {
1N/A push(@m, "test_static :: pure_all \$(MAP_TARGET)\n");
1N/A push(@m, $self->test_via_harness('$(MAP_TARGET)', $tests)) if $tests;
1N/A push(@m, $self->test_via_script('$(MAP_TARGET)', 'test.pl')) if -f 'test.pl';
1N/A push(@m, "\n");
1N/A push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n");
1N/A push(@m, $self->test_via_script('$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)'));
1N/A push(@m, "\n");
1N/A }
1N/A else {
1N/A push @m, "test_static :: test_dynamic\n\t\$(NOECHO) \$(NOOP)\n\n";
1N/A push @m, "testdb_static :: testdb_dynamic\n\t\$(NOECHO) \$(NOOP)\n";
1N/A }
1N/A
1N/A join('',@m);
1N/A}
1N/A
1N/A=item makeaperl (override)
1N/A
1N/AUndertake to build a new set of Perl images using VMS commands. Since
1N/AVMS does dynamic loading, it's not necessary to statically link each
1N/Aextension into the Perl image, so this isn't the normal build path.
1N/AConsequently, it hasn't really been tested, and may well be incomplete.
1N/A
1N/A=cut
1N/A
1N/Ause vars qw(%olbs);
1N/A
1N/Asub makeaperl {
1N/A my($self, %attribs) = @_;
1N/A my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmpdir, $libperl) =
1N/A @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
1N/A my(@m);
1N/A push @m, "
1N/A# --- MakeMaker makeaperl section ---
1N/AMAP_TARGET = $target
1N/A";
1N/A return join '', @m if $self->{PARENT};
1N/A
1N/A my($dir) = join ":", @{$self->{DIR}};
1N/A
1N/A unless ($self->{MAKEAPERL}) {
1N/A push @m, q{
1N/A$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
1N/A $(NOECHO) $(ECHO) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
1N/A $(NOECHO) $(PERLRUNINST) \
1N/A Makefile.PL DIR=}, $dir, q{ \
1N/A FIRST_MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
1N/A MAKEAPERL=1 NORECURS=1 };
1N/A
1N/A push @m, map(q[ \\\n\t\t"$_"], @ARGV),q{
1N/A
1N/A$(MAP_TARGET) :: $(MAKE_APERL_FILE)
1N/A $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
1N/A};
1N/A push @m, "\n";
1N/A
1N/A return join '', @m;
1N/A }
1N/A
1N/A
1N/A my($linkcmd,@optlibs,@staticpkgs,$extralist,$targdir,$libperldir,%libseen);
1N/A local($_);
1N/A
1N/A # The front matter of the linkcommand...
1N/A $linkcmd = join ' ', $Config{'ld'},
1N/A grep($_, @Config{qw(large split ldflags ccdlflags)});
1N/A $linkcmd =~ s/\s+/ /g;
1N/A
1N/A # Which *.olb files could we make use of...
1N/A local(%olbs); # XXX can this be lexical?
1N/A $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
1N/A require File::Find;
1N/A File::Find::find(sub {
1N/A return unless m/\Q$self->{LIB_EXT}\E$/;
1N/A return if m/^libperl/;
1N/A
1N/A if( exists $self->{INCLUDE_EXT} ){
1N/A my $found = 0;
1N/A my $incl;
1N/A my $xx;
1N/A
1N/A ($xx = $File::Find::name) =~ s,.*?/auto/,,;
1N/A $xx =~ s,/?$_,,;
1N/A $xx =~ s,/,::,g;
1N/A
1N/A # Throw away anything not explicitly marked for inclusion.
1N/A # DynaLoader is implied.
1N/A foreach $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
1N/A if( $xx eq $incl ){
1N/A $found++;
1N/A last;
1N/A }
1N/A }
1N/A return unless $found;
1N/A }
1N/A elsif( exists $self->{EXCLUDE_EXT} ){
1N/A my $excl;
1N/A my $xx;
1N/A
1N/A ($xx = $File::Find::name) =~ s,.*?/auto/,,;
1N/A $xx =~ s,/?$_,,;
1N/A $xx =~ s,/,::,g;
1N/A
1N/A # Throw away anything explicitly marked for exclusion
1N/A foreach $excl (@{$self->{EXCLUDE_EXT}}){
1N/A return if( $xx eq $excl );
1N/A }
1N/A }
1N/A
1N/A $olbs{$ENV{DEFAULT}} = $_;
1N/A }, grep( -d $_, @{$searchdirs || []}));
1N/A
1N/A # We trust that what has been handed in as argument will be buildable
1N/A $static = [] unless $static;
1N/A @olbs{@{$static}} = (1) x @{$static};
1N/A
1N/A $extra = [] unless $extra && ref $extra eq 'ARRAY';
1N/A # Sort the object libraries in inverse order of
1N/A # filespec length to try to insure that dependent extensions
1N/A # will appear before their parents, so the linker will
1N/A # search the parent library to resolve references.
1N/A # (e.g. Intuit::DWIM will precede Intuit, so unresolved
1N/A # references from [.intuit.dwim]dwim.obj can be found
1N/A # in [.intuit]intuit.olb).
1N/A for (sort { length($a) <=> length($b) } keys %olbs) {
1N/A next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
1N/A my($dir) = $self->fixpath($_,1);
1N/A my($extralibs) = $dir . "extralibs.ld";
1N/A my($extopt) = $dir . $olbs{$_};
1N/A $extopt =~ s/$self->{LIB_EXT}$/.opt/;
1N/A push @optlibs, "$dir$olbs{$_}";
1N/A # Get external libraries this extension will need
1N/A if (-f $extralibs ) {
1N/A my %seenthis;
1N/A open LIST,$extralibs or warn $!,next;
1N/A while (<LIST>) {
1N/A chomp;
1N/A # Include a library in the link only once, unless it's mentioned
1N/A # multiple times within a single extension's options file, in which
1N/A # case we assume the builder needed to search it again later in the
1N/A # link.
1N/A my $skip = exists($libseen{$_}) && !exists($seenthis{$_});
1N/A $libseen{$_}++; $seenthis{$_}++;
1N/A next if $skip;
1N/A push @$extra,$_;
1N/A }
1N/A close LIST;
1N/A }
1N/A # Get full name of extension for ExtUtils::Miniperl
1N/A if (-f $extopt) {
1N/A open OPT,$extopt or die $!;
1N/A while (<OPT>) {
1N/A next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
1N/A my $pkg = $1;
1N/A $pkg =~ s#__*#::#g;
1N/A push @staticpkgs,$pkg;
1N/A }
1N/A }
1N/A }
1N/A # Place all of the external libraries after all of the Perl extension
1N/A # libraries in the final link, in order to maximize the opportunity
1N/A # for XS code from multiple extensions to resolve symbols against the
1N/A # same external library while only including that library once.
1N/A push @optlibs, @$extra;
1N/A
1N/A $target = "Perl$Config{'exe_ext'}" unless $target;
1N/A my $shrtarget;
1N/A ($shrtarget,$targdir) = fileparse($target);
1N/A $shrtarget =~ s/^([^.]*)/$1Shr/;
1N/A $shrtarget = $targdir . $shrtarget;
1N/A $target = "Perlshr.$Config{'dlext'}" unless $target;
1N/A $tmpdir = "[]" unless $tmpdir;
1N/A $tmpdir = $self->fixpath($tmpdir,1);
1N/A if (@optlibs) { $extralist = join(' ',@optlibs); }
1N/A else { $extralist = ''; }
1N/A # Let ExtUtils::Liblist find the necessary libs for us (but skip PerlShr)
1N/A # that's what we're building here).
1N/A push @optlibs, grep { !/PerlShr/i } split ' ', +($self->ext())[2];
1N/A if ($libperl) {
1N/A unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
1N/A print STDOUT "Warning: $libperl not found\n";
1N/A undef $libperl;
1N/A }
1N/A }
1N/A unless ($libperl) {
1N/A if (defined $self->{PERL_SRC}) {
1N/A $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
1N/A } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
1N/A } else {
1N/A print STDOUT "Warning: $libperl not found
1N/A If you're going to build a static perl binary, make sure perl is installed
1N/A otherwise ignore this warning\n";
1N/A }
1N/A }
1N/A $libperldir = $self->fixpath((fileparse($libperl))[1],1);
1N/A
1N/A push @m, '
1N/A# Fill in the target you want to produce if it\'s not perl
1N/AMAP_TARGET = ',$self->fixpath($target,0),'
1N/AMAP_SHRTARGET = ',$self->fixpath($shrtarget,0),"
1N/AMAP_LINKCMD = $linkcmd
1N/AMAP_PERLINC = ", $perlinc ? map('"$_" ',@{$perlinc}) : '',"
1N/AMAP_EXTRA = $extralist
1N/AMAP_LIBPERL = ",$self->fixpath($libperl,0),'
1N/A';
1N/A
1N/A
1N/A push @m,"\n${tmpdir}Makeaperl.Opt : \$(MAP_EXTRA)\n";
1N/A foreach (@optlibs) {
1N/A push @m,' $(NOECHO) $(PERL) -e "print q{',$_,'}" >>$(MMS$TARGET)',"\n";
1N/A }
1N/A push @m,"\n${tmpdir}PerlShr.Opt :\n\t";
1N/A push @m,'$(NOECHO) $(PERL) -e "print q{$(MAP_SHRTARGET)}" >$(MMS$TARGET)',"\n";
1N/A
1N/A push @m,'
1N/A$(MAP_SHRTARGET) : $(MAP_LIBPERL) Makeaperl.Opt ',"${libperldir}Perlshr_Attr.Opt",'
1N/A $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_LIBPERL), Makeaperl.Opt/Option ',"${libperldir}Perlshr_Attr.Opt/Option",'
1N/A$(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}PerlShr.Opt",'
1N/A $(MAP_LINKCMD) ',"${tmpdir}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
1N/A $(NOECHO) $(ECHO) "To install the new ""$(MAP_TARGET)"" binary, say"
1N/A $(NOECHO) $(ECHO) " $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(FIRST_MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
1N/A $(NOECHO) $(ECHO) "To remove the intermediate files, say
1N/A $(NOECHO) $(ECHO) " $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(FIRST_MAKEFILE) map_clean"
1N/A';
1N/A push @m,"\n${tmpdir}perlmain.c : \$(FIRST_MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmpdir}Writemain.tmp\n";
1N/A push @m, "# More from the 255-char line length limit\n";
1N/A foreach (@staticpkgs) {
1N/A push @m,' $(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmpdir}Writemain.tmp\n];
1N/A }
1N/A
1N/A push @m, sprintf <<'MAKE_FRAG', $tmpdir, $tmpdir;
1N/A $(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" %sWritemain.tmp >$(MMS$TARGET)
1N/A $(NOECHO) $(RM_F) %sWritemain.tmp
1N/AMAKE_FRAG
1N/A
1N/A push @m, q[
1N/A# Still more from the 255-char line length limit
1N/Adoc_inst_perl :
1N/A $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1N/A $(NOECHO) $(ECHO) "Perl binary $(MAP_TARGET)|" >.MM_tmp
1N/A $(NOECHO) $(ECHO) "MAP_STATIC|$(MAP_STATIC)|" >>.MM_tmp
1N/A $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
1N/A $(NOECHO) $(ECHO) -e "MAP_LIBPERL|$(MAP_LIBPERL)|" >>.MM_tmp
1N/A $(NOECHO) $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(DESTINSTALLARCHLIB)','perllocal.pod').q[
1N/A $(NOECHO) $(RM_F) .MM_tmp
1N/A];
1N/A
1N/A push @m, "
1N/Ainst_perl : pure_inst_perl doc_inst_perl
1N/A \$(NOECHO) \$(NOOP)
1N/A
1N/Apure_inst_perl : \$(MAP_TARGET)
1N/A $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
1N/A $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
1N/A
1N/Aclean :: map_clean
1N/A \$(NOECHO) \$(NOOP)
1N/A
1N/Amap_clean :
1N/A \$(RM_F) ${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}perlmain.c \$(FIRST_MAKEFILE)
1N/A \$(RM_F) ${tmpdir}Makeaperl.Opt ${tmpdir}PerlShr.Opt \$(MAP_TARGET)
1N/A";
1N/A
1N/A join '', @m;
1N/A}
1N/A
1N/A# --- Output postprocessing section ---
1N/A
1N/A=item nicetext (override)
1N/A
1N/AInsure that colons marking targets are preceded by space, in order
1N/Ato distinguish the target delimiter from a colon appearing as
1N/Apart of a filespec.
1N/A
1N/A=cut
1N/A
1N/Asub nicetext {
1N/A my($self,$text) = @_;
1N/A return $text if $text =~ m/^\w+\s*=/; # leave macro defs alone
1N/A $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
1N/A $text;
1N/A}
1N/A
1N/A=item prefixify (override)
1N/A
1N/Aprefixifying on VMS is simple. Each should simply be:
1N/A
1N/A perl_root:[some.dir]
1N/A
1N/Awhich can just be converted to:
1N/A
1N/A volume:[your.prefix.some.dir]
1N/A
1N/Aotherwise you get the default layout.
1N/A
1N/AIn effect, your search prefix is ignored and $Config{vms_prefix} is
1N/Aused instead.
1N/A
1N/A=cut
1N/A
1N/Asub prefixify {
1N/A my($self, $var, $sprefix, $rprefix, $default) = @_;
1N/A
1N/A # Translate $(PERLPREFIX) to a real path.
1N/A $rprefix = $self->eliminate_macros($rprefix);
1N/A $rprefix = VMS::Filespec::vmspath($rprefix) if $rprefix;
1N/A $sprefix = VMS::Filespec::vmspath($sprefix) if $sprefix;
1N/A
1N/A $default = VMS::Filespec::vmsify($default)
1N/A unless $default =~ /\[.*\]/;
1N/A
1N/A (my $var_no_install = $var) =~ s/^install//;
1N/A my $path = $self->{uc $var} ||
1N/A $ExtUtils::MM_Unix::Config_Override{lc $var} ||
1N/A $Config{lc $var} || $Config{lc $var_no_install};
1N/A
1N/A if( !$path ) {
1N/A print STDERR " no Config found for $var.\n" if $Verbose >= 2;
1N/A $path = $self->_prefixify_default($rprefix, $default);
1N/A }
1N/A elsif( $sprefix eq $rprefix ) {
1N/A print STDERR " no new prefix.\n" if $Verbose >= 2;
1N/A }
1N/A else {
1N/A
1N/A print STDERR " prefixify $var => $path\n" if $Verbose >= 2;
1N/A print STDERR " from $sprefix to $rprefix\n" if $Verbose >= 2;
1N/A
1N/A my($path_vol, $path_dirs) = $self->splitpath( $path );
1N/A if( $path_vol eq $Config{vms_prefix}.':' ) {
1N/A print STDERR " $Config{vms_prefix}: seen\n" if $Verbose >= 2;
1N/A
1N/A $path_dirs =~ s{^\[}{\[.} unless $path_dirs =~ m{^\[\.};
1N/A $path = $self->_catprefix($rprefix, $path_dirs);
1N/A }
1N/A else {
1N/A $path = $self->_prefixify_default($rprefix, $default);
1N/A }
1N/A }
1N/A
1N/A print " now $path\n" if $Verbose >= 2;
1N/A return $self->{uc $var} = $path;
1N/A}
1N/A
1N/A
1N/Asub _prefixify_default {
1N/A my($self, $rprefix, $default) = @_;
1N/A
1N/A print STDERR " cannot prefix, using default.\n" if $Verbose >= 2;
1N/A
1N/A if( !$default ) {
1N/A print STDERR "No default!\n" if $Verbose >= 1;
1N/A return;
1N/A }
1N/A if( !$rprefix ) {
1N/A print STDERR "No replacement prefix!\n" if $Verbose >= 1;
1N/A return '';
1N/A }
1N/A
1N/A return $self->_catprefix($rprefix, $default);
1N/A}
1N/A
1N/Asub _catprefix {
1N/A my($self, $rprefix, $default) = @_;
1N/A
1N/A my($rvol, $rdirs) = $self->splitpath($rprefix);
1N/A if( $rvol ) {
1N/A return $self->catpath($rvol,
1N/A $self->catdir($rdirs, $default),
1N/A ''
1N/A )
1N/A }
1N/A else {
1N/A return $self->catdir($rdirs, $default);
1N/A }
1N/A}
1N/A
1N/A
1N/A=item oneliner (o)
1N/A
1N/A=cut
1N/A
1N/Asub oneliner {
1N/A my($self, $cmd, $switches) = @_;
1N/A $switches = [] unless defined $switches;
1N/A
1N/A # Strip leading and trailing newlines
1N/A $cmd =~ s{^\n+}{};
1N/A $cmd =~ s{\n+$}{};
1N/A
1N/A $cmd = $self->quote_literal($cmd);
1N/A $cmd = $self->escape_newlines($cmd);
1N/A
1N/A # Switches must be quoted else they will be lowercased.
1N/A $switches = join ' ', map { qq{"$_"} } @$switches;
1N/A
1N/A return qq{\$(PERLRUN) $switches -e $cmd};
1N/A}
1N/A
1N/A
1N/A=item B<echo> (o)
1N/A
1N/Aperl trips up on "<foo>" thinking it's an input redirect. So we use the
1N/Anative Write command instead. Besides, its faster.
1N/A
1N/A=cut
1N/A
1N/Asub echo {
1N/A my($self, $text, $file, $appending) = @_;
1N/A $appending ||= 0;
1N/A
1N/A my $opencmd = $appending ? 'Open/Append' : 'Open/Write';
1N/A
1N/A my @cmds = ("\$(NOECHO) $opencmd MMECHOFILE $file ");
1N/A push @cmds, map { '$(NOECHO) Write MMECHOFILE '.$self->quote_literal($_) }
1N/A split /\n/, $text;
1N/A push @cmds, '$(NOECHO) Close MMECHOFILE';
1N/A return @cmds;
1N/A}
1N/A
1N/A
1N/A=item quote_literal
1N/A
1N/A=cut
1N/A
1N/Asub quote_literal {
1N/A my($self, $text) = @_;
1N/A
1N/A # I believe this is all we should need.
1N/A $text =~ s{"}{""}g;
1N/A
1N/A return qq{"$text"};
1N/A}
1N/A
1N/A=item escape_newlines
1N/A
1N/A=cut
1N/A
1N/Asub escape_newlines {
1N/A my($self, $text) = @_;
1N/A
1N/A $text =~ s{\n}{-\n}g;
1N/A
1N/A return $text;
1N/A}
1N/A
1N/A=item max_exec_len
1N/A
1N/A256 characters.
1N/A
1N/A=cut
1N/A
1N/Asub max_exec_len {
1N/A my $self = shift;
1N/A
1N/A return $self->{_MAX_EXEC_LEN} ||= 256;
1N/A}
1N/A
1N/A=item init_linker (o)
1N/A
1N/A=cut
1N/A
1N/Asub init_linker {
1N/A my $self = shift;
1N/A $self->{EXPORT_LIST} ||= '$(BASEEXT).opt';
1N/A
1N/A my $shr = $Config{dbgprefix} . 'PERLSHR';
1N/A if ($self->{PERL_SRC}) {
1N/A $self->{PERL_ARCHIVE} ||=
1N/A $self->catfile($self->{PERL_SRC}, "$shr.$Config{'dlext'}");
1N/A }
1N/A else {
1N/A $self->{PERL_ARCHIVE} ||=
1N/A $ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}";
1N/A }
1N/A
1N/A $self->{PERL_ARCHIVE_AFTER} ||= '';
1N/A}
1N/A
1N/A=item eliminate_macros
1N/A
1N/AExpands MM[KS]/Make macros in a text string, using the contents of
1N/Aidentically named elements of C<%$self>, and returns the result
1N/Aas a file specification in Unix syntax.
1N/A
1N/ANOTE: This is the canonical version of the method. The version in
1N/AFile::Spec::VMS is deprecated.
1N/A
1N/A=cut
1N/A
1N/Asub eliminate_macros {
1N/A my($self,$path) = @_;
1N/A return '' unless $path;
1N/A $self = {} unless ref $self;
1N/A
1N/A if ($path =~ /\s/) {
1N/A return join ' ', map { $self->eliminate_macros($_) } split /\s+/, $path;
1N/A }
1N/A
1N/A my($npath) = unixify($path);
1N/A # sometimes unixify will return a string with an off-by-one trailing null
1N/A $npath =~ s{\0$}{};
1N/A
1N/A my($complex) = 0;
1N/A my($head,$macro,$tail);
1N/A
1N/A # perform m##g in scalar context so it acts as an iterator
1N/A while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#gs) {
1N/A if (defined $self->{$2}) {
1N/A ($head,$macro,$tail) = ($1,$2,$3);
1N/A if (ref $self->{$macro}) {
1N/A if (ref $self->{$macro} eq 'ARRAY') {
1N/A $macro = join ' ', @{$self->{$macro}};
1N/A }
1N/A else {
1N/A print "Note: can't expand macro \$($macro) containing ",ref($self->{$macro}),
1N/A "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n";
1N/A $macro = "\cB$macro\cB";
1N/A $complex = 1;
1N/A }
1N/A }
1N/A else { ($macro = unixify($self->{$macro})) =~ s#/\Z(?!\n)##; }
1N/A $npath = "$head$macro$tail";
1N/A }
1N/A }
1N/A if ($complex) { $npath =~ s#\cB(.*?)\cB#\${$1}#gs; }
1N/A $npath;
1N/A}
1N/A
1N/A=item fixpath
1N/A
1N/ACatchall routine to clean up problem MM[SK]/Make macros. Expands macros
1N/Ain any directory specification, in order to avoid juxtaposing two
1N/AVMS-syntax directories when MM[SK] is run. Also expands expressions which
1N/Aare all macro, so that we can tell how long the expansion is, and avoid
1N/Aoverrunning DCL's command buffer when MM[KS] is running.
1N/A
1N/AIf optional second argument has a TRUE value, then the return string is
1N/Aa VMS-syntax directory specification, if it is FALSE, the return string
1N/Ais a VMS-syntax file specification, and if it is not specified, fixpath()
1N/Achecks to see whether it matches the name of a directory in the current
1N/Adefault directory, and returns a directory or file specification accordingly.
1N/A
1N/ANOTE: This is the canonical version of the method. The version in
1N/AFile::Spec::VMS is deprecated.
1N/A
1N/A=cut
1N/A
1N/Asub fixpath {
1N/A my($self,$path,$force_path) = @_;
1N/A return '' unless $path;
1N/A $self = bless {} unless ref $self;
1N/A my($fixedpath,$prefix,$name);
1N/A
1N/A if ($path =~ /\s/) {
1N/A return join ' ',
1N/A map { $self->fixpath($_,$force_path) }
1N/A split /\s+/, $path;
1N/A }
1N/A
1N/A if ($path =~ m#^\$\([^\)]+\)\Z(?!\n)#s || $path =~ m#[/:>\]]#) {
1N/A if ($force_path or $path =~ /(?:DIR\)|\])\Z(?!\n)/) {
1N/A $fixedpath = vmspath($self->eliminate_macros($path));
1N/A }
1N/A else {
1N/A $fixedpath = vmsify($self->eliminate_macros($path));
1N/A }
1N/A }
1N/A elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#s)) && $self->{$prefix}) {
1N/A my($vmspre) = $self->eliminate_macros("\$($prefix)");
1N/A # is it a dir or just a name?
1N/A $vmspre = ($vmspre =~ m|/| or $prefix =~ /DIR\Z(?!\n)/) ? vmspath($vmspre) : '';
1N/A $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name;
1N/A $fixedpath = vmspath($fixedpath) if $force_path;
1N/A }
1N/A else {
1N/A $fixedpath = $path;
1N/A $fixedpath = vmspath($fixedpath) if $force_path;
1N/A }
1N/A # No hints, so we try to guess
1N/A if (!defined($force_path) and $fixedpath !~ /[:>(.\]]/) {
1N/A $fixedpath = vmspath($fixedpath) if -d $fixedpath;
1N/A }
1N/A
1N/A # Trim off root dirname if it's had other dirs inserted in front of it.
1N/A $fixedpath =~ s/\.000000([\]>])/$1/;
1N/A # Special case for VMS absolute directory specs: these will have had device
1N/A # prepended during trip through Unix syntax in eliminate_macros(), since
1N/A # Unix syntax has no way to express "absolute from the top of this device's
1N/A # directory tree".
1N/A if ($path =~ /^[\[>][^.\-]/) { $fixedpath =~ s/^[^\[<]+//; }
1N/A
1N/A return $fixedpath;
1N/A}
1N/A
1N/A
1N/A=item os_flavor
1N/A
1N/AVMS is VMS.
1N/A
1N/A=cut
1N/A
1N/Asub os_flavor {
1N/A return('VMS');
1N/A}
1N/A
1N/A=back
1N/A
1N/A=cut
1N/A
1N/A1;
1N/A