diff options
Diffstat (limited to 'vms/ext/MM_VMS.pm')
-rw-r--r-- | vms/ext/MM_VMS.pm | 1249 |
1 files changed, 454 insertions, 795 deletions
diff --git a/vms/ext/MM_VMS.pm b/vms/ext/MM_VMS.pm index 801f2f8587..4701245f52 100644 --- a/vms/ext/MM_VMS.pm +++ b/vms/ext/MM_VMS.pm @@ -3,9 +3,9 @@ # This package is inserted into @ISA of MakeMaker's MM before the # built-in MM_Unix methods if MakeMaker.pm is run under VMS. # -# Version: 4.03 +# Version: 4.15 # Author: Charles Bailey bailey@genetics.upenn.edu -# Revised: 30-Jan-1995 +# Revised: 11-Jun-1995 package ExtUtils::MM_VMS; @@ -18,17 +18,95 @@ Exporter::import('ExtUtils::MakeMaker', qw(%att %skip %Recognized_Att_Keys $Verbose &neatvalue)); -sub fixpath { - my($path) = @_; +sub eliminate_macros { + my($path) = unixify(@_); my($head,$macro,$tail); while (($head,$macro,$tail) = ($path =~ m#(.*?)\$\((\S+?)\)/(.*)#)) { ($macro = unixify($att{$macro})) =~ s#/$##; $path = "$head$macro/$tail"; } - vmsify($path); + $path; } +sub fixpath { + my($path) = @_; + return $path if $path =~ /^[^\)\/]+\)?[\w\-\.]*/; + vmsify(eliminate_macros(@_)); +} + +sub catdir { + my($self,$path,$dir) = @_; + vmspath(eliminate_macros($path).'/'.eliminate_macros($dir)); +} + +sub catfile { + my($self,$path,$file) = @_; + if ( $path =~ /^[^\)\]\/:>]+\)$/ ) { "$path$file"; } + else { vmsify(eliminate_macros($path)."/$file"); } +} + + +sub find_perl{ + my($self, $ver, $names, $dirs, $trace) = @_; + my($name, $dir,$vmsfile); + if ($trace){ + print "Looking for perl $ver by these names: "; + print "@$names, "; + print "in these dirs:"; + print "@$dirs"; + } + foreach $dir (@$dirs){ + next unless defined $dir; # $att{PERL_SRC} may be undefined + foreach $name (@$names){ + $name .= ".exe" unless -x "$dir/$name"; + $vmsfile = vmsify("$dir/$name"); + print "Checking $vmsfile" if ($trace >= 2); + next unless -x "$vmsfile"; + print "Executing $vmsfile" if ($trace >= 2); + if (`MCR $vmsfile -e "require $ver; print ""VER_OK\n"""` =~ /VER_OK/) { + print "Using PERL=MCR $vmsfile" if $trace; + return "MCR $vmsfile" + } + } + } + print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n"; + 0; # false and not empty +} + + +# $att{NAME} is taken from the directory name if it's not passed in. +# Since VMS filenames are case-insensitive, we actually look in the +# extension files to find the Mixed-case name +sub init_main { + my($self) = @_; + + if (!$att{NAME}) { + my($defname,$defpm); + local *PM; + $defname = $ENV{'DEFAULT'}; + $defname =~ s:.*?([^.\]]+)\]:$1: unless ($defname =~ s:.*[.\[]ext\.(.*)\]:$1:i); + $defname =~ s#[.\]]#::#g; + ($defpm = $defname) =~ s/.*:://; + if (open(PM,"${defpm}.pm")){ + while (<PM>) { + if (/^\s*package\s+($defname)/oi) { + $att{NAME} = $1; + last; + } + } + close PM; + print STDOUT "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t", + "defaulting package name to $defname\n" unless $att{NAME}; + } + else { + print STDOUT "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t", + "defaulting package name to $defname\n" unless $att{NAME}; + } + $att{NAME} = $defname unless $att{NAME}; + } + MM_Unix::init_main(@_); +} sub init_others { &MM_Unix::init_others; @@ -36,17 +114,20 @@ sub init_others { $att{MAKEFILE} = '$(MAKEFILE)'; $att{RM_F} = '$(PERL) -e "foreach (@ARGV) { -d $_ ? rmdir $_ : unlink $_}"'; $att{RM_RF} = '$(PERL) -e "use File::Path; use VMS::Filespec; @dirs = map(unixify($_),@ARGV); rmtree(\@dirs,0,0)"'; - $att{TOUCH} = '$(PERL) -e "$t=time; utime $t,$t,@ARGV"'; + $att{TOUCH} = '$(PERL) -e "$t=time; foreach (@ARGV) { -e $_ ? utime($t,$t,@ARGV) : (open(F,"">$_""),close F)"'; + $att{CHMOD} = '$(PERL) -e "chmod @ARGV"'; # expect Unix syntax from MakeMaker $att{CP} = 'Copy/NoConfirm'; $att{MV} = 'Rename/NoConfirm'; } sub constants { + my($self) = @_; my(@m,$def); push @m, " NAME = $att{NAME} DISTNAME = $att{DISTNAME} VERSION = $att{VERSION} +VERSION_SYM = $att{VERSION_SYM} # In which library should we install this extension? # This is typically the same as PERL_LIB. @@ -55,25 +136,38 @@ INST_LIB = ",vmspath($att{INST_LIB})," INST_ARCHLIB = ",vmspath($att{INST_ARCHLIB})," INST_EXE = ",vmspath($att{INST_EXE})," +# AFS users will want to set the installation directories for +# the final 'make install' early without setting INST_LIB, +# INST_ARCHLIB, and INST_EXE for the testing phase +INSTALLPRIVLIB = ",vmspath($att{INSTALLPRIVLIB}),' +INSTALLARCHLIB = ',vmspath($att{INSTALLARCHLIB}),' +INSTALLBIN = ',vmspath($att{INSTALLBIN}),' + # Perl library to use when building the extension -PERL_LIB = ",vmspath($att{PERL_LIB})," -PERL_ARCHLIB = ",vmspath($att{PERL_ARCHLIB})," -LIBPERL_A = ",vmsify($att{LIBPERL_A})," +PERL_LIB = ',vmspath($att{PERL_LIB}),' +PERL_ARCHLIB = ',vmspath($att{PERL_ARCHLIB}),' +LIBPERL_A = ',vmsify($att{LIBPERL_A}),' + +MAKEMAKER = ',vmsify(unixpath($att{PERL_LIB}).'ExtUtils/MakeMaker.pm')," +MM_VERSION = $ExtUtils::MakeMaker::Version "; -# Define I_PERL_LIBS to include the required -Ipaths -# To be cute we only include PERL_ARCHLIB if different -# To be portable we add quotes for VMS -my(@i_perl_libs) = qw{-I$(PERL_ARCHLIB) -I$(PERL_LIB)}; -shift(@i_perl_libs) if ($att{PERL_ARCHLIB} eq $att{PERL_LIB}); -push @m, "I_PERL_LIBS = \"".join('" "',@i_perl_libs)."\"\n"; + # Define I_PERL_LIBS to include the required -Ipaths + # To be cute we only include PERL_ARCHLIB if different + # To be portable we add quotes for VMS + #### Deprecated from Version 4.11: We want to avoid different + #### behavior for variables with make(1) and perl(1) + + my(@i_perl_libs) = qw{-I$(PERL_ARCHLIB) -I$(PERL_LIB)}; + shift(@i_perl_libs) if ($att{PERL_ARCHLIB} eq $att{PERL_LIB}); + push @m, "I_PERL_LIBS = \"".join('" "',@i_perl_libs)."\"\n"; -if ($att{PERL_SRC}) { - push @m, " + if ($att{PERL_SRC}) { + push @m, " # Where is the perl source code located? PERL_SRC = ",vmspath($att{PERL_SRC}); -} - push @m," + } + push @m," # Perl header files (will eventually be under PERL_LIB) PERL_INC = ",vmspath($att{PERL_INC})," # Perl binaries @@ -108,16 +202,22 @@ INC = "; $att{DEFINE} = join ',',@defs; } + $att{OBJECT} =~ s#\.o\b#\.obj#; + if ($att{OBJECT} =~ /\s/) { + $att{OBJECT} =~ s/(\\)?\n+\s+/ /g; + $att{OBJECT} = map(vmsify($_),split(/,?\s+/,$att{OBJECT})); + } + $att{LDFROM} = join(' ',map(fixpath($_),split(/,?\s+/,$att{LDFROM}))); push @m," DEFINE = $att{DEFINE} -OBJECT = ",vmsify($att{OBJECT})," -LDFROM = ",vmsify($att{LDFROM})," +OBJECT = $att{OBJECT} +LDFROM = $att{LDFROM}) LINKTYPE = $att{LINKTYPE} # Handy lists of source code files: XS_FILES = ",join(', ', sort keys %{$att{XS}})," C_FILES = ",join(', ', @{$att{C}})," -O_FILES = ",join(', ', @{$att{O_FILES}})," +O_FILES = ",join(', ', map { s#\.o\b#\.obj#; $_ } @{$att{O_FILES}} )," H_FILES = ",join(', ', @{$att{H}})," .SUFFIXES : .xs @@ -135,10 +235,23 @@ INST_ARCHLIBDIR = ",($att{'INST_ARCHLIBDIR'} = vmspath(unixpath($att{INST_ARCHLI INST_AUTODIR = ",($att{'INST_AUTODIR'} = vmspath(unixpath($att{INST_LIB}) . 'auto/' . unixpath($att{FULLEXT}))),' INST_ARCHAUTODIR = ',($att{'INST_ARCHAUTODIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . 'auto/' . unixpath($att{FULLEXT}))),' +'; + if ($self->needs_linking) { + push @m,' INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT).olb INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT) INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs +'; + } else { + push @m,' +INST_STATIC = +INST_DYNAMIC = +INST_BOOT = +'; + } + + push @m,' INST_PM = ',join(', ',map(fixpath($_),sort values %{$att{PM}})),' '; @@ -182,20 +295,36 @@ sub const_loadlibs{ my (@m); push @m, " # $att{NAME} might depend on some other libraries. +# (These comments may need revising:) # -# Dependent libraries are linked in either by the Link command -# at build time or by the DynaLoader at bootstrap time. +# Dependent libraries can be linked in one of three ways: # -# These comments may need revising: +# 1. (For static extensions) by the ld command when the perl binary +# is linked with the extension library. See EXTRALIBS below. # -# EXTRALIBS = Full list of libraries needed for static linking. +# 2. (For dynamic extensions) by the ld command when the shared +# object is built/linked. See LDLOADLIBS below. +# +# 3. (For dynamic extensions) by the DynaLoader when the shared +# object is loaded. See BSLOADLIBS below. +# +# EXTRALIBS = List of libraries that need to be linked with when +# linking a perl binary which includes this extension # Only those libraries that actually exist are included. +# These are written to a file and used when linking perl. # -# BSLOADLIBS = List of those libraries that are needed but can be -# linked in dynamically. +# LDLOADLIBS = List of those libraries which can or must be linked into +# the shared library when created using ld. These may be +# static or dynamic libraries. +# LD_RUN_PATH is a colon separated list of the directories +# in LDLOADLIBS. It is passed as an environment variable to +# the process that links the shared library. # -# LDLOADLIBS = List of those libraries which must be statically -# linked into the shared library. +# BSLOADLIBS = List of those libraries that are needed but can be +# linked in dynamically at run time on this platform. +# SunOS/Solaris does not need this because ld records +# the information (from LDLOADLIBS) into the object file. +# This list is used to create a .bs (bootstrap) file. # EXTRALIBS = ",map(vmsify($_) . ' ',$att{'EXTRALIBS'})," BSLOADLIBS = ",map(vmsify($_) . ' ',$att{'BSLOADLIBS'})," @@ -212,7 +341,7 @@ sub tool_autosplit{ $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN}; q{ # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto -AUTOSPLITFILE = $(PERL) $(I_PERL_LIBS) -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;" +AUTOSPLITFILE = $(PERL) "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;" }; } @@ -234,6 +363,8 @@ XSUBPPARGS = @tmargs sub tools_other { " # Assumes \$(MMS) invokes MMS or MMK +# (It is assumed in some cases later that the default makefile name +# (Descrip.MMS for MM[SK]) is used.) USEMAKEFILE = /Descrip= USEMACROS = /Macro=( MACROEND = ) @@ -298,22 +429,27 @@ sub dlsyms { my(@m); push(@m,' -dynamic :: perlshr.opt $(BASEEXT).opt +dynamic :: $(INST_ARCHAUTODIR)perlshr.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt ',$att{NOOP},' -perlshr.opt : makefile.PL +$(INST_ARCHAUTODIR)perlshr.opt : makefile.PL $(PERL) -e "open O,\'>perlshr.opt\'; print O ""PerlShr/Share\n""; close O" + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" ') unless $skip{'dynamic'}; push(@m,' -static :: $(BASEEXT).opt +static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt ',$att{NOOP},' ') unless $skip{'static'}; push(@m,' +$(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt + $(CP) $(MMS$SOURCE) $(MMS$TARGET) + $(BASEEXT).opt : makefile.PL - $(PERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ',neatvalue($att{DL_FUNCS}),', DL_VARS => ',neatvalue($att{DL_VARS}),',NAME => ',$att{NAME},')" - $(PERL) $(I_PERL_LIBS) -e "open OPT,\'>>$(MMS$TARGET)\'; print OPT ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";close OPT" + $(PERL) "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ',neatvalue($att{DL_FUNCS}),', DL_VARS => ',neatvalue($att{DL_VARS}),',NAME => \'',$att{NAME},'\')" + $(PERL) -e "open OPT,\'>>$(MMS$TARGET)\'; print OPT ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";close OPT" + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" '); join('',@m); @@ -332,9 +468,11 @@ OTHERLDFLAGS = $otherldflags "; push @m, ' -$(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt perlshr.opt $(BASEEXT).opt +$(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt $(INST_ARCHAUTODIR)perlshr.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt @ $(MKPATH) $(INST_ARCHAUTODIR) - Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,perlshr.opt/Option,$(PERL_INC)perlshr_attr.opt/Option + Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(INST_ARCHAUTODIR)$(BASEEXT).opt/Option,perlshr.opt/Option,$(PERL_INC)perlshr_attr.opt/Option + $(CHMOD) 755 $(MMS$TARGET) + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" '; join('',@m); @@ -348,25 +486,34 @@ BOOTSTRAP = '."$att{BASEEXT}.bs".' # As MakeMaker mkbootstrap might not write a file (if none is required) # we use touch to prevent make continually trying to remake it. # The DynaLoader only reads a non-empty file. -$(BOOTSTRAP): '."$att{MAKEFILE} $att{BOOTDEP}".' +$(BOOTSTRAP) : '."$att{MAKEFILE} $att{BOOTDEP}".' @ Write Sys$Output "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))" - @ $(PERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; &mkbootstrap(""$(BSLOADLIBS)"");" "INST_LIB=$(INST_LIB)" "INST_ARCHLIB=$(INST_ARCHLIB)" "PERL_SRC=$(PERL_SRC)" "NAME=$(NAME)" - @ $(TOUCH) $(BOOTSTRAP) + @ $(PERL) "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');" + @ $(TOUCH) $(MMS$TARGET) + $(CHMOD) 644 $(MMS$TARGET) + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" -$(INST_BOOT): $(BOOTSTRAP) +$(INST_BOOT) : $(BOOTSTRAP) @ '.$att{RM_RF}.' $(INST_BOOT) - - '.$att{CP}.' $(BOOTSTRAP) $(INST_BOOT) + - $(CP) $(BOOTSTRAP) $(INST_BOOT) + $(CHMOD) 644 $(MMS$TARGET) + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" '; } # --- Static Loading Sections --- sub static_lib { - ' -$(INST_STATIC) : $(OBJECT), $(MYEXTLIB) - @ $(MKPATH) $(INST_ARCHAUTODIR) + my(@m); + push @m,' +$(INST_STATIC) : $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR).exists If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET) Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST) + $(CHMOD) 755 $(MMS$TARGET) + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F \'$(EXTRALIBS)\';close F;" + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" '; + push @m, MM->dir_target('$(INST_ARCHAUTODIR)'); + join('',@m); } @@ -374,14 +521,15 @@ sub installpm_x { # called by installpm perl file my($self, $dist, $inst, $splitlib) = @_; $inst = fixpath($inst); $dist = vmsify($dist); - my($instdir) = dirname($inst); + my($instdir) = $inst =~ /([^\)]+\))[^\)]*$/ ? $1 : dirname($inst); my(@m); push(@m, " -$inst : $dist $att{MAKEFILE} -",' @ ',$att{RM_F},' $(MMS$TARGET);* - @ $(MKPATH) ',$instdir,' - @ ',$att{CP},' $(MMS$SOURCE) $(MMS$TARGET) +$inst : $dist $att{MAKEFILE} ${instdir}.exists +",' @ $(RM_F) $(MMS$TARGET);* + @ $(CP) $(MMS$SOURCE) $(MMS$TARGET) + $(CHMOD) 644 $(MMS$TARGET) + @ $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR).packlist\';print F \'$(MMS$TARGET)\';close F;" '); if ($splitlib and $inst =~ /\.pm$/) { my($attdir) = $splitlib; @@ -389,46 +537,101 @@ $inst : $dist $att{MAKEFILE} $attdir = $att{$attdir} if $att{$attdir}; push(@m, ' $(AUTOSPLITFILE) $(MMS$TARGET) ', - vmspath(unixpath($attdir) . 'auto')."\n"); - push(@m,"\n"); + vmspath(unixpath($attdir) . 'auto')."\n\n"); } + push(@m,MM->dir_target($instdir)); join('',@m); } +sub processPL { + return "" unless $att{PL_FILES}; + my(@m, $plfile); + foreach $plfile (sort keys %{$att{PL_FILES}}) { + push @m, " +all :: $att{PL_FILES}->{$plfile} + +$att{PL_FILES}->{$plfile} :: $plfile +",' $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $plfile +"; + } + join "", @m; +} -# --- Sub-directory Sections --- -sub exescan { - vmsify($_); +sub installbin { + return "" unless $att{EXE_FILES} && ref $att{EXE_FILES} eq "ARRAY"; + my(@m, $from, $to, %fromto, @to, $line); + for $from (@{$att{EXE_FILES}}) { + local($_)= '$(INST_EXE)' . basename($from); + $to = MY->exescan(); + print "exescan($from) => '$to'" if ($Verbose >=2); + $fromto{$from}=$to; + } + @to = values %fromto; + push @m, " +EXE_FILES = @{$att{EXE_FILES}} + +all :: @to + +realclean :: +"; + $line = ''; #avoid unitialized var warning + foreach $to (@to) { + if (length($line) + length($to) > 150) { + push @m, "\t\$(RM_F) $line\n"; + $line = $to; + } + else { $line .= " $to"; } + } + push @m, "\t\$(RM_F) $line\n\n"; + + while (($from,$to) = each %fromto) { + my $todir; + if ($to =~ m#[/>:\]]#) { $todir = dirname($to); } + else { ($todir = $to) =~ s/[^\)]+$//; } + $todir = fixpath($todir); + push @m, " +$to : $from $att{MAKEFILE} ${todir}.exists + \$(CP) \$(MMS\$SOURCE_LIST) \$(MMS\$TARGET) + +", MY->dir_target($todir); + } + join "", @m; } +# --- Sub-directory Sections --- + sub subdir_x { my($self, $subdir) = @_; my(@m); + $subdir = vmspath($subdir); # The intention is that the calling Makefile.PL should define the # $(SUBDIR_MAKEFILE_PL_ARGS) make macro to contain whatever # information needs to be passed down to the other Makefile.PL scripts. # If this does not suit your needs you'll need to write your own # MY::subdir_x() method to override this one. push @m, ' -config :: ',vmspath($subdir) . '$(MAKEFILE) - $(MMS) $(USEMAKEFILE) $(MMS$SOURCE) config $(USEMACROS)(INST_LIB=$(INST_LIB),INST_ARCHLIB=$(INST_ARCHLIB), \\ - LINKTYPE=$(LINKTYPE),INST_EXE=$(INST_EXE),LIBPERL_A=$(LIBPERL_A)$(MACROEND) $(SUBDIR_MAKEFILE_PL_ARGS) +config :: ',$subdir,'$(MAKEFILE) + olddef = F$Environment("Default") + Set Default ',$subdir,' + $(MMS) config $(PASTHRU1) $(SUBDIR_MAKEFILE_PL_ARGS) + Set Default \'olddef\' -',vmspath($subdir),'$(MAKEFILE) : ',vmspath($subdir),'Makefile.PL, $(CONFIGDEP) +',$subdir,'$(MAKEFILE) : ',$subdir,'Makefile.PL, $(CONFIGDEP) @Write Sys$Output "Rebuilding $(MMS$TARGET) ..." $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::MakeMaker; MM->runsubdirpl(qw('.$subdir.'))" \\ - $(SUBDIR_MAKEFILE_PL_ARGS) INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) \\ - INST_EXE=$(INST_EXE) LIBPERL_A=$(LIBPERL_A) LINKTYPE=$(LINKTYPE) + $(PASTHRU1) $(SUBDIR_MAKEFILE_PL_ARGS) @Write Sys$Output "Rebuild of $(MMS$TARGET) complete." # The default clean, realclean and test targets in this Makefile # have automatically been given entries for $subdir. subdirs :: - Set Default ',vmspath($subdir),' - $(MMS) all $(USEMACROS)LINKTYPE=$(LINKTYPE)$(MACROEND) + olddef = F$Environment("Default") + Set Default ',$subdir,' + $(MMS) all $(PASTHRU2) + Set Default \'olddef\' '; join('',@m); } @@ -440,25 +643,34 @@ sub clean { my($self, %attribs) = @_; my(@m); push @m, ' -# Delete temporary files but do not touch installed files -# We don\'t delete the Makefile here so that a -# later make realclean still has a makefile to work from +# Delete temporary files but do not touch installed files. We don\'t delete +# the Descrip.MMS here so that a later make realclean still has it to use. clean :: '; foreach (@{$att{DIR}}) { # clean subdirectories first my($vmsdir) = vmspath($_); - push( @m, ' If F$Search("'.$vmsdir.'$(MAKEFILE)") Then $(MMS) $(USEMAKEFILE)'.$vmsdir.'$(MAKEFILE) clean'."\n"); + push( @m, ' If F$Search("'.$vmsdir.'$(MAKEFILE)") Then \\',"\n\t", + '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n"); } - push @m, " - $att{RM_F} *.Map;* *.lis;* *.cpp;* *.Obj;* *.Olb;* \$(BOOTSTRAP);* \$(BASEEXT).bso;* -"; + push @m, ' $(RM_F) *.Map;* *.lis;* *.cpp;* *.Obj;* *.Olb;* $(BOOTSTRAP);* $(BASEEXT).bso;* +'; my(@otherfiles) = values %{$att{XS}}; # .c files from *.xs files push(@otherfiles, $attribs{FILES}) if $attribs{FILES}; push(@otherfiles, "blib.dir"); - push(@m, " $att{RM_F} ".join(";* ", map(fixpath($_),@otherfiles)),";*\n"); + my($file,$line); + $line = ''; #avoid unitialized var warning + foreach $file (@otherfiles) { + $file = fixpath($file); + if (length($line) + length($file) > 150) { + push @m, "\t\$(RM_F) $line\n"; + $line = "$file;*"; + } + else { $line .= " $file;*"; } + } + push @m, "\t\$(RM_F) $line\n\n"; # See realclean and ext/utils/make_ext for usage of Makefile.old - push(@m, " $att{MV} $att{MAKEFILE} $att{MAKEFILE}_old"); + push(@m, ' $(MV) $(MAKEFILE) $(MAKEFILE)_old'); push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; join('', @m); } @@ -473,37 +685,106 @@ realclean :: clean '); foreach(@{$att{DIR}}){ my($vmsdir) = vmspath($_); - push(@m, ' If F$Search("'."$vmsdir$att{MAKEFILE}".'").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".' realclean'."\n"); - push(@m, ' If F$Search("'."$vmsdir$att{MAKEFILE}".'_old").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".'_old realclean'."\n"); + push(@m, ' If F$Search("'."$vmsdir$att{MAKEFILE}".'").nes."" Then \\',"\n\t", + '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) realclean`;"',"\n"); + push(@m, ' If F$Search("'."$vmsdir$att{MAKEFILE}".'_old").nes."" \\',"\n\t", + '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE)_old realclean`;"'."\n"); } - push @m,' - ',$att{RM_RF},' $(INST_AUTODIR) $(INST_ARCHAUTODIR) - ',$att{RM_F},' *.Opt;* $(INST_DYNAMIC);* $(INST_STATIC);* $(INST_BOOT);* $(INST_PM);* - ',$att{RM_F},' $(OBJECT);* $(MAKEFILE);* $(MAKEFILE)_old;* + push @m,' $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR) '; - push(@m, " $att{RM_RF} ".join(";* ", map(fixpath($_),$attribs{'FILES'})),";*\n") if $attribs{'FILES'}; + my($file,$line); + my(@files) = qw{ *.Opt $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(INST_PM) $(OBJECT) $(MAKEFILE) $(MAKEFILE)_old }; + $line = ''; #avoid unitialized var warning + foreach $file (@files) { + $file = fixpath($file); + if (length($line) + length($file) > 150) { + push @m, "\t\$(RM_F) $line\n"; + $line = "$file;*"; + } + else { $line .= " $file;*"; } + } + push @m, "\t\$(RM_F) $line\n"; + if ($attribs{FILES} && ref $attribs{FILES} eq 'ARRAY') { + foreach $file (@{$attribs{'FILES'}}) { + $file = unixify($file); + if (length($line) + length($file) > 150) { + push @m, "\t\$(RM_RF) $line\n"; + $line = "$file;*"; + } + else { $line .= " $file;*"; } + } + } + push @m, "\t\$(RM_RF) $line\n"; push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; join('', @m); } -sub distclean { +sub dist { my($self, %attribs) = @_; - my($preop) = $attribs{PREOP} || '@ !'; # e.g., update MANIFEST - my($zipname) = $attribs{TARNAME} || '$(DISTNAME)-$(VERSION)'; - my($zipflags) = $attribs{ZIPFLAGS} || '-Vu'; - my($postop) = $attribs{POSTOP} || ""; + my(@m); + if ($attribs{TARNAME}){ + print STDOUT "Error (fatal): Attribute TARNAME for target dist is deprecated +Please use DISTNAME and VERSION"; + } + my($name) = $attribs{NAME} || '$(DISTNAME)-$(VERSION)'; + my($zip) = $attribs{ZIP} || 'zip'; + my($zipflags) = $attribs{ZIPFLAGS} || '-Vu'; + my($suffix) = $attribs{SUFFIX} || ''; + my($shar) = $attribs{SHAR} || 'vms_share'; + my($preop) = $attribs{PREOP} || '@ !'; # e.g., update MANIFEST + my($postop) = $attribs{POSTOP} || '@ !'; + my($dist_default) = $attribs{DIST_DEFAULT} || 'zipdist'; my($mkfiles) = join(' ', map("$_\$(MAKEFILE) $_\$(MAKEFILE)_old",map(vmspath($_),@{$att{'DIR'}}))); - " -distclean : clean - $preop - $att{RM_F} $mkfiles - Zip \"$zipflags\" $zipname \$(BASEEXT).* Makefile.PL - $postop + my($src) = $name; + $src = "[.$src]" unless $src =~ /\[/; + $src =~ s#\]#...]#; + $src .= '*.*' if $src =~ /\]$/; + $suffix =~ s#\.#_#g; + push @m," +ZIP = $zip +ZIPFLAGS = $zipflags +SUFFIX = $suffix +SHARE = $shar +PREOP = $preop +POSTOP = $postop +DIST_DEFAULT = $dist_default "; -} + push @m, ' +distclean :: realclean distcheck + +distcheck : + $(PERL) "-I$(PERL_LIB)" -e "use ExtUtils:Manifest \'&fullcheck\'; &fullcheck;" + +manifest : + $(PERL) "-I$(PERL_LIB)" -e "use ExtUtils:Manifest \'&mkmanifest\'; &mkmanifest;" + +dist : $(DIST_DEFAULT) + +zipdist : ',"${name}.zip$suffix + +${name}.zip_$suffix : distdir + ",'$(PREOP) + $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) ',$src,' + $(RM_RF) ',$name,' + $(POSTOP) + +shdist : distdir + $(PREOP) + $(SHARE) ',"$src ${name}.share$suffix",' + $(RM_RF) ',$name,' + $(POSTOP) + +distdir : + $(RM_RF) ',$name,' + $(PERL) "-I$(PERL_LIB)" -e use ExtUtils::Manifest \'/mani/\';" \\ + -e "manicopy(maniread(),',"'$name'",'); +'; + + join('',@m); +} # --- Test and Installation Sections --- @@ -512,16 +793,19 @@ sub test { my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : ''); my(@m); push @m,' +TEST_VERBOSE = 0 + test : all -'; - push(@m,' $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) -e "use Test::Harness; runtests @ARGV;" '.$tests."\n") +' if $tests; + push(@m,' $(FULLPERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" \\',"\n\t", + '-e "use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;" \\',"\n\t$tests\n") if $tests; - push(@m,' $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) test.pl',"\n") + push(@m,' $(FULLPERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" test.pl',"\n") if -f 'test.pl'; foreach(@{$att{DIR}}){ my($vmsdir) = vmspath($_); - push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir, - '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) $(USEMACRO)LINKTYPE=$(LINKTYPE)$(MACROEND) test`'."\n"); + push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", + '; print `$(MMS) $(PASTHRU2) test`'."\n"); } push(@m, "\t\@echo 'No tests defined for \$(NAME) extension.'\n") unless @m > 1; @@ -533,9 +817,10 @@ sub install { my(@m); push @m, q{ doc_install :: - @ $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) \\ + @ $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "_I$(PERL_ARCHLIB)" \\ -e "use ExtUtils::MakeMaker; MM->writedoc('Module', '$(NAME)', \\ - 'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', 'EXE_FILES=$(EXE_FILES)')" + 'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', 'EXE_FILES=$(EXE_FILES)')" \\ + >>$(INSTALLARCHLIB)perllocal.pod }; push(@m, " @@ -546,15 +831,30 @@ pure_install :: all # install subdirectories first foreach(@{$att{DIR}}){ my($vmsdir) = vmspath($_); - push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir, - '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) install`'."\n"); + push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", + '; print `$(MMS) install`"'."\n"); } - push(@m, "\t! perl5.000 used to autosplit into INST_ARCHLIB, we delete these old files here - $att{RM_F} ",fixpath(unixpath($Config{'installarchlib'}).'auto/$(FULLEXT)/*.al'),';* ', - fixpath(unixpath($Config{'installarchlib'}).'auto/$(FULLEXT)/*.ix'),";* - \$(MMS) \$(USEMACROS)INST_LIB=$Config{'installprivlib'},INST_ARCHLIB=$Config{'installarchlib'},INST_EXE=$Config{'installbin'}\$(MACROEND) -"); + push(@m, ' + @ $(PERL) -e "foreach (@ARGV){die qq{You do not have permissions to install into $$_\n} unless -w $$_}" $(INSTALLPRIVLIB) $(INSTALLARCHLIB) + ! perl5.000 and MM pre 3.8 used to autosplit into INST_ARCHLIB, we delete these old files here + $(RM_F) ',fixpath('$(INSTALLARCHLIB)/auto/$(FULLEXT)/*.al;*'),' ', + fixpath('$(INSTALLARCHLIB)/auto/$(FULLEXT)/*.ix;*')," + \$(MMS) \$(USEMACROS)INST_LIB=$att{INSTALLPRIVLIB},INST_ARCHLIB=$att{INSTALLARCHLIB},INST_EXE=$att{INSTALLBIN}\$(MACROEND)",' + @ $(PERL) -i_bak -lne "print unless $seen{$_}++" $(INST_ARCHAUTODIR).packlist +'); + + push @m, ' +#### UNINSTALL IS STILL EXPERIMENTAL #### +uninstall :: +'; + foreach(@{$att{DIR}}){ + my($vmsdir) = vmspath($_); + push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", + '; print `$(MMS) uninstall`"'."\n"); + } + push @m, "\t".'$(PERL) -e "use File::Path; foreach (<>) {chomp;rmtree($_,1,0);}" $(INST_ARCHAUTODIR).packlist +'; join("",@m); } @@ -571,14 +871,20 @@ $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)p $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h -'; - push(@m,' +' if $att{OBJECT}; -$(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh - @ Write Sys$Error "$(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh" + push(@m,' +# Check for unpropogated config.sh changes. Should never happen. +# We do NOT just update config.h because that is not sufficient. +# An out of date config.h is not fatal but complains loudly! +$(PERL_INC)config.h : $(PERL_SRC)config.sh + @ Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_SRC)config.sh" + +$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh + @ Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with $(PERL_SRC)config.sh" Set Default $(PERL_SRC) - $(MMS) $(USEMAKEFILE)[.VMS]$(MAKEFILE) [.lib]config.pm -'); + $(MMS) $(USEMAKEFILE)[.VMS]$(MAKEFILE) [.lib.',$Config{'arch'},']config.pm +') if $att{PERL_SRC}; push(@m, join(" ", map(vmsify($_),values %{$att{XS}}))." : \$(XSUBPPDEPS)\n") if %{$att{XS}}; @@ -588,24 +894,51 @@ $(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh sub makefile { my(@m,@cmd); - push(@m,' + # We do not know what target was originally specified so we + # must force a manual rerun to be sure. But as it should only + # happen very rarely it is not a significant problem. + push @m, ' +$(OBJECT) : $(MAKEFILE) # We take a very conservative approach here, but it\'s worth it. # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping. $(MAKEFILE) : Makefile.PL $(CONFIGDEP) - @ Write Sys$Output "',$att{MAKEFILE},' out-of-date with respect to $(MMS$SOURCE_LIST)" - @ Write Sys$Output "Cleaning current config before rebuilding ',$att{MAKEFILE},'... - - ',"$att{MV} $att{MAKEFILE} $att{MAKEFILE}_old",' - - $(MMS) $(USEMAKEFILE)',$att{MAKEFILE},'_old clean - $(PERL) $(I_PERL_LIBS) Makefile.PL + @ Write Sys$Output "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)" + @ Write Sys$Output "Cleaning current config before rebuilding $(MAKEFILE) ..." + - $(MV) $(MAKEFILE) $(MAKEFILE)_old + - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean + $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ',join(' ',@ARGV),' @ Write Sys$Output "Now you must rerun $(MMS)." -'); +'; join('',@m); } +# --- Make-Directories section (internal method) --- +# dir_target(@array) returns a Makefile entry for the file .exists in each +# named directory. Returns nothing, if the entry has already been processed. +# We're helpless though, if the same directory comes as $(FOO) _and_ as "bar". +# Both of them get an entry, that's why we use "::". I chose '$(PERL)' as the +# prerequisite, because there has to be one, something that doesn't change +# too often :) +%Dir_Target = (); # package global + +sub dir_target { + my($self,@dirs) = @_; + my(@m,$dir); + foreach $dir (@dirs) { + next if $Dir_Target{$dir}; + my($vmsdir) = fixpath($dir); + push @m, " +${vmsdir}.exists :: \$(PERL_INC)perl.h + \@ \$(MKPATH) $vmsdir + \@ \$(TOUCH) ${vmsdir}.exists +"; + $Dir_Target{$dir}++; + } + join "", @m; +} -# --- Determine libraries to use and how to use them --- sub makeaperl { my($self, %attribs) = @_; @@ -621,6 +954,7 @@ sub makeaperl { # Which *.olb files could we make use of... local(%olbs); + $olbs{$att{INST_ARCHAUTODIR}} = "$att{BASEEXT}.olb"; File::Find::find(sub { return unless m/\.olb$/; return if m/^libperl/; @@ -749,13 +1083,6 @@ sub new_extliblist { '','','' } -# --- Write a DynaLoader bootstrap file if required - -# VMS doesn't require a bootstrap file as a rule -sub mkbootstrap { - 1; -} - sub mksymlists { my($self,%attribs) = @_; @@ -810,671 +1137,3 @@ sub nicetext { 1; __END__ -# MM_VMS.pm -# MakeMaker default methods for VMS -# This package is inserted into @ISA of MakeMaker's MM before the -# built-in MM_Unix methods if MakeMaker.pm is run under VMS. -# -# Version: 4.03 -# Author: Charles Bailey bailey@genetics.upenn.edu -# Revised: 30-Jan-1995 - -package ExtUtils::MM_VMS; - -use Config; -require Exporter; -use File::VMSspec; -use File::Basename; - -Exporter::import('ExtUtils::MakeMaker', - qw(%att %skip %Recognized_Att_Keys $Verbose &neatvalue)); - - -sub fixpath { - my($path) = @_; - my($head,$macro,$tail); - - while (($head,$macro,$tail) = ($path =~ m#(.*?)\$\((\S+?)\)/(.*)#)) { - ($macro = unixify($att{$macro})) =~ s#/$##; - $path = "$head$macro/$tail"; - } - vmsify($path); -} - - -sub init_others { - &MM_Unix::init_others; - $att{NOOP} = "\tContinue"; - $att{MAKEFILE} = '$(MAKEFILE)'; - $att{RM_F} = '$(PERL) -e "foreach (@ARGV) { -d $_ ? rmdir $_ : unlink $_}"'; - $att{RM_RF} = '$(FULLPERL) -e "use File::Path; use File::VMSspec; @dirs = map(unixify($_),@ARGV); rmtree(\@dirs,0,0)"'; - $att{TOUCH} = '$(PERL) -e "$t=time; utime $t,$t,@ARGV"'; - $att{CP} = 'Copy/NoConfirm'; - $att{MV} = 'Rename/NoConfirm'; -} - -sub constants { - my(@m,$def); - push @m, " -NAME = $att{NAME} -DISTNAME = $att{DISTNAME} -VERSION = $att{VERSION} - -# In which library should we install this extension? -# This is typically the same as PERL_LIB. -# (also see INST_LIBDIR and relationship to ROOTEXT) -INST_LIB = ",vmspath($att{INST_LIB})," -INST_ARCHLIB = ",vmspath($att{INST_ARCHLIB})," - -# Perl library to use when building the extension -PERL_LIB = ",vmspath($att{PERL_LIB})," -PERL_ARCHLIB = ",vmspath($att{PERL_ARCHLIB})," -"; - -# Define I_PERL_LIBS to include the required -Ipaths -# To be cute we only include PERL_ARCHLIB if different -# To be portable we add quotes for VMS -my(@i_perl_libs) = qw{-I$(PERL_ARCHLIB) -I$(PERL_LIB)}; -shift(@i_perl_libs) if ($att{PERL_ARCHLIB} eq $att{PERL_LIB}); -push @m, "I_PERL_LIBS = \"".join('" "',@i_perl_libs)."\"\n"; - - push @m, " -# Where is the perl source code located? (Eventually we should -# be able to build extensions without requiring the perl source -# but that's a long way off yet). -PERL_SRC = ",vmspath($att{PERL_SRC})," -# Perl header files (will eventually be under PERL_LIB) -PERL_INC = ",vmspath($att{PERL_INC})," -# Perl binaries -PERL = $att{PERL} -FULLPERL = $att{FULLPERL} - -# FULLEXT = Pathname for extension directory (eg DBD/Oracle). -# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. -# ROOTEXT = Directory part of FULLEXT with leading slash (e.g /DBD) -FULLEXT = ",vmsify($att{FULLEXT})," -BASEEXT = $att{BASEEXT} -ROOTEXT = ",$att{ROOTEXT} eq '' ? '[]' : vmspath($att{ROOTEXT})," - -INC = "; - - if ($att{'INC'}) { - push @m,'/Include=('; - my(@includes) = split(/\s+/,$att{INC}); - foreach (@includes) { - s/^-I//; - push @m,vmspath($_); - } - push @m, ")\n"; - } - - if ($att{DEFINE} ne '') { - my(@defs) = split(/\s+/,$att{DEFINE}); - foreach $def (@defs) { - $def =~ s/^-D//; - $def = "\"$def\"" if $def =~ /=/; - } - $att{DEFINE} = join ',',@defs; - } - - push @m," -DEFINE = $att{DEFINE} -OBJECT = ",vmsify($att{OBJECT})," -LDFROM = ",vmsify($att{LDFROM})," -LINKTYPE = $att{LINKTYPE} - -# Handy lists of source code files: -XS_FILES = ",join(', ', sort keys %{$att{XS}})," -C_FILES = ",join(', ', @{$att{C}})," -O_FILES = ",join(', ', @{$att{O_FILES}})," -H_FILES = ",join(', ', @{$att{H}})," - -.SUFFIXES : .xs - -# This extension may link to it's own library (see SDBM_File)"; - push @m," -MYEXTLIB = ",vmsify($att{MYEXTLIB})," - -# Here is the Config.pm that we are using/depend on -CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h - -# Where to put things: -INST_LIBDIR = ",($att{'INST_LIBDIR'} = vmspath(unixpath($att{INST_LIB}) . unixpath($att{ROOTEXT})))," -INST_ARCHLIBDIR = ",($att{'INST_ARCHLIBDIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . unixpath($att{ROOTEXT})))," - -INST_AUTODIR = ",($att{'INST_AUTODIR'} = vmspath(unixpath($att{INST_LIB}) . 'auto/' . unixpath($att{FULLEXT}))),' -INST_ARCHAUTODIR = ',($att{'INST_ARCHAUTODIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . 'auto/' . unixpath($att{FULLEXT}))),' - -INST_STATIC = $(INST_ARCHLIBDIR)$(BASEEXT).olb -INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT) -INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs -INST_PM = ',join(', ',map(fixpath($_),sort values %{$att{PM}})),' -'; - - join('',@m); -} - - -sub const_cccmd { - my($cmd) = $Config{'cc'}; - my($name,$sys,@m); - - ( $name = $att{NAME} . "_cflags" ) =~ s/:/_/g ; - warn "Unix shell script ".$Config{"$att{'BASEEXT'}_cflags"}. - " required to modify CC command for $att{'BASEEXT'}\n" - if ($Config{$name}); - - # Deal with $att{DEFINE} here since some C compilers pay attention - # to only one /Define clause on command line, so we have to - # conflate the ones from $Config{'cc'} and $att{DEFINE} - if ($att{DEFINE} ne '') { - if ($cmd =~ m:/define=\(?([^\(\/\)]+)\)?:i) { - $cmd = $` . "/Define=(" . $1 . ",$att{DEFINE})" . $'; - } - else { $cmd .= "/Define=($att{DEFINE})" } - } - - $sys = ($cmd =~ /^gcc/i) ? 'GNU_CC_Include:[VMS]' : 'Sys$Library'; - push @m,' -.FIRST - @ If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS ',$sys,' - -'; - push(@m, "CCCMD = $cmd\n"); - - join('',@m); -} - - - -sub const_loadlibs{ - my (@m); - push @m, " -# $att{NAME} might depend on some other libraries. -# -# Dependent libraries are linked in either by the Link command -# at build time or by the DynaLoader at bootstrap time. -# -# These comments may need revising: -# -# EXTRALIBS = Full list of libraries needed for static linking. -# Only those libraries that actually exist are included. -# -# BSLOADLIBS = List of those libraries that are needed but can be -# linked in dynamically. -# -# LDLOADLIBS = List of those libraries which must be statically -# linked into the shared library. -# -EXTRALIBS = ",map(vmsify($_) . ' ',$att{'EXTRALIBS'})," -BSLOADLIBS = ",map(vmsify($_) . ' ',$att{'BSLOADLIBS'})," -LDLOADLIBS = ",map(vmsify($_) . ' ',$att{'LDLOADLIBS'}),"\n"; - - join('',@m); -} - -# --- Tool Sections --- - -sub tool_autosplit{ - my($self, %attribs) = @_; - my($asl) = ""; - $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN}; - q{ -# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto -AUTOSPLITFILE = $(PERL) $(I_PERL_LIBS) -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;" -}; -} - -sub tool_xsubpp{ - my($xsdir) = unixpath($att{PERL_LIB}).'ExtUtils'; - # drop back to old location if xsubpp is not in new location yet - $xsdir = unixpath($att{PERL_SRC}).'ext' unless (-f "$xsdir/xsubpp"); - my(@tmdeps) = '$(XSUBPPDIR)typemap'; - push(@tmdeps, "typemap") if -f "typemap"; - my(@tmargs) = map("-typemap $_", @tmdeps); - " -XSUBPPDIR = ".vmspath($xsdir)." -XSUBPP = \$(PERL) \$(XSUBPPDIR)xsubpp -XSUBPPDEPS = @tmdeps -XSUBPPARGS = @tmargs -"; -} - -sub tools_other { - " -# Assumes \$(MMS) invokes MMS or MMK -USEMAKEFILE = /Descrip= -USEMACROS = /Macro=( -MACROEND = ) -MAKEFILE = Descrip.MMS -SHELL = Posix -LD = $att{LD} -TOUCH = $att{TOUCH} -CP = $att{CP} -RM_F = $att{RM_F} -RM_RF = $att{RM_RF} -MKPATH = Create/Directory -"; -} - - -# --- Translation Sections --- - -sub c_o { - ' -.c.obj : - $(CCCMD) $(CCCDLFLAGS) /Include=($(PERL_INC)) $(INC) $(MMS$TARGET_NAME).c -'; -} - -sub xs_c { - ' -.xs.c : - $(XSUBPP) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET) -'; -} - -sub xs_o { # many makes are too dumb to use xs_c then c_o - ' -.xs.obj : - $(XSUBPP) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c - $(CCCMD) $(CCCDLFLAGS) /Include=($(PERL_INC)) $(INC) $(MMS$TARGET_NAME).c -'; -} - - -# --- Target Sections --- - -sub top_targets{ - ' -all :: config linkext $(INST_PM) -'.$att{NOOP}.' - -config :: '.$att{MAKEFILE}.' - @ $(MKPATH) $(INST_LIBDIR), $(INST_ARCHAUTODIR) -'; -} - -sub dlsyms { - my($self,%attribs) = @_; - my($funcs) = $attribs{DL_FUNCS} || $att{DL_FUNCS} || {}; - my($vars) = $attribs{DL_VARS} || $att{DL_VARS} || []; - my(@m); - - push(@m,' -dynamic :: perlshr.opt $(BASEEXT).opt - ',$att{NOOP},' - -perlshr.opt : makefile.PL - $(FULLPERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ', - %$funcs ? neatvalue($funcs) : "' '",', DL_VARS => ', - @$vars ? neatvalue($vars) : "' '",')" -') unless $skip{'dynamic'}; - - push(@m,' -static :: $(BASEEXT).opt - ',$att{NOOP},' -') unless $skip{'static'}; - - push(@m,' -$(BASEEXT).opt : makefile.PL - $(FULLPERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ',neatvalue($att{DL_FUNCS}),', DL_VARS => ',neatvalue($att{DL_VARS}),')" -'); - - join('',@m); -} - - -# --- Dynamic Loading Sections --- - -sub dynamic_lib { - my($self, %attribs) = @_; - my($otherldflags) = $attribs{OTHERLDFLAGS} || ""; - my(@m); - push @m," - -OTHERLDFLAGS = $otherldflags - -"; - push @m, ' -$(INST_DYNAMIC) : $(OBJECT) $(MYEXTLIB) $(PERL_INC)perlshr_attr.opt $(PERL_INC)crtl.opt perlshr.opt $(BASEEXT).opt - @ $(MKPATH) $(INST_ARCHAUTODIR) - Link $(LDFLAGS) /Shareable/Executable=$(MMS$TARGET)$(OTHERLDFLAGS) $(OBJECT),$(PERL_INC)perlshr_attr.opt/Option,$(PERL_INC)crtl.opt/Option,[]perlshr.opt/Option,[]$(BASEEXT).opt/Option -'; - - join('',@m); -} - -# --- Static Loading Sections --- - -sub static_lib { - my(@m); - push @m, <<'END'; -$(INST_STATIC) : $(OBJECT), $(MYEXTLIB) - If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET) - Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST) -END - push @m," - $att{CP}",'$(MMS$SOURCE) $(INST_ARCHAUTODIR) - $(PERL) -e "print ""$(MMS$TARGET)\n""" >$(INST_ARCHAUTODIR)extralibs.ld -'; - push @m, <<'END' if $att{PERL_SRC}; - @! Old mechanism - still needed: - $(PERL) -e "print ""$(MMS$TARGET)\n""" >>$(PERL_SRC)ext.libs -END - - join('',@m); -} - - -sub installpm_x { # called by installpm perl file - my($self, $dist, $inst, $splitlib) = @_; - $inst = fixpath($inst); - $dist = vmsify($dist); - my($instdir) = dirname($inst); - my(@m); - - push(@m, " -$inst : $dist -",' @ ',$att{RM_F},' $(MMS$TARGET);* - @ $(MKPATH) ',$instdir,' - @ ',$att{CP},' $(MMS$SOURCE) $(MMS$TARGET) -'); - if ($splitlib and $inst =~ /\.pm$/) { - my($attdir) = $splitlib; - $attdir =~ s/\$\((.*)\)/$1/; - $attdir = $att{$attdir} if $att{$attdir}; - - push(@m, ' $(AUTOSPLITFILE) $(MMS$TARGET) ', - vmspath(unixpath($attdir) . 'auto')."\n"); - push(@m,"\n"); - } - - join('',@m); -} - - -# --- Sub-directory Sections --- - -sub subdir_x { - my($self, $subdir) = @_; - my(@m); - # The intention is that the calling Makefile.PL should define the - # $(SUBDIR_MAKEFILE_PL_ARGS) make macro to contain whatever - # information needs to be passed down to the other Makefile.PL scripts. - # If this does not suit your needs you'll need to write your own - # MY::subdir_x() method to override this one. - push @m, ' -config :: ',vmspath($subdir) . '$(MAKEFILE) - $(MMS) $(USEMAKEFILE) $(MMS$SOURCE) config $(USEMACROS)(INST_LIB=$(INST_LIB),INST_ARCHLIB=$(INST_ARCHLIB),LINKTYPE=$(LINKTYPE)$(MACROEND) - -',vmspath($subdir),'$(MAKEFILE) : ',vmspath($subdir),'Makefile.PL, $(CONFIGDEP) - @Write Sys$Output "Rebuilding $(MMS$TARGET) ..." - $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::MakeMaker; MM->runsubdirpl(qw('.$subdir.'))" \\ - $(SUBDIR_MAKEFILE_PL_ARGS) INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) - @Write Sys$Output "Rebuild of $(MMS$TARGET) complete." - -# The default clean, realclean and test targets in this Makefile -# have automatically been given entries for $subdir. - -subdirs :: - Set Default ',vmspath($subdir),' - $(MMS) all $(USEMACROS)LINKTYPE=$(LINKTYPE)$(MACROEND) -'; - join('',@m); -} - - -# --- Cleanup and Distribution Sections --- - -sub clean { - my($self, %attribs) = @_; - my(@m); - push @m, ' -# Delete temporary files but do not touch installed files -# We don\'t delete the Makefile here so that a -# later make realclean still has a makefile to work from -clean :: -'; - foreach (@{$att{DIR}}) { # clean subdirectories first - my($vmsdir) = vmspath($_); - push( @m, ' If F$Search("'.$vmsdir.'$(MAKEFILE)") Then $(MMS) $(USEMAKEFILE)'.$vmsdir.'$(MAKEFILE) clean'."\n"); - } - push @m, " - $att{RM_F} *.Map;* *.lis;* *.cpp;* *.Obj;* *.Olb;* \$(BOOTSTRAP);* \$(BASEEXT).bso;* -"; - - my(@otherfiles) = values %{$att{XS}}; # .c files from *.xs files - push(@otherfiles, $attribs{FILES}) if $attribs{FILES}; - push(@otherfiles, "blib.dir"); - push(@m, " $att{RM_F} ".join(";* ", map(fixpath($_),@otherfiles)),";*\n"); - # See realclean and ext/utils/make_ext for usage of Makefile.old - push(@m, " $att{MV} $att{MAKEFILE} $att{MAKEFILE}_old"); - push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; - join('', @m); -} - - -sub realclean { - my($self, %attribs) = @_; - my(@m); - push(@m,' -# Delete temporary files (via clean) and also delete installed files -realclean :: clean -'); - foreach(@{$att{DIR}}){ - my($vmsdir) = vmspath($_); - push(@m, ' If F$Search("'."$vmsdir$att{MAKEFILE}".'").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".' realclean'."\n"); - push(@m, ' If F$Search("'."$vmsdir$att{MAKEFILE}".'_old").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".'_old realclean'."\n"); - } - push @m,' - ',$att{RM_RF},' $(INST_AUTODIR) $(INST_ARCHAUTODIR) - ',$att{RM_F},' *.Opt;* $(INST_DYNAMIC);* $(INST_STATIC);* $(INST_BOOT);* $(INST_PM);* - ',$att{RM_F},' $(OBJECT);* $(MAKEFILE);* $(MAKEFILE)_old;* -'; - push(@m, " $att{RM_RF} ".join(";* ", map(fixpath($_),$attribs{'FILES'})),";*\n") if $attribs{'FILES'}; - push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; - join('', @m); -} - - -sub distclean { - my($self, %attribs) = @_; - my($preop) = $attribs{PREOP} || '@ !'; # e.g., update MANIFEST - my($zipname) = $attribs{ZIPNAME} || '$(DISTNAME)-$(VERSION)'; - my($zipflags) = $attribs{ZIPFLAGS} || '-Vu'; - my($postop) = $attribs{POSTOP} || ""; - my(@mkfildirs) = map(vmspath($_),@{$att{'DIR'}}); - my(@m,$dir); - - push @m,' -distclean : realclean - ',$preop,' - If F$Search("$(MAKEFILE)").nes."" Then ',$att{RM_F},' $(MAKEFILE);* -'; - foreach $dir (@mkfildirs) { - push(@m,'If F$Search("',$dir,'$(MAKEFILE)") Then Delete/Log/NoConfirm ', - $dir,'$(MAKEFILE);*',"\n"); - } - - push(@m," Zip \"$zipflags\" $zipname \$(BASEEXT).* Makefile.PL - $postop -"); - - join('',@m); -} - - -# --- Test and Installation Sections --- - -sub test { - my($self, %attribs) = @_; - my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : ''); - my(@m); - push @m,' -test : all -'; - push(@m,' $(FULLPERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) -e "use Test::Harness; runtests @ARGV;" '.$tests."\n") - if $tests; - push(@m,' $(FULLPERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" test.pl',"\n") - if -f 'test.pl'; - foreach(@{$att{DIR}}){ - my($vmsdir) = vmspath($_); - push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir, - '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) $(USEMACRO)LINKTYPE=$(LINKTYPE)$(MACROEND) test`'."\n"); - } - push(@m, "\t\@echo 'No tests defined for \$(NAME) extension.'\n") unless @m > 1; - - join('',@m); -} - -sub install { - my($self, %attribs) = @_; - my(@m); - push(@m, " -install :: all -"); - # install subdirectories first - foreach(@{$att{DIR}}){ - my($vmsdir) = vmspath($_); - push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir, - '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) install`'."\n"); - } - - push(@m, "\t! perl5.000 used to autosplit into INST_ARCHLIB, we delete these old files here - $att{RM_F} ",fixpath('$(INST_ARCHLIB)/auto/$(FULLEXT)/*.al'),";*,",fixpath('$(INST_ARCHLIB)/auto/$(FULLEXT)/*.ix'),';* - $(MMS) $(USEMACROS)INST_LIB=\$(INST_PRIVLIB),INST_ARCHLIB=\$(INST_ARCHLIB)$(MACROEND) -'); - - join("",@m); -} - -sub perldepend { - my(@m); - - push @m, ' -$(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h -$(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h -$(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h -$(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h -$(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h -$(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h -$(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h -$(O_FILES) : $(H_FILES) - -'; - push(@m,' - -$(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh - @ Write Sys$Error "$(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh" - Set Default $(PERL_SRC) - $(MMS) $(USEMAKEFILE)[.VMS]$(MAKEFILE) [.lib]config.pm -'); - - push(@m, join(" ", map(vmsify($_),values %{$att{XS}}))." : \$(XSUBPPDEPS)\n") - if %{$att{XS}}; - - join('',@m); -} - -sub makefile { - my(@m,@cmd); - @cmd = grep(/^\s/,split(/\n/,MY->c_o())); - push(@m,join("\n",@cmd)); - push(@m,' - -# We take a very conservative approach here, but it\'s worth it. -# We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping. -$(MAKEFILE) : Makefile.PL $(CONFIGDEP) - @ Write Sys$Output "',$att{MAKEFILE},' out-of-date with respect to $(MMS$SOURCE_LIST)" - @ Write Sys$Output "Cleaning current config before rebuilding ',$att{MAKEFILE},'... - - ',"$att{MV} $att{MAKEFILE} $att{MAKEFILE}_old",' - - $(MMS) $(USEMAKEFILE)',$att{MAKEFILE},'_old clean - $(PERL) $(I_PERL_LIBS) Makefile.PL - @ Write Sys$Output "Now you must rerun $(MMS)." -'); - - join('',@m); -} - - -# --- Determine libraries to use and how to use them --- - -sub extliblist { - '','',''; -} - -sub old_extliblist { - '','','' -} - -sub new_extliblist { - '','','' -} - -# --- Write a DynaLoader bootstrap file if required - -# VMS doesn't require a bootstrap file as a rule -sub mkbootstrap { - 1; -} - -sub mksymlists { - my($self,%attribs) = @_; - - MY->init_main() unless $att{BASEEXT}; - - my($vars) = $attribs{DL_VARS} || $att{DL_VARS} || []; - my($procs) = $attribs{DL_FUNCS} || $att{DL_FUNCS}; - my($package,$packprefix,$sym); - if (!%$procs) { - $package = $attribs{NAME} || $att{NAME}; - $package =~ s/\W/_/g; - $procs = { $package => ["boot_$package"] }; - } - my($isvax) = $Config{'arch'} =~ /VAX/i; - # First, a short linker options file to specify PerlShr - # used only when linking dynamic extension - open OPT, ">PerlShr.Opt"; - print OPT "PerlShr/Share\n"; - close OPT; - - # Next, the options file declaring universal symbols - # Used when linking shareable image for dynamic extension, - # or when linking PerlShr into which we've added this package - # as a static extension - # We don't do anything to preserve order, so we won't relax - # the GSMATCH criteria for a dynamic extension - open OPT, ">$att{BASEEXT}.opt"; - foreach $package (keys %$procs) { - ($packprefix = $package) =~ s/\W/_/g; - foreach $sym (@{$$procs{$package}}) { - $sym = "XS_${packprefix}_$sym" unless $sym =~ /^boot_/; - if ($isvax) { print OPT "UNIVERSAL=$sym\n" } - else { print OPT "SYMBOL_VECTOR=($sym=PROCEDURE)\n"; } - } - } - foreach $sym (@$vars) { - print OPT "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n"; - if ($isvax) { print OPT "UNIVERSAL=$sym\n" } - else { print OPT "SYMBOL_VECTOR=($sym=DATA)\n"; } - } - close OPT; -} - -# --- Output postprocessing section --- - -sub nicetext { - # Insure that colons marking targets are preceded by space - - # most Unix Makes don't need this, but it's necessary under VMS - # to distinguish the target delimiter from a colon appearing as - # part of a filespec. - - my($self,$text) = @_; - $text =~ s/([^\s:])(:+\s)/$1 $2/gs; - $text; -} - -1; - -__END__ |