+
+sub build_extension {
+ my ($ext_dir, $perl, $mname, $pass_through) = @_;
+
+ unless (chdir "$ext_dir") {
+ warn "Cannot cd to $ext_dir: $!";
+ return;
+ }
+
+ my $up = $ext_dir;
+ $up =~ s![^/]+!..!g;
+
+ $perl ||= "$up/miniperl";
+ my $return_dir = $up;
+ my $lib_dir = "$up/lib";
+ $ENV{PERL_CORE} = 1;
+
+ my $makefile;
+ if ($is_VMS) {
+ $makefile = 'descrip.mms';
+ if ($target =~ /clean$/
+ && !-f $makefile
+ && -f "${makefile}_old") {
+ $makefile = "${makefile}_old";
+ }
+ } else {
+ $makefile = 'Makefile';
+ }
+
+ if (-f $makefile) {
+ 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 ($newv ne $oldv) {
+ close $mfh or die "close $makefile: $!";
+ _unlink($makefile);
+ {
+ no warnings 'deprecated';
+ goto NO_MAKEFILE;
+ }
+ }
+ }
+ if(IS_CROSS){
+ seek($mfh, 0, 0) or die "Cannot seek $makefile: $!";
+ while (<$mfh>) {
+ #this is used to stop the while loop early for efficiency when
+ #the line is reached, and possibly match a cross build
+ my $header = quotemeta '# These definitions are from config.sh (via ';
+ if(/^$header.+?
+ (xlib[\/\\]
+ $::Cross::platform\Q\/Config.pm\E)?\)\./x) {
+ unless (defined $1){
+ print "Deleting non-Cross makefile\n";
+ close $mfh or die "close $makefile: $!";
+ _unlink($makefile);
+ {
+ no warnings 'deprecated';
+ goto NO_MAKEFILE;
+ }
+ } else { #have a cross makefile
+ goto CROSS_OK_MF;
+ }
+ }
+ } #catch breakage from future changes
+ die "non-standard makefile found in $mname";
+ CROSS_OK_MF:
+ }
+ }
+
+ if (!-f $makefile) {
+ NO_MAKEFILE:
+ if (!-f 'Makefile.PL') {
+ print "\nCreating Makefile.PL in $ext_dir for $mname\n";
+ my ($fromname, $key, $value);
+ if ($mname eq 'podlators') {
+ # We need to special case this somewhere, and this is fewer
+ # lines of code than a core-only Makefile.PL, and no more
+ # complex
+ $fromname = 'VERSION';
+ $key = 'DISTNAME';
+ $value = 'podlators';
+ $mname = 'Pod';
+ } else {
+ $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");
+ unshift @locations, 'lib/IO/Compress/Base.pm' if $mname eq 'IO::Compress';
+ foreach (@locations) {
+ if (-f $_) {
+ $fromname = $_;
+ last;
+ }
+ }
+
+ unless ($fromname) {
+ die "For $mname tried @locations in in $ext_dir but can't find source";
+ }
+ ($value = $fromname) =~ s/\.pm\z/.pod/;
+ $value = $fromname unless -e $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.
+# 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;