From 4916b8f2e32f0123ef193969a0610f9f24783beb Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Thu, 18 Dec 2025 16:07:52 -0500 Subject: [PATCH 01/11] Standardize leading whitespace on 4 inside build_extension() We'll need to do some refactoring and re-arranging of code in make_ext.pl to address GH #24014. That will be easier to do if we tidy up the code inside sub build_extension(): 300+ lines with a mixture of hard tabs and whitespace for leading indents. However, for the time being we won't do additional tidying (e.g., uncuddling else's) because that would change line numbers. --- make_ext.pl | 244 ++++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index ba507c8abc33..3347f5163e84 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -31,14 +31,14 @@ # make_ext.pl "MAKE=make [-make_opts]" --dir=directory [--target=target] [--static|--dynamic|--all] +ext2 !ext1 # # E.g. -# +# # make_ext.pl "MAKE=nmake -nologo" --dir=..\ext -# +# # make_ext.pl "MAKE=nmake -nologo" --dir=..\ext --target=clean -# +# # Will skip building extensions which are marked with an '!' char. # Mostly because they still not ported to specified platform. -# +# # If any extensions are listed with a '+' char then only those # extensions will be built, but only if they aren't countermanded # by an '!ext' and are appropriate to the type of building being done. @@ -276,8 +276,8 @@ sub build_extension { my ($ext_dir, $perl, $mname, $target, $pass_through) = @_; unless (chdir "$ext_dir") { - warn "Cannot cd to $ext_dir: $!"; - return; + warn "Cannot cd to $ext_dir: $!"; + return; } my $up = $ext_dir; @@ -289,42 +289,42 @@ sub build_extension { my ($makefile, $makefile_no_minus_f); if (IS_VMS) { - $makefile = 'descrip.mms'; - if ($target =~ /clean$/ - && !-f $makefile - && -f "${makefile}_old") { - $makefile = "${makefile}_old"; - } + $makefile = 'descrip.mms'; + if ($target =~ /clean$/ + && !-f $makefile + && -f "${makefile}_old") { + $makefile = "${makefile}_old"; + } } else { - $makefile = 'Makefile'; + $makefile = 'Makefile'; } - + if (-f $makefile) { - $makefile_no_minus_f = 0; - open my $mfh, '<', $makefile or die "Cannot open $makefile: $!"; - while (<$mfh>) { - # Plagiarised from CPAN::Distribution - last if /MakeMaker post_initialize section/; - next unless /^#\s+VERSION_FROM\s+=>\s+(.+)/; - my $vmod = eval $1; - my $oldv; - while (<$mfh>) { - next unless /^XS_VERSION = (\S+)/; - $oldv = $1; - last; - } - last unless defined $oldv; - require ExtUtils::MM_Unix; - defined (my $newv = parse_version MM $vmod) or last; - if (version->parse($newv) ne $oldv) { - close $mfh or die "close $makefile: $!"; - _unlink($makefile); - { - no warnings 'deprecated'; - goto NO_MAKEFILE; - } - } - } + $makefile_no_minus_f = 0; + open my $mfh, '<', $makefile or die "Cannot open $makefile: $!"; + while (<$mfh>) { + # Plagiarised from CPAN::Distribution + last if /MakeMaker post_initialize section/; + next unless /^#\s+VERSION_FROM\s+=>\s+(.+)/; + my $vmod = eval $1; + my $oldv; + while (<$mfh>) { + next unless /^XS_VERSION = (\S+)/; + $oldv = $1; + last; + } + last unless defined $oldv; + require ExtUtils::MM_Unix; + defined (my $newv = parse_version MM $vmod) or last; + if (version->parse($newv) ne $oldv) { + close $mfh or die "close $makefile: $!"; + _unlink($makefile); + { + no warnings 'deprecated'; + goto NO_MAKEFILE; + } + } + } if (IS_CROSS) { # If we're cross-compiling, it's possible that the host's @@ -352,40 +352,40 @@ sub build_extension { } } } else { - $makefile_no_minus_f = 1; + $makefile_no_minus_f = 1; } if ($makefile_no_minus_f || !-f $makefile) { - NO_MAKEFILE: - if (!-f 'Makefile.PL') { + NO_MAKEFILE: + if (!-f 'Makefile.PL') { unless (just_pm_to_blib($target, $ext_dir, $mname, $return_dir)) { # No problems returned, so it has faked everything for us. :-) chdir $return_dir || die "Cannot cd to $return_dir: $!"; return; } - print "\nCreating Makefile.PL in $ext_dir for $mname\n" if $verbose; - my ($fromname, $key, $value); - - $key = 'ABSTRACT_FROM'; - # We need to cope well with various possible layouts - my @dirs = split /::/, $mname; - my $leaf = pop @dirs; - my $leafname = "$leaf.pm"; - my $pathname = join '/', @dirs, $leafname; - my @locations = ($leafname, $pathname, "lib/$pathname"); - foreach (@locations) { - if (-f $_) { - $fromname = $_; - last; - } - } + print "\nCreating Makefile.PL in $ext_dir for $mname\n" if $verbose; + my ($fromname, $key, $value); + + $key = 'ABSTRACT_FROM'; + # We need to cope well with various possible layouts + my @dirs = split /::/, $mname; + my $leaf = pop @dirs; + my $leafname = "$leaf.pm"; + my $pathname = join '/', @dirs, $leafname; + my @locations = ($leafname, $pathname, "lib/$pathname"); + foreach (@locations) { + if (-f $_) { + $fromname = $_; + last; + } + } - unless ($fromname) { - die "For $mname tried @locations in $ext_dir but can't find source"; - } - ($value = $fromname) =~ s/\.pm\z/.pod/; - $value = $fromname unless -e $value; + unless ($fromname) { + die "For $mname tried @locations in $ext_dir but can't find source"; + } + ($value = $fromname) =~ s/\.pm\z/.pod/; + $value = $fromname unless -e $value; if ($mname eq 'Pod::Checker') { # the abstract in the .pm file is unparseable by MM, @@ -397,9 +397,9 @@ sub build_extension { $value = 'Pod::Checker verifies POD documentation contents for compliance with the POD format specifications'; } - open my $fh, '>', 'Makefile.PL' - or die "Can't open Makefile.PL for writing: $!"; - printf $fh <<'EOM', $0, $mname, $fromname, $key, $value; + open my $fh, '>', 'Makefile.PL' + or die "Can't open Makefile.PL for writing: $!"; + printf $fh <<'EOM', $0, $mname, $fromname, $key, $value; #-*- buffer-read-only: t -*- # This Makefile.PL was written by %s. @@ -452,17 +452,17 @@ sub build_extension { # ex: set ro: EOM - close $fh or die "Can't close Makefile.PL: $!"; - # As described in commit 23525070d6c0e51f: - # Push the atime and mtime of generated Makefile.PLs back 4 - # seconds. In certain circumstances ( on virtual machines ) the - # generated Makefile.PL can produce a Makefile that is older than - # the Makefile.PL. Altering the atime and mtime backwards by 4 - # seconds seems to resolve the issue. - eval { - my $ftime = (stat('Makefile.PL'))[9] - 4; - utime $ftime, $ftime, 'Makefile.PL'; - }; + close $fh or die "Can't close Makefile.PL: $!"; + # As described in commit 23525070d6c0e51f: + # Push the atime and mtime of generated Makefile.PLs back 4 + # seconds. In certain circumstances ( on virtual machines ) the + # generated Makefile.PL can produce a Makefile that is older than + # the Makefile.PL. Altering the atime and mtime backwards by 4 + # seconds seems to resolve the issue. + eval { + my $ftime = (stat('Makefile.PL'))[9] - 4; + utime $ftime, $ftime, 'Makefile.PL'; + }; } elsif ($mname =~ /\A(?:Carp |ExtUtils::CBuilder |Safe @@ -505,46 +505,46 @@ sub build_extension { chdir $return_dir || die "Cannot cd to $return_dir: $!"; return; } - } + } # We are going to have to use Makefile.PL: - print "\nRunning Makefile.PL in $ext_dir\n" if $verbose; + print "\nRunning Makefile.PL in $ext_dir\n" if $verbose; - my @args = ("-I$lib_dir", 'Makefile.PL'); - if (IS_VMS) { - my $libd = VMS::Filespec::vmspath($lib_dir); - push @args, "INST_LIB=$libd", "INST_ARCHLIB=$libd"; - } else { - push @args, 'INSTALLDIRS=perl', 'INSTALLMAN1DIR=none', - 'INSTALLMAN3DIR=none'; - } - push @args, @$pass_through; - push @args, 'PERL=' . $perl if $perl; # use miniperl to run the Makefile later - _quote_args(\@args) if IS_VMS; - print join(' ', $perl, @args), "\n" if $verbose; - my $code = do { - local $ENV{PERL_MM_USE_DEFAULT} = 1; - system $perl, @args; - }; - if($code != 0){ - #make sure next build attempt/run of make_ext.pl doesn't succeed - _unlink($makefile); - die "Unsuccessful Makefile.PL($ext_dir): code=$code"; - } + my @args = ("-I$lib_dir", 'Makefile.PL'); + if (IS_VMS) { + my $libd = VMS::Filespec::vmspath($lib_dir); + push @args, "INST_LIB=$libd", "INST_ARCHLIB=$libd"; + } else { + push @args, 'INSTALLDIRS=perl', 'INSTALLMAN1DIR=none', + 'INSTALLMAN3DIR=none'; + } + push @args, @$pass_through; + push @args, 'PERL=' . $perl if $perl; # use miniperl to run the Makefile later + _quote_args(\@args) if IS_VMS; + print join(' ', $perl, @args), "\n" if $verbose; + my $code = do { + local $ENV{PERL_MM_USE_DEFAULT} = 1; + system $perl, @args; + }; + if($code != 0){ + #make sure next build attempt/run of make_ext.pl doesn't succeed + _unlink($makefile); + die "Unsuccessful Makefile.PL($ext_dir): code=$code"; + } - # Right. The reason for this little hack is that we're sitting inside - # a program run by ./miniperl, but there are tasks we need to perform - # when the 'realclean', 'distclean' or 'veryclean' targets are run. - # Unfortunately, they can be run *after* 'clean', which deletes - # ./miniperl - # So we do our best to leave a set of instructions identical to what - # we would do if we are run directly as 'realclean' etc - # Whilst we're perfect, unfortunately the targets we call are not, as - # some of them rely on a $(PERL) for their own distclean targets. - # But this always used to be a problem with the old /bin/sh version of - # this. - if (IS_UNIX) { - foreach my $clean_target ('realclean', 'veryclean') { + # Right. The reason for this little hack is that we're sitting inside + # a program run by ./miniperl, but there are tasks we need to perform + # when the 'realclean', 'distclean' or 'veryclean' targets are run. + # Unfortunately, they can be run *after* 'clean', which deletes + # ./miniperl + # So we do our best to leave a set of instructions identical to what + # we would do if we are run directly as 'realclean' etc + # Whilst we're perfect, unfortunately the targets we call are not, as + # some of them rely on a $(PERL) for their own distclean targets. + # But this always used to be a problem with the old /bin/sh version of + # this. + if (IS_UNIX) { + foreach my $clean_target ('realclean', 'veryclean') { fallback_cleanup($return_dir, $clean_target, <<"EOS"); cd $ext_dir if test ! -f Makefile -a -f Makefile.old; then @@ -552,26 +552,26 @@ sub build_extension { make -f Makefile.old $clean_target MAKE='@make' @pass_through else if test ! -f Makefile ; then - echo "Warning: No Makefile!" + echo "Warning: No Makefile!" fi @make $clean_target MAKE='@make' @pass_through fi cd $return_dir EOS - } - } + } + } } if (not -f $makefile) { - print "Warning: No Makefile!\n"; + print "Warning: No Makefile!\n"; } if (IS_VMS) { - _quote_args($pass_through); - @$pass_through = ( - "/DESCRIPTION=$makefile", - '/MACRO=(' . join(',',@$pass_through) . ')' - ); + _quote_args($pass_through); + @$pass_through = ( + "/DESCRIPTION=$makefile", + '/MACRO=(' . join(',',@$pass_through) . ')' + ); } my @targ = ($target, @$pass_through); From 3c0e80e9b9fe14f361ab55294abc644949e777f0 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Thu, 18 Dec 2025 16:37:45 -0500 Subject: [PATCH 02/11] Indent 2 here-docs We're going to be shifting a lot of code around during refactoring. So let's grant ourselves the flexibility of indented here-docs. --- make_ext.pl | 134 ++++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index 3347f5163e84..6fac988db99b 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -330,7 +330,7 @@ sub build_extension { # If we're cross-compiling, it's possible that the host's # Makefiles are around. seek($mfh, 0, 0) or die "Cannot seek $makefile: $!"; - + my $cross_makefile; while (<$mfh>) { # XXX This might not be throughout enough. @@ -344,7 +344,7 @@ sub build_extension { last; } } - + if (!$cross_makefile) { print "Deleting non-Cross makefile\n"; close $mfh or die "close $makefile: $!"; @@ -399,59 +399,59 @@ sub build_extension { open my $fh, '>', 'Makefile.PL' or die "Can't open Makefile.PL for writing: $!"; - printf $fh <<'EOM', $0, $mname, $fromname, $key, $value; -#-*- buffer-read-only: t -*- - -# This Makefile.PL was written by %s. -# It will be deleted automatically by make realclean - -use strict; -use ExtUtils::MakeMaker; - -# This is what the .PL extracts to. Not the ultimate file that is installed. -# (ie Win32 runs pl2bat after this) - -# Doing this here avoids all sort of quoting issues that would come from -# attempting to write out perl source with literals to generate the arrays and -# hash. -my @temps = 'Makefile.PL'; -foreach (glob('scripts/pod*.PL')) { - # The various pod*.PL extractors change directory. Doing that with relative - # paths in @INC breaks. It seems the lesser of two evils to copy (to avoid) - # the chdir doing anything, than to attempt to convert lib paths to - # absolute, and potentially run into problems with quoting special - # characters in the path to our build dir (such as spaces) - require File::Copy; - - my $temp = $_; - $temp =~ s!scripts/!!; - File::Copy::copy($_, $temp) or die "Can't copy $temp to $_: $!"; - push @temps, $temp; -} + printf $fh <<~'EOM', $0, $mname, $fromname, $key, $value; + #-*- buffer-read-only: t -*- + + # This Makefile.PL was written by %s. + # It will be deleted automatically by make realclean + + use strict; + use ExtUtils::MakeMaker; + + # This is what the .PL extracts to. Not the ultimate file that is installed. + # (ie Win32 runs pl2bat after this) + + # Doing this here avoids all sort of quoting issues that would come from + # attempting to write out perl source with literals to generate the arrays and + # hash. + my @temps = 'Makefile.PL'; + foreach (glob('scripts/pod*.PL')) { + # The various pod*.PL extractors change directory. Doing that with relative + # paths in @INC breaks. It seems the lesser of two evils to copy (to avoid) + # the chdir doing anything, than to attempt to convert lib paths to + # absolute, and potentially run into problems with quoting special + # characters in the path to our build dir (such as spaces) + require File::Copy; + + my $temp = $_; + $temp =~ s!scripts/!!; + File::Copy::copy($_, $temp) or die "Can't copy $temp to $_: $!"; + push @temps, $temp; + } -my $script_ext = $^O eq 'VMS' ? '.com' : ''; -my %%pod_scripts; -foreach (glob('pod*.PL')) { - my $script = $_; - s/.PL$/$script_ext/i; - $pod_scripts{$script} = $_; -} -my @exe_files = values %%pod_scripts; - -WriteMakefile( - NAME => '%s', - VERSION_FROM => '%s', - %-13s => '%s', - realclean => { FILES => "@temps" }, - (%%pod_scripts ? ( - PL_FILES => \%%pod_scripts, - EXE_FILES => \@exe_files, - clean => { FILES => "@exe_files" }, - ) : ()), -); - -# ex: set ro: -EOM + my $script_ext = $^O eq 'VMS' ? '.com' : ''; + my %%pod_scripts; + foreach (glob('pod*.PL')) { + my $script = $_; + s/.PL$/$script_ext/i; + $pod_scripts{$script} = $_; + } + my @exe_files = values %%pod_scripts; + + WriteMakefile( + NAME => '%s', + VERSION_FROM => '%s', + %-13s => '%s', + realclean => { FILES => "@temps" }, + (%%pod_scripts ? ( + PL_FILES => \%%pod_scripts, + EXE_FILES => \@exe_files, + clean => { FILES => "@exe_files" }, + ) : ()), + ); + + # ex: set ro: + EOM close $fh or die "Can't close Makefile.PL: $!"; # As described in commit 23525070d6c0e51f: # Push the atime and mtime of generated Makefile.PLs back 4 @@ -545,19 +545,19 @@ sub build_extension { # this. if (IS_UNIX) { foreach my $clean_target ('realclean', 'veryclean') { - fallback_cleanup($return_dir, $clean_target, <<"EOS"); -cd $ext_dir -if test ! -f Makefile -a -f Makefile.old; then - echo "Note: Using Makefile.old" - make -f Makefile.old $clean_target MAKE='@make' @pass_through -else - if test ! -f Makefile ; then - echo "Warning: No Makefile!" - fi - @make $clean_target MAKE='@make' @pass_through -fi -cd $return_dir -EOS + fallback_cleanup($return_dir, $clean_target, <<~"EOS"); + cd $ext_dir + if test ! -f Makefile -a -f Makefile.old; then + echo "Note: Using Makefile.old" + make -f Makefile.old $clean_target MAKE='@make' @pass_through + else + if test ! -f Makefile ; then + echo "Warning: No Makefile!" + fi + @make $clean_target MAKE='@make' @pass_through + fi + cd $return_dir + EOS } } } From d9cbbedac98d57542a12de41217ea21235863d83 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Thu, 18 Dec 2025 17:41:08 -0500 Subject: [PATCH 03/11] Disambiguate two variable names We had both @pass_through and $pass_through, the latter being an array ref -- but not one holding the same exact list as @pass_through! Let's disambiguate them (a little) by renaming the latter to $pass_through_ref (at least within the scope of sub build_extension()). --- make_ext.pl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index 6fac988db99b..b11739208f22 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -273,7 +273,7 @@ } sub build_extension { - my ($ext_dir, $perl, $mname, $target, $pass_through) = @_; + my ($ext_dir, $perl, $mname, $target, $pass_through_ref) = @_; unless (chdir "$ext_dir") { warn "Cannot cd to $ext_dir: $!"; @@ -518,7 +518,7 @@ sub build_extension { push @args, 'INSTALLDIRS=perl', 'INSTALLMAN1DIR=none', 'INSTALLMAN3DIR=none'; } - push @args, @$pass_through; + push @args, @$pass_through_ref; push @args, 'PERL=' . $perl if $perl; # use miniperl to run the Makefile later _quote_args(\@args) if IS_VMS; print join(' ', $perl, @args), "\n" if $verbose; @@ -549,12 +549,12 @@ sub build_extension { cd $ext_dir if test ! -f Makefile -a -f Makefile.old; then echo "Note: Using Makefile.old" - make -f Makefile.old $clean_target MAKE='@make' @pass_through + make -f Makefile.old $clean_target MAKE='@make' @$pass_through_ref else if test ! -f Makefile ; then echo "Warning: No Makefile!" fi - @make $clean_target MAKE='@make' @pass_through + @make $clean_target MAKE='@make' @$pass_through_ref fi cd $return_dir EOS @@ -567,14 +567,14 @@ sub build_extension { } if (IS_VMS) { - _quote_args($pass_through); - @$pass_through = ( + _quote_args($pass_through_ref); + @$pass_through_ref = ( "/DESCRIPTION=$makefile", - '/MACRO=(' . join(',',@$pass_through) . ')' + '/MACRO=(' . join(',',@$pass_through_ref) . ')' ); } - my @targ = ($target, @$pass_through); + my @targ = ($target, @$pass_through_ref); print "Making $target in $ext_dir\n@make @targ\n" if $verbose; local $ENV{PERL_INSTALL_QUIET} = 1; my $code = system(@make, @targ); From 3f640bf15ad8a16bdcea0603dbd921cbde78e515 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 09:24:52 -0500 Subject: [PATCH 04/11] Refactor code into internal sub _use_Makefile_PL() --- make_ext.pl | 66 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index b11739208f22..b44dd0191064 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -356,7 +356,13 @@ sub build_extension { } if ($makefile_no_minus_f || !-f $makefile) { + + # What we actually need at this point for encapsulation: + # $target, $ext_dir, $mname, $return_dir, + # $lib_dir, $pass_through_ref, $makefile, $perl, \@make, $verbose); + NO_MAKEFILE: +#################### if (!-f 'Makefile.PL') { unless (just_pm_to_blib($target, $ext_dir, $mname, $return_dir)) { # No problems returned, so it has faked everything for us. :-) @@ -508,29 +514,7 @@ sub build_extension { } # We are going to have to use Makefile.PL: - print "\nRunning Makefile.PL in $ext_dir\n" if $verbose; - - my @args = ("-I$lib_dir", 'Makefile.PL'); - if (IS_VMS) { - my $libd = VMS::Filespec::vmspath($lib_dir); - push @args, "INST_LIB=$libd", "INST_ARCHLIB=$libd"; - } else { - push @args, 'INSTALLDIRS=perl', 'INSTALLMAN1DIR=none', - 'INSTALLMAN3DIR=none'; - } - push @args, @$pass_through_ref; - push @args, 'PERL=' . $perl if $perl; # use miniperl to run the Makefile later - _quote_args(\@args) if IS_VMS; - print join(' ', $perl, @args), "\n" if $verbose; - my $code = do { - local $ENV{PERL_MM_USE_DEFAULT} = 1; - system $perl, @args; - }; - if($code != 0){ - #make sure next build attempt/run of make_ext.pl doesn't succeed - _unlink($makefile); - die "Unsuccessful Makefile.PL($ext_dir): code=$code"; - } + _use_Makefile_PL($ext_dir, $verbose, $lib_dir, $pass_through_ref, $perl, $makefile); # Right. The reason for this little hack is that we're sitting inside # a program run by ./miniperl, but there are tasks we need to perform @@ -558,10 +542,11 @@ sub build_extension { fi cd $return_dir EOS - } - } - } + } # END loop around targets + } # END if IS_UNIX +#################### + } # END NO_MAKEFILE scope if (not -f $makefile) { print "Warning: No Makefile!\n"; } @@ -776,3 +761,32 @@ sub fallback_cleanup { print $fh $contents or die "print $file: $!"; close $fh or die "close $file: $!"; } + +sub _use_Makefile_PL { + my ($ext_dir, $verbose, $lib_dir, $pass_through_ref, $perl, $makefile) = @_; + + print "\nRunning Makefile.PL in $ext_dir\n" if $verbose; + my @args = ("-I$lib_dir", 'Makefile.PL'); + if (IS_VMS) { + my $libd = VMS::Filespec::vmspath($lib_dir); + push @args, "INST_LIB=$libd", "INST_ARCHLIB=$libd"; + } else { + push @args, 'INSTALLDIRS=perl', 'INSTALLMAN1DIR=none', + 'INSTALLMAN3DIR=none'; + } + push @args, @$pass_through_ref; + push @args, 'PERL=' . $perl if $perl; # use miniperl to run the Makefile later + _quote_args(\@args) if IS_VMS; + print join(' ', $perl, @args), "\n" if $verbose; + my $code = do { + local $ENV{PERL_MM_USE_DEFAULT} = 1; + system $perl, @args; + }; + if($code != 0){ + #make sure next build attempt/run of make_ext.pl doesn't succeed + _unlink($makefile); + die "Unsuccessful Makefile.PL($ext_dir): code=$code"; + } + return 1; +} + From 9451ad797165fdeffbe9fd8c5ae5c01c2ff6e7f9 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 09:33:00 -0500 Subject: [PATCH 05/11] Refactor code into internal sub _making_target() --- make_ext.pl | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index b44dd0191064..3850dfcb022c 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -547,26 +547,8 @@ sub build_extension { } # END if IS_UNIX #################### } # END NO_MAKEFILE scope - if (not -f $makefile) { - print "Warning: No Makefile!\n"; - } - - if (IS_VMS) { - _quote_args($pass_through_ref); - @$pass_through_ref = ( - "/DESCRIPTION=$makefile", - '/MACRO=(' . join(',',@$pass_through_ref) . ')' - ); - } - my @targ = ($target, @$pass_through_ref); - print "Making $target in $ext_dir\n@make @targ\n" if $verbose; - local $ENV{PERL_INSTALL_QUIET} = 1; - my $code = system(@make, @targ); - if($code >> 8 != 0){ # probably cleaned itself, try again once more time - $code = system(@make, @targ); - } - die "Unsuccessful make($ext_dir): code=$code" if $code != 0; + _making_target($makefile, $pass_through_ref, $target, $verbose, \@make, $ext_dir, $return_dir); chdir $return_dir || die "Cannot cd to $return_dir: $!"; } @@ -790,3 +772,31 @@ sub _use_Makefile_PL { return 1; } +sub _making_target { + my ($makefile, $pass_through_ref, $target, $verbose, $makeref, $ext_dir, $return_dir) = @_; + my @make = @{$makeref}; + if (not -f $makefile) { + print "Warning: No Makefile!\n"; + } + + if (IS_VMS) { + _quote_args($pass_through_ref); + @$pass_through_ref = ( + "/DESCRIPTION=$makefile", + '/MACRO=(' . join(',',@$pass_through_ref) . ')' + ); + } + + my @targ = ($target, @$pass_through_ref); + print "Making $target in $ext_dir\n@make @targ\n" if $verbose; + local $ENV{PERL_INSTALL_QUIET} = 1; + my $code = system(@make, @targ); + if($code >> 8 != 0){ # probably cleaned itself, try again once more time + $code = system(@make, @targ); + } + die "Unsuccessful make($ext_dir): code=$code" if $code != 0; + + chdir $return_dir || die "Cannot cd to $return_dir: $!"; + return 1; +} + From ce97c3a70f56e54c7a6a1afffaa11a04c671acd7 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 09:45:41 -0500 Subject: [PATCH 06/11] Refactor code into internal sub _is_unix() --- make_ext.pl | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index 3850dfcb022c..bfcb6f6d9a77 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -527,24 +527,9 @@ sub build_extension { # some of them rely on a $(PERL) for their own distclean targets. # But this always used to be a problem with the old /bin/sh version of # this. - if (IS_UNIX) { - foreach my $clean_target ('realclean', 'veryclean') { - fallback_cleanup($return_dir, $clean_target, <<~"EOS"); - cd $ext_dir - if test ! -f Makefile -a -f Makefile.old; then - echo "Note: Using Makefile.old" - make -f Makefile.old $clean_target MAKE='@make' @$pass_through_ref - else - if test ! -f Makefile ; then - echo "Warning: No Makefile!" - fi - @make $clean_target MAKE='@make' @$pass_through_ref - fi - cd $return_dir - EOS - } # END loop around targets - } # END if IS_UNIX + _is_unix($return_dir, $ext_dir, $pass_through_ref, \@make, $return_dir); + #################### } # END NO_MAKEFILE scope @@ -772,6 +757,29 @@ sub _use_Makefile_PL { return 1; } +sub _is_unix { + my ($return_dir, $ext_dir, $pass_through_ref, $makeref) = @_; + my @make = @{$makeref}; + if (IS_UNIX) { + foreach my $clean_target ('realclean', 'veryclean') { + fallback_cleanup($return_dir, $clean_target, <<~"EOS"); + cd $ext_dir + if test ! -f Makefile -a -f Makefile.old; then + echo "Note: Using Makefile.old" + make -f Makefile.old $clean_target MAKE='@make' @$pass_through_ref + else + if test ! -f Makefile ; then + echo "Warning: No Makefile!" + fi + @make $clean_target MAKE='@make' @$pass_through_ref + fi + cd $return_dir + EOS + } # END loop around targets + } # END if IS_UNIX + return 1; +} + sub _making_target { my ($makefile, $pass_through_ref, $target, $verbose, $makeref, $ext_dir, $return_dir) = @_; my @make = @{$makeref}; From dc9f014d94a73876bec4067db400756cac2e1e0d Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 09:56:26 -0500 Subject: [PATCH 07/11] Refactor code into internal sub _handle_problem() --- make_ext.pl | 61 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index bfcb6f6d9a77..f0dced22583c 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -472,7 +472,8 @@ sub build_extension { } elsif ($mname =~ /\A(?:Carp |ExtUtils::CBuilder |Safe - |Search::Dict)\z/x) { + |Search::Dict)\z/x + ) { # An explicit list of dual-life extensions that have a Makefile.PL # for CPAN, but we have verified can also be built using the fakery. my ($problem) = just_pm_to_blib($target, $ext_dir, $mname, $return_dir); @@ -480,32 +481,7 @@ sub build_extension { # Otherwise "skips" will go undetected, and the build slow down for # everyone, defeating the purpose. if (defined $problem) { - if (-d "$return_dir/.git") { - # Get the list of files that git isn't ignoring: - my @files = `git ls-files --cached --others --exclude-standard 2>/dev/null`; - # on error (eg no git) we get nothing, but that's not a - # problem. The goal is to see if git thinks that the problem - # file is interesting, by getting a positive match with - # something git told us about, and if so bail out: - foreach (@files) { - chomp; - # We really need to sanity test that we can fake it. - # The intent is that this should only fail because - # you've just added a file to the dual-life dist that - # we can't handle. In which case you should either - # 1) remove the dist from the regex a few lines above. - # or - # 2) add the file to regex of "safe" filenames earlier - # in this function, that starts with ChangeLog - die "FATAL - $0 has $mname in the list of simple extensions, but it now contains file '$problem' which we can't handle" - if $problem eq $_; - } - # There's an unexpected file, but it seems to be something - # that git will ignore. So fall through to the regular - # Makefile.PL handling code below, on the assumption that - # we won't get here for a clean build. - } - warn "WARNING - $0 is building $mname using EU::MM, as it found file '$problem'"; + _handle_problem( $problem, $return_dir, $mname ); } else { # It faked everything for us. chdir $return_dir || die "Cannot cd to $return_dir: $!"; @@ -757,6 +733,37 @@ sub _use_Makefile_PL { return 1; } + +sub _handle_problem { + my ( $problem, $return_dir, $mname ) = @_; + if (-d "$return_dir/.git") { + # Get the list of files that git isn't ignoring: + my @files = `git ls-files --cached --others --exclude-standard 2>/dev/null`; + # on error (eg no git) we get nothing, but that's not a + # problem. The goal is to see if git thinks that the problem + # file is interesting, by getting a positive match with + # something git told us about, and if so bail out: + foreach (@files) { + chomp; + # We really need to sanity test that we can fake it. + # The intent is that this should only fail because + # you've just added a file to the dual-life dist that + # we can't handle. In which case you should either + # 1) remove the dist from the regex a few lines above. + # or + # 2) add the file to regex of "safe" filenames earlier + # in this function, that starts with ChangeLog + die "FATAL - $0 has $mname in the list of simple extensions, but it now contains file '$problem' which we can't handle" + if $problem eq $_; + } + # There's an unexpected file, but it seems to be something + # that git will ignore. So fall through to the regular + # Makefile.PL handling code below, on the assumption that + # we won't get here for a clean build. + } + warn "WARNING - $0 is building $mname using EU::MM, as it found file '$problem'"; +} # END _handle_problem + sub _is_unix { my ($return_dir, $ext_dir, $pass_through_ref, $makeref) = @_; my @make = @{$makeref}; From aac30aa8c500315a1fb081f788479cf05e7db957 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 10:07:35 -0500 Subject: [PATCH 08/11] Comment at locations where a return from build_extension is possible. --- make_ext.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index f0dced22583c..cc3ce176e294 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -270,14 +270,14 @@ build_extension($ext_pathname, $perl, $mname, $target, [@pass_through, @{$extra_passthrough{$spec} || []}]); -} +} # END foreach loop over elements in @extspec sub build_extension { my ($ext_dir, $perl, $mname, $target, $pass_through_ref) = @_; unless (chdir "$ext_dir") { warn "Cannot cd to $ext_dir: $!"; - return; + return; # 1st possible return from build_extension } my $up = $ext_dir; @@ -367,7 +367,7 @@ sub build_extension { unless (just_pm_to_blib($target, $ext_dir, $mname, $return_dir)) { # No problems returned, so it has faked everything for us. :-) chdir $return_dir || die "Cannot cd to $return_dir: $!"; - return; + return; # 2nd possible return from build_extension } print "\nCreating Makefile.PL in $ext_dir for $mname\n" if $verbose; @@ -485,7 +485,7 @@ sub build_extension { } else { # It faked everything for us. chdir $return_dir || die "Cannot cd to $return_dir: $!"; - return; + return; # 3rd possible return from build_extension } } From 119233895a0a1868415590c339642fcd68d7fdf3 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 10:22:48 -0500 Subject: [PATCH 09/11] Refactor code into _internal_build_extension() We take the code that was previously within the scope of the NO_MAKEFILE label and place it in its own subroutine. Two of the newly created internal functions, _use_Makefile_PL() and _is_unix(), will now be called from within _internal_build_extension() rather than directly from build_extension(). Two of the four possible places at which build_extension could previously return -- thereby triggering progression to the next module to be built in sequence -- now fall within the scope of _internal_build_extension(). These have to be a "hard return," i.e., they have to return an undefined value. At the point at which they are called from within build_extension(), we now capture that (undefined) return value and say 'return unless defined $rv;' in order to return from build_extension() and proceed to the next module's processing. --- make_ext.pl | 290 +++++++++++++++++++++++++++------------------------- 1 file changed, 152 insertions(+), 138 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index cc3ce176e294..77a37f1e9108 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -363,157 +363,171 @@ sub build_extension { NO_MAKEFILE: #################### - if (!-f 'Makefile.PL') { - unless (just_pm_to_blib($target, $ext_dir, $mname, $return_dir)) { - # No problems returned, so it has faked everything for us. :-) - chdir $return_dir || die "Cannot cd to $return_dir: $!"; - return; # 2nd possible return from build_extension - } + my $rv = _internal_build_extension( + $target, $ext_dir, $mname, $return_dir, $verbose, + $lib_dir, $pass_through_ref, $perl, $makefile, \@make + ); + return unless defined $rv; - print "\nCreating Makefile.PL in $ext_dir for $mname\n" if $verbose; - my ($fromname, $key, $value); - - $key = 'ABSTRACT_FROM'; - # We need to cope well with various possible layouts - my @dirs = split /::/, $mname; - my $leaf = pop @dirs; - my $leafname = "$leaf.pm"; - my $pathname = join '/', @dirs, $leafname; - my @locations = ($leafname, $pathname, "lib/$pathname"); - foreach (@locations) { - if (-f $_) { - $fromname = $_; - last; - } - } +#################### + } # END NO_MAKEFILE scope - unless ($fromname) { - die "For $mname tried @locations in $ext_dir but can't find source"; - } - ($value = $fromname) =~ s/\.pm\z/.pod/; - $value = $fromname unless -e $value; - - if ($mname eq 'Pod::Checker') { - # the abstract in the .pm file is unparseable by MM, - # so special-case it. We can't use the package's own - # Makefile.PL, as it doesn't handle the executable scripts - # right. - $key = 'ABSTRACT'; - # this is copied from the CPAN Makefile.PL v 1.171 - $value = 'Pod::Checker verifies POD documentation contents for compliance with the POD format specifications'; - } + _making_target($makefile, $pass_through_ref, $target, $verbose, \@make, $ext_dir, $return_dir); - open my $fh, '>', 'Makefile.PL' - or die "Can't open Makefile.PL for writing: $!"; - printf $fh <<~'EOM', $0, $mname, $fromname, $key, $value; - #-*- buffer-read-only: t -*- - - # This Makefile.PL was written by %s. - # It will be deleted automatically by make realclean - - use strict; - use ExtUtils::MakeMaker; - - # This is what the .PL extracts to. Not the ultimate file that is installed. - # (ie Win32 runs pl2bat after this) - - # Doing this here avoids all sort of quoting issues that would come from - # attempting to write out perl source with literals to generate the arrays and - # hash. - my @temps = 'Makefile.PL'; - foreach (glob('scripts/pod*.PL')) { - # The various pod*.PL extractors change directory. Doing that with relative - # paths in @INC breaks. It seems the lesser of two evils to copy (to avoid) - # the chdir doing anything, than to attempt to convert lib paths to - # absolute, and potentially run into problems with quoting special - # characters in the path to our build dir (such as spaces) - require File::Copy; - - my $temp = $_; - $temp =~ s!scripts/!!; - File::Copy::copy($_, $temp) or die "Can't copy $temp to $_: $!"; - push @temps, $temp; - } + chdir $return_dir || die "Cannot cd to $return_dir: $!"; +} - my $script_ext = $^O eq 'VMS' ? '.com' : ''; - my %%pod_scripts; - foreach (glob('pod*.PL')) { - my $script = $_; - s/.PL$/$script_ext/i; - $pod_scripts{$script} = $_; - } - my @exe_files = values %%pod_scripts; - - WriteMakefile( - NAME => '%s', - VERSION_FROM => '%s', - %-13s => '%s', - realclean => { FILES => "@temps" }, - (%%pod_scripts ? ( - PL_FILES => \%%pod_scripts, - EXE_FILES => \@exe_files, - clean => { FILES => "@exe_files" }, - ) : ()), - ); - - # ex: set ro: - EOM - close $fh or die "Can't close Makefile.PL: $!"; - # As described in commit 23525070d6c0e51f: - # Push the atime and mtime of generated Makefile.PLs back 4 - # seconds. In certain circumstances ( on virtual machines ) the - # generated Makefile.PL can produce a Makefile that is older than - # the Makefile.PL. Altering the atime and mtime backwards by 4 - # seconds seems to resolve the issue. - eval { - my $ftime = (stat('Makefile.PL'))[9] - 4; - utime $ftime, $ftime, 'Makefile.PL'; - }; - } elsif ($mname =~ /\A(?:Carp - |ExtUtils::CBuilder - |Safe - |Search::Dict)\z/x - ) { - # An explicit list of dual-life extensions that have a Makefile.PL - # for CPAN, but we have verified can also be built using the fakery. - my ($problem) = just_pm_to_blib($target, $ext_dir, $mname, $return_dir); - # We really need to sanity test that we can fake it. - # Otherwise "skips" will go undetected, and the build slow down for - # everyone, defeating the purpose. - if (defined $problem) { - _handle_problem( $problem, $return_dir, $mname ); - } else { - # It faked everything for us. - chdir $return_dir || die "Cannot cd to $return_dir: $!"; - return; # 3rd possible return from build_extension +sub _internal_build_extension { + my ($target, $ext_dir, $mname, $return_dir, $verbose, + $lib_dir, $pass_through_ref, $perl, $makefile, $makeref, + ) = @_; + my @make = $makeref; + if (!-f 'Makefile.PL') { + unless (just_pm_to_blib($target, $ext_dir, $mname, $return_dir)) { + # No problems returned, so it has faked everything for us. :-) + chdir $return_dir || die "Cannot cd to $return_dir: $!"; + return; # 2nd possible return from build_extension + } + + print "\nCreating Makefile.PL in $ext_dir for $mname\n" if $verbose; + my ($fromname, $key, $value); + + $key = 'ABSTRACT_FROM'; + # We need to cope well with various possible layouts + my @dirs = split /::/, $mname; + my $leaf = pop @dirs; + my $leafname = "$leaf.pm"; + my $pathname = join '/', @dirs, $leafname; + my @locations = ($leafname, $pathname, "lib/$pathname"); + foreach (@locations) { + if (-f $_) { + $fromname = $_; + last; } } - # We are going to have to use Makefile.PL: - _use_Makefile_PL($ext_dir, $verbose, $lib_dir, $pass_through_ref, $perl, $makefile); + unless ($fromname) { + die "For $mname tried @locations in $ext_dir but can't find source"; + } + ($value = $fromname) =~ s/\.pm\z/.pod/; + $value = $fromname unless -e $value; + + if ($mname eq 'Pod::Checker') { + # the abstract in the .pm file is unparseable by MM, + # so special-case it. We can't use the package's own + # Makefile.PL, as it doesn't handle the executable scripts + # right. + $key = 'ABSTRACT'; + # this is copied from the CPAN Makefile.PL v 1.171 + $value = 'Pod::Checker verifies POD documentation contents for compliance with the POD format specifications'; + } - # Right. The reason for this little hack is that we're sitting inside - # a program run by ./miniperl, but there are tasks we need to perform - # when the 'realclean', 'distclean' or 'veryclean' targets are run. - # Unfortunately, they can be run *after* 'clean', which deletes - # ./miniperl - # So we do our best to leave a set of instructions identical to what - # we would do if we are run directly as 'realclean' etc - # Whilst we're perfect, unfortunately the targets we call are not, as - # some of them rely on a $(PERL) for their own distclean targets. - # But this always used to be a problem with the old /bin/sh version of - # this. + open my $fh, '>', 'Makefile.PL' + or die "Can't open Makefile.PL for writing: $!"; + printf $fh <<~'EOM', $0, $mname, $fromname, $key, $value; + #-*- buffer-read-only: t -*- + + # This Makefile.PL was written by %s. + # It will be deleted automatically by make realclean + + use strict; + use ExtUtils::MakeMaker; + + # This is what the .PL extracts to. Not the ultimate file that is installed. + # (ie Win32 runs pl2bat after this) + + # Doing this here avoids all sort of quoting issues that would come from + # attempting to write out perl source with literals to generate the arrays and + # hash. + my @temps = 'Makefile.PL'; + foreach (glob('scripts/pod*.PL')) { + # The various pod*.PL extractors change directory. Doing that with relative + # paths in @INC breaks. It seems the lesser of two evils to copy (to avoid) + # the chdir doing anything, than to attempt to convert lib paths to + # absolute, and potentially run into problems with quoting special + # characters in the path to our build dir (such as spaces) + require File::Copy; + + my $temp = $_; + $temp =~ s!scripts/!!; + File::Copy::copy($_, $temp) or die "Can't copy $temp to $_: $!"; + push @temps, $temp; + } - _is_unix($return_dir, $ext_dir, $pass_through_ref, \@make, $return_dir); + my $script_ext = $^O eq 'VMS' ? '.com' : ''; + my %%pod_scripts; + foreach (glob('pod*.PL')) { + my $script = $_; + s/.PL$/$script_ext/i; + $pod_scripts{$script} = $_; + } + my @exe_files = values %%pod_scripts; + + WriteMakefile( + NAME => '%s', + VERSION_FROM => '%s', + %-13s => '%s', + realclean => { FILES => "@temps" }, + (%%pod_scripts ? ( + PL_FILES => \%%pod_scripts, + EXE_FILES => \@exe_files, + clean => { FILES => "@exe_files" }, + ) : ()), + ); -#################### - } # END NO_MAKEFILE scope + # ex: set ro: + EOM + close $fh or die "Can't close Makefile.PL: $!"; + # As described in commit 23525070d6c0e51f: + # Push the atime and mtime of generated Makefile.PLs back 4 + # seconds. In certain circumstances ( on virtual machines ) the + # generated Makefile.PL can produce a Makefile that is older than + # the Makefile.PL. Altering the atime and mtime backwards by 4 + # seconds seems to resolve the issue. + eval { + my $ftime = (stat('Makefile.PL'))[9] - 4; + utime $ftime, $ftime, 'Makefile.PL'; + }; + } + elsif ($mname =~ /\A(?:Carp + |ExtUtils::CBuilder + |Safe + |Search::Dict)\z/x + ) { + # An explicit list of dual-life extensions that have a Makefile.PL + # for CPAN, but we have verified can also be built using the fakery. + my ($problem) = just_pm_to_blib($target, $ext_dir, $mname, $return_dir); + # We really need to sanity test that we can fake it. + # Otherwise "skips" will go undetected, and the build slow down for + # everyone, defeating the purpose. + if (defined $problem) { + _handle_problem( $problem, $return_dir, $mname ); + } + else { + # It faked everything for us. + chdir $return_dir || die "Cannot cd to $return_dir: $!"; + return; # 3rd possible return from build_extension + } + } - _making_target($makefile, $pass_through_ref, $target, $verbose, \@make, $ext_dir, $return_dir); + # We are going to have to use Makefile.PL: - chdir $return_dir || die "Cannot cd to $return_dir: $!"; -} + _use_Makefile_PL($ext_dir, $verbose, $lib_dir, $pass_through_ref, $perl, $makefile); + # Right. The reason for this little hack is that we're sitting inside + # a program run by ./miniperl, but there are tasks we need to perform + # when the 'realclean', 'distclean' or 'veryclean' targets are run. + # Unfortunately, they can be run *after* 'clean', which deletes + # ./miniperl + # So we do our best to leave a set of instructions identical to what + # we would do if we are run directly as 'realclean' etc + # Whilst we're perfect, unfortunately the targets we call are not, as + # some of them rely on a $(PERL) for their own distclean targets. + # But this always used to be a problem with the old /bin/sh version of + # this. + + _is_unix($return_dir, $ext_dir, $pass_through_ref, \@make, $return_dir); +} sub _quote_args { my $args = shift; # must be array reference From d02ad357494bf9b14da1415d607c63799f48c621 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Sat, 20 Dec 2025 11:06:15 -0500 Subject: [PATCH 10/11] Replace instance of 'goto LABEL' with subroutine call This is the commit at which we finally solve the problem discussed in https://github.com/Perl/perl5/issues/24015. We replace the 'goto' call with a call of _internal_build_extension() with the same arguments we are already using in the standard cases. Can be verified by configuring and running make test_prep, mangling dist/Data-Dumper/Makefile to change the value of 'XS_VERSION' -- which previously (at least in a post-d306795336 world) would have caused a build failure -- then re-run 'make test_prep' which, during the rebuild, will generate a new, corrected dist/Data-Dumper/Makefile and run to completion. --- make_ext.pl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index 77a37f1e9108..7c1318d02d7a 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -319,10 +319,11 @@ sub build_extension { if (version->parse($newv) ne $oldv) { close $mfh or die "close $makefile: $!"; _unlink($makefile); - { - no warnings 'deprecated'; - goto NO_MAKEFILE; - } + my $rv = _internal_build_extension( + $target, $ext_dir, $mname, $return_dir, $verbose, + $lib_dir, $pass_through_ref, $perl, $makefile, \@make + ); + return unless defined $rv; } } From 6d03b98137d914c796141b4c25799ce37018943c Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Fri, 19 Dec 2025 21:49:01 -0500 Subject: [PATCH 11/11] Replace remaining hard tabs with 4 spaces Earlier in this pull request we tidied up leading whitespace and uncuddled else's, but only in the parts of the file that we were planning to revise. At this point, we can do some common-sense tidying in the remaining parts of the file. We leave a hard tab in one case where it's illustrating a 'make' command. Get indents in better shape (though leaving some else's uncuddled unchanged where that's more readable). --- make_ext.pl | 137 ++++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/make_ext.pl b/make_ext.pl index 7c1318d02d7a..30d5ffd1a51c 100644 --- a/make_ext.pl +++ b/make_ext.pl @@ -32,9 +32,9 @@ # # E.g. # -# make_ext.pl "MAKE=nmake -nologo" --dir=..\ext +# make_ext.pl "MAKE=nmake -nologo" --dir=..\ext # -# make_ext.pl "MAKE=nmake -nologo" --dir=..\ext --target=clean +# make_ext.pl "MAKE=nmake -nologo" --dir=..\ext --target=clean # # Will skip building extensions which are marked with an '!' char. # Mostly because they still not ported to specified platform. @@ -65,19 +65,19 @@ foreach (@ARGV) { if (/^!(.*)$/) { - $excl{$1} = 1; + $excl{$1} = 1; } elsif (/^\+(.*)$/) { - $incl{$1} = 1; + $incl{$1} = 1; } elsif (/^--verbose$/ or /^-v$/) { - $verbose = 1; + $verbose = 1; } elsif (/^--([\w\-]+)$/) { - $opts{$1} = 1; + $opts{$1} = 1; } elsif (/^--([\w\-]+)=(.*)$/) { - push @{$opts{$1}}, $2; + push @{$opts{$1}}, $2; } elsif (/=/) { - push @pass_through, $_; + push @pass_through, $_; } elsif (length) { - push @extspec, $_; + push @extspec, $_; } } @@ -87,35 +87,35 @@ my $dynaloader = $opts{dynaloader} || $opts{all}; # The Perl Makefile.SH will expand all extensions to -# lib/auto/X/X.a (or lib/auto/X/Y/Y.a if nested) +# lib/auto/X/X.a (or lib/auto/X/Y/Y.a if nested) # A user wishing to run make_ext might use -# X (or X/Y or X::Y if nested) +# X (or X/Y or X::Y if nested) # canonise into X/Y form (pname) foreach (@extspec) { if (s{^lib/auto/}{}) { - # Remove lib/auto prefix and /*.* suffix - s{/[^/]+\.[^/]+$}{}; + # Remove lib/auto prefix and /*.* suffix + s{/[^/]+\.[^/]+$}{}; } elsif (s{^$ext_dirs_re/}{}) { - # Remove ext/ prefix and /pm_to_blib suffix - s{/pm_to_blib$}{}; - # Targets are given as files on disk, but the extension spec is still - # written using /s for each :: - tr!-!/!; + # Remove ext/ prefix and /pm_to_blib suffix + s{/pm_to_blib$}{}; + # Targets are given as files on disk, but the extension spec is still + # written using /s for each :: + tr!-!/!; } elsif (s{::}{\/}g) { - # Convert :: to / + # Convert :: to / } else { - s/\..*o//; + s/\..*o//; } } my $makecmd = shift @pass_through; # Should be something like MAKE=make unshift @pass_through, 'PERL_CORE=1'; -my @dirs = @{$opts{dir} || \@ext_dirs}; -my $target = $opts{target}[0]; -$target = 'all' unless defined $target; +my @dirs = @{$opts{dir} || \@ext_dirs}; +my $target = $opts{target}[0]; +$target = 'all' unless defined $target; # Previously, $make was taken from config.sh. However, the user might # instead be running a possibly incompatible make. This might happen if @@ -124,6 +124,7 @@ # makefile as MAKE=/whatever/make in $makecmd. We'll be cautious in # case third party users of this script (are there any?) don't have the # MAKE=$(MAKE) argument, which was added after 5.004_03. + unless(defined $makecmd and $makecmd =~ /^MAKE=(.*)$/) { die "$0: WARNING: Please include MAKE=\$(MAKE) in \@ARGV\n"; } @@ -131,8 +132,8 @@ # This isn't going to cope with anything fancy, such as spaces inside command # names, but neither did what it replaced. Once there is a use case that needs # it, please supply patches. Until then, I'm sticking to KISS -my @make = split ' ', $1 || $Config{make} || $ENV{MAKE}; +my @make = split ' ', $1 || $Config{make} || $ENV{MAKE}; if ($target eq '') { die "make_ext: no make target specified (eg all or clean)\n"; @@ -155,28 +156,28 @@ my $build = Cwd::getcwd(); $perl = $^X; if ($perl =~ m#^\.\.#) { - my $here = $build; - $here =~ s{/}{\\}g; - $perl = "$here\\$perl"; + my $here = $build; + $here =~ s{/}{\\}g; + $perl = "$here\\$perl"; } (my $topdir = $perl) =~ s/\\[^\\]+$//; # miniperl needs to find perlglob and pl2bat $ENV{PATH} = "$topdir;$topdir\\win32\\bin;$ENV{PATH}"; my $pl2bat = "$topdir\\win32\\bin\\pl2bat"; unless (-f "$pl2bat.bat") { - my @args = ($perl, "-I$topdir\\lib", "-I$topdir\\cpan\\ExtUtils-PL2Bat\\lib", ("$pl2bat.pl") x 2); - print "@args\n" if $verbose; - system(@args) unless IS_CROSS; + my @args = ($perl, "-I$topdir\\lib", "-I$topdir\\cpan\\ExtUtils-PL2Bat\\lib", ("$pl2bat.pl") x 2); + print "@args\n" if $verbose; + system(@args) unless IS_CROSS; } print "In $build" if $verbose; foreach my $dir (@dirs) { - chdir($dir) or die "Cannot cd to $dir: $!\n"; - (my $ext = Cwd::getcwd()) =~ s{/}{\\}g; - FindExt::scan_ext($ext); - FindExt::set_static_extensions(split ' ', $Config{static_ext}); - chdir $build - or die "Couldn't chdir to '$build': $!"; # restore our start directory + chdir($dir) or die "Cannot cd to $dir: $!\n"; + (my $ext = Cwd::getcwd()) =~ s{/}{\\}g; + FindExt::scan_ext($ext); + FindExt::set_static_extensions(split ' ', $Config{static_ext}); + chdir $build + or die "Couldn't chdir to '$build': $!"; # restore our start directory } my @ext; @@ -186,22 +187,22 @@ push @ext, 'DynaLoader' if $dynaloader; foreach (sort @ext) { - if (%incl and !exists $incl{$_}) { - #warn "Skipping extension $_, not in inclusion list\n"; - next; - } - if (exists $excl{$_}) { - warn "Skipping extension $_, not ported to current platform"; - next; - } - push @extspec, $_; - if($_ ne 'DynaLoader' && FindExt::is_static($_)) { - push @{$extra_passthrough{$_}}, 'LINKTYPE=static'; - } + if (%incl and !exists $incl{$_}) { + #warn "Skipping extension $_, not in inclusion list\n"; + next; + } + if (exists $excl{$_}) { + warn "Skipping extension $_, not ported to current platform"; + next; + } + push @extspec, $_; + if($_ ne 'DynaLoader' && FindExt::is_static($_)) { + push @{$extra_passthrough{$_}}, 'LINKTYPE=static'; + } } chdir '..' - or die "Couldn't chdir to build directory: $!"; # now in the Perl build + or die "Couldn't chdir to build directory: $!"; # now in the Perl build } elsif (IS_VMS) { $perl = $^X; @@ -218,14 +219,14 @@ # This seems to be the simplest way to ensure this ordering: my (@first, @second, @other); foreach (@extspec) { - if ($_ eq 'Cwd' || $_ eq 'if' || $_ eq 'lib') { - push @first, $_; + if ($_ eq 'Cwd' || $_ eq 'if' || $_ eq 'lib') { + push @first, $_; + } + elsif ($_ eq 'Pod/Simple') { + push @second, $_; + } else { + push @other, $_; } - elsif ($_ eq 'Pod/Simple') { - push @second, $_; - } else { - push @other, $_; - } } @extspec = (@first, @second, @other); } @@ -250,26 +251,26 @@ $copy = 'PathTools' if $copy eq 'Cwd'; foreach my $dir (@ext_dirs) { - if (-d "$dir/$copy") { - $ext_pathname = "$dir/$copy"; - last; - } + if (-d "$dir/$copy") { + $ext_pathname = "$dir/$copy"; + last; + } } if (!defined $ext_pathname) { - if (-d "ext/$spec") { - # Old style ext/Data/Dumper/ - $ext_pathname = "ext/$spec"; - } else { - warn "Can't find extension $spec in any of @ext_dirs"; - next; - } + if (-d "ext/$spec") { + # Old style ext/Data/Dumper/ + $ext_pathname = "ext/$spec"; + } else { + warn "Can't find extension $spec in any of @ext_dirs"; + next; + } } print "\tMaking $mname ($target)\n" if $verbose; build_extension($ext_pathname, $perl, $mname, $target, - [@pass_through, @{$extra_passthrough{$spec} || []}]); + [@pass_through, @{$extra_passthrough{$spec} || []}]); } # END foreach loop over elements in @extspec sub build_extension {