1#!./miniperl 2use strict; 3use warnings; 4use Config; 5use constant{IS_CROSS => defined $Config::Config{usecrosscompile} ? 1 : 0, 6 IS_WIN32 => $^O eq 'MSWin32', 7 IS_VMS => $^O eq 'VMS', 8 IS_UNIX => $^O ne 'MSWin32' && $^O ne 'VMS', 9}; 10 11my @ext_dirs = qw(cpan dist ext); 12my $ext_dirs_re = '(?:' . join('|', @ext_dirs) . ')'; 13 14# This script acts as a simple interface for building extensions. 15 16# It's actually a cut and shut of the Unix version ext/utils/makeext and the 17# Windows version win32/build_ext.pl hence the two invocation styles. 18 19# On Unix, it primarily used by the perl Makefile one extension at a time: 20# 21# d_dummy $(dynamic_ext): miniperl preplibrary FORCE 22# @$(RUN) ./miniperl make_ext.pl --target=dynamic $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) 23# 24# On Windows or VMS, 25# If '--static' is specified, static extensions will be built. 26# If '--dynamic' is specified, dynamic extensions will be built. 27# If '--nonxs' is specified, nonxs extensions will be built. 28# If '--dynaloader' is specified, DynaLoader will be built. 29# If '--all' is specified, all extensions will be built. 30# 31# make_ext.pl "MAKE=make [-make_opts]" --dir=directory [--target=target] [--static|--dynamic|--all] +ext2 !ext1 32# 33# E.g. 34# 35# make_ext.pl "MAKE=nmake -nologo" --dir=..\ext 36# 37# make_ext.pl "MAKE=nmake -nologo" --dir=..\ext --target=clean 38# 39# make_ext.pl MAKE=dmake --dir=..\ext 40# 41# make_ext.pl MAKE=dmake --dir=..\ext --target=clean 42# 43# Will skip building extensions which are marked with an '!' char. 44# Mostly because they still not ported to specified platform. 45# 46# If any extensions are listed with a '+' char then only those 47# extensions will be built, but only if they aren't countermanded 48# by an '!ext' and are appropriate to the type of building being done. 49# An extensions follows the format of Foo/Bar, which would be extension Foo::Bar 50 51# To fix dependency ordering, on *nix systems, edit Makefile.SH to create a 52# rule. That isn't sufficient for other systems; you also have to do 53# something in this file. See the code at 54# '# XXX hack for dependency # ordering' 55# below. 56# 57# The basic logic is: 58# 1) if there's a Makefile.PL in git for the module, use it. and call make 59# 2) If not, auto-generate one (normally) 60# 3) unless the auto-generation code figures out that the extension is 61# *really* simple, in which case don't. This will be for pure perl 62# modules, and all that is needed to be done is to copy from the source 63# to the dest directories. 64# 65# It may be deleted in a later release of perl so try to 66# avoid using it for other purposes. 67 68my (%excl, %incl, %opts, @extspec, @pass_through, $verbose); 69 70foreach (@ARGV) { 71 if (/^!(.*)$/) { 72 $excl{$1} = 1; 73 } elsif (/^\+(.*)$/) { 74 $incl{$1} = 1; 75 } elsif (/^--verbose$/ or /^-v$/) { 76 $verbose = 1; 77 } elsif (/^--([\w\-]+)$/) { 78 $opts{$1} = 1; 79 } elsif (/^--([\w\-]+)=(.*)$/) { 80 push @{$opts{$1}}, $2; 81 } elsif (/=/) { 82 push @pass_through, $_; 83 } elsif (length) { 84 push @extspec, $_; 85 } 86} 87 88my $static = $opts{static} || $opts{all}; 89my $dynamic = $opts{dynamic} || $opts{all}; 90my $nonxs = $opts{nonxs} || $opts{all}; 91my $dynaloader = $opts{dynaloader} || $opts{all}; 92 93# The Perl Makefile.SH will expand all extensions to 94# lib/auto/X/X.a (or lib/auto/X/Y/Y.a if nested) 95# A user wishing to run make_ext might use 96# X (or X/Y or X::Y if nested) 97 98# canonise into X/Y form (pname) 99 100foreach (@extspec) { 101 if (s{^lib/auto/}{}) { 102 # Remove lib/auto prefix and /*.* suffix 103 s{/[^/]+\.[^/]+$}{}; 104 } elsif (s{^$ext_dirs_re/}{}) { 105 # Remove ext/ prefix and /pm_to_blib suffix 106 s{/pm_to_blib$}{}; 107 # Targets are given as files on disk, but the extension spec is still 108 # written using /s for each :: 109 tr!-!/!; 110 } elsif (s{::}{\/}g) { 111 # Convert :: to / 112 } else { 113 s/\..*o//; 114 } 115} 116 117my $makecmd = shift @pass_through; # Should be something like MAKE=make 118unshift @pass_through, 'PERL_CORE=1'; 119 120my @dirs = @{$opts{dir} || \@ext_dirs}; 121my $target = $opts{target}[0]; 122$target = 'all' unless defined $target; 123 124# Previously, $make was taken from config.sh. However, the user might 125# instead be running a possibly incompatible make. This might happen if 126# the user types "gmake" instead of a plain "make", for example. The 127# correct current value of MAKE will come through from the main perl 128# makefile as MAKE=/whatever/make in $makecmd. We'll be cautious in 129# case third party users of this script (are there any?) don't have the 130# MAKE=$(MAKE) argument, which was added after 5.004_03. 131unless(defined $makecmd and $makecmd =~ /^MAKE=(.*)$/) { 132 die "$0: WARNING: Please include MAKE=\$(MAKE) in \@ARGV\n"; 133} 134 135# This isn't going to cope with anything fancy, such as spaces inside command 136# names, but neither did what it replaced. Once there is a use case that needs 137# it, please supply patches. Until then, I'm sticking to KISS 138my @make = split ' ', $1 || $Config{make} || $ENV{MAKE}; 139 140 141if ($target eq '') { 142 die "make_ext: no make target specified (eg all or clean)\n"; 143} elsif ($target !~ /^(?:all|clean|distclean|realclean|veryclean)$/) { 144 # we are strict about what make_ext is used for because we emulate these 145 # targets for simple modules: 146 die "$0: unknown make target '$target'\n"; 147} 148 149if (!@extspec and !$static and !$dynamic and !$nonxs and !$dynaloader) { 150 die "$0: no extension specified\n"; 151} 152 153my $perl; 154my %extra_passthrough; 155 156if (IS_WIN32) { 157 require Cwd; 158 require FindExt; 159 my $build = Cwd::getcwd(); 160 $perl = $^X; 161 if ($perl =~ m#^\.\.#) { 162 my $here = $build; 163 $here =~ s{/}{\\}g; 164 $perl = "$here\\$perl"; 165 } 166 (my $topdir = $perl) =~ s/\\[^\\]+$//; 167 # miniperl needs to find perlglob and pl2bat 168 $ENV{PATH} = "$topdir;$topdir\\win32\\bin;$ENV{PATH}"; 169 my $pl2bat = "$topdir\\win32\\bin\\pl2bat"; 170 unless (-f "$pl2bat.bat") { 171 my @args = ($perl, "-I$topdir\\lib", ("$pl2bat.pl") x 2); 172 print "@args\n" if $verbose; 173 system(@args) unless IS_CROSS; 174 } 175 176 print "In $build" if $verbose; 177 foreach my $dir (@dirs) { 178 chdir($dir) or die "Cannot cd to $dir: $!\n"; 179 (my $ext = Cwd::getcwd()) =~ s{/}{\\}g; 180 FindExt::scan_ext($ext); 181 FindExt::set_static_extensions(split ' ', $Config{static_ext}); 182 chdir $build 183 or die "Couldn't chdir to '$build': $!"; # restore our start directory 184 } 185 186 my @ext; 187 push @ext, FindExt::static_ext() if $static; 188 push @ext, FindExt::dynamic_ext() if $dynamic; 189 push @ext, FindExt::nonxs_ext() if $nonxs; 190 push @ext, 'DynaLoader' if $dynaloader; 191 192 foreach (sort @ext) { 193 if (%incl and !exists $incl{$_}) { 194 #warn "Skipping extension $_, not in inclusion list\n"; 195 next; 196 } 197 if (exists $excl{$_}) { 198 warn "Skipping extension $_, not ported to current platform"; 199 next; 200 } 201 push @extspec, $_; 202 if($_ ne 'DynaLoader' && FindExt::is_static($_)) { 203 push @{$extra_passthrough{$_}}, 'LINKTYPE=static'; 204 } 205 } 206 207 chdir '..' 208 or die "Couldn't chdir to build directory: $!"; # now in the Perl build 209} 210elsif (IS_VMS) { 211 $perl = $^X; 212 push @extspec, (split ' ', $Config{static_ext}) if $static; 213 push @extspec, (split ' ', $Config{dynamic_ext}) if $dynamic; 214 push @extspec, (split ' ', $Config{nonxs_ext}) if $nonxs; 215 push @extspec, 'DynaLoader' if $dynaloader; 216} 217 218{ # XXX hack for dependency ordering 219 # Cwd needs to be built before Encode recurses into subdirectories. 220 # Pod::Simple needs to be built before Pod::Functions, but after 'if' 221 # lib needs to be built before IO-Compress 222 # This seems to be the simplest way to ensure this ordering: 223 my (@first, @second, @other); 224 foreach (@extspec) { 225 if ($_ eq 'Cwd' || $_ eq 'if' || $_ eq 'lib') { 226 push @first, $_; 227 } 228 elsif ($_ eq 'Pod/Simple') { 229 push @second, $_; 230 } else { 231 push @other, $_; 232 } 233 } 234 @extspec = (@first, @second, @other); 235} 236 237if ($Config{osname} eq 'catamount' and @extspec) { 238 # Snowball's chance of building extensions. 239 die "This is $Config{osname}, not building $extspec[0], sorry.\n"; 240} 241$ENV{PERL_CORE} = 1; 242 243foreach my $spec (@extspec) { 244 my $mname = $spec; 245 $mname =~ s!/!::!g; 246 my $ext_pathname; 247 248 # Try new style ext/Data-Dumper/ first 249 my $copy = $spec; 250 $copy =~ tr!/!-!; 251 252 # List/Util.xs lives in Scalar-List-Utils, Cwd.xs lives in PathTools 253 $copy = 'Scalar-List-Utils' if $copy eq 'List-Util'; 254 $copy = 'PathTools' if $copy eq 'Cwd'; 255 256 foreach my $dir (@ext_dirs) { 257 if (-d "$dir/$copy") { 258 $ext_pathname = "$dir/$copy"; 259 last; 260 } 261 } 262 263 if (!defined $ext_pathname) { 264 if (-d "ext/$spec") { 265 # Old style ext/Data/Dumper/ 266 $ext_pathname = "ext/$spec"; 267 } else { 268 warn "Can't find extension $spec in any of @ext_dirs"; 269 next; 270 } 271 } 272 273 print "\tMaking $mname ($target)\n" if $verbose; 274 275 build_extension($ext_pathname, $perl, $mname, $target, 276 [@pass_through, @{$extra_passthrough{$spec} || []}]); 277} 278 279sub build_extension { 280 my ($ext_dir, $perl, $mname, $target, $pass_through) = @_; 281 282 unless (chdir "$ext_dir") { 283 warn "Cannot cd to $ext_dir: $!"; 284 return; 285 } 286 287 my $up = $ext_dir; 288 $up =~ s![^/]+!..!g; 289 290 $perl ||= "$up/miniperl"; 291 my $return_dir = $up; 292 my $lib_dir = "$up/lib"; 293 294 my ($makefile, $makefile_no_minus_f); 295 if (IS_VMS) { 296 $makefile = 'descrip.mms'; 297 if ($target =~ /clean$/ 298 && !-f $makefile 299 && -f "${makefile}_old") { 300 $makefile = "${makefile}_old"; 301 } 302 } else { 303 $makefile = 'Makefile'; 304 } 305 306 if (-f $makefile) { 307 $makefile_no_minus_f = 0; 308 open my $mfh, '<', $makefile or die "Cannot open $makefile: $!"; 309 while (<$mfh>) { 310 # Plagiarised from CPAN::Distribution 311 last if /MakeMaker post_initialize section/; 312 next unless /^#\s+VERSION_FROM\s+=>\s+(.+)/; 313 my $vmod = eval $1; 314 my $oldv; 315 while (<$mfh>) { 316 next unless /^XS_VERSION = (\S+)/; 317 $oldv = $1; 318 last; 319 } 320 last unless defined $oldv; 321 require ExtUtils::MM_Unix; 322 defined (my $newv = parse_version MM $vmod) or last; 323 if (version->parse($newv) ne $oldv) { 324 close $mfh or die "close $makefile: $!"; 325 _unlink($makefile); 326 { 327 no warnings 'deprecated'; 328 goto NO_MAKEFILE; 329 } 330 } 331 } 332 333 if (IS_CROSS) { 334 # If we're cross-compiling, it's possible that the host's 335 # Makefiles are around. 336 seek($mfh, 0, 0) or die "Cannot seek $makefile: $!"; 337 338 my $cross_makefile; 339 while (<$mfh>) { 340 # XXX This might not be throughout enough. 341 # For example, it's possible to cause a false-positive 342 # if cross compiling on and for the Raspberry Pi, 343 # which is insane but plausible. 344 # False positives are really not troublesome, though; 345 # all they mean is that the module gets rebuilt. 346 if (/^CC = \Q$Config{cc}\E/) { 347 $cross_makefile = 1; 348 last; 349 } 350 } 351 352 if (!$cross_makefile) { 353 print "Deleting non-Cross makefile\n"; 354 close $mfh or die "close $makefile: $!"; 355 _unlink($makefile); 356 } 357 } 358 } else { 359 $makefile_no_minus_f = 1; 360 } 361 362 if ($makefile_no_minus_f || !-f $makefile) { 363 NO_MAKEFILE: 364 if (!-f 'Makefile.PL') { 365 unless (just_pm_to_blib($target, $ext_dir, $mname, $return_dir)) { 366 # No problems returned, so it has faked everything for us. :-) 367 chdir $return_dir || die "Cannot cd to $return_dir: $!"; 368 return; 369 } 370 371 print "\nCreating Makefile.PL in $ext_dir for $mname\n" if $verbose; 372 my ($fromname, $key, $value); 373 374 $key = 'ABSTRACT_FROM'; 375 # We need to cope well with various possible layouts 376 my @dirs = split /::/, $mname; 377 my $leaf = pop @dirs; 378 my $leafname = "$leaf.pm"; 379 my $pathname = join '/', @dirs, $leafname; 380 my @locations = ($leafname, $pathname, "lib/$pathname"); 381 foreach (@locations) { 382 if (-f $_) { 383 $fromname = $_; 384 last; 385 } 386 } 387 388 unless ($fromname) { 389 die "For $mname tried @locations in $ext_dir but can't find source"; 390 } 391 ($value = $fromname) =~ s/\.pm\z/.pod/; 392 $value = $fromname unless -e $value; 393 394 if ($mname eq 'Pod::Checker') { 395 # the abstract in the .pm file is unparseable by MM, 396 # so special-case it. We can't use the package's own 397 # Makefile.PL, as it doesn't handle the executable scripts 398 # right. 399 $key = 'ABSTRACT'; 400 # this is copied from the CPAN Makefile.PL v 1.171 401 $value = 'Pod::Checker verifies POD documentation contents for compliance with the POD format specifications'; 402 } 403 404 open my $fh, '>', 'Makefile.PL' 405 or die "Can't open Makefile.PL for writing: $!"; 406 printf $fh <<'EOM', $0, $mname, $fromname, $key, $value; 407#-*- buffer-read-only: t -*- 408 409# This Makefile.PL was written by %s. 410# It will be deleted automatically by make realclean 411 412use strict; 413use ExtUtils::MakeMaker; 414 415# This is what the .PL extracts to. Not the ultimate file that is installed. 416# (ie Win32 runs pl2bat after this) 417 418# Doing this here avoids all sort of quoting issues that would come from 419# attempting to write out perl source with literals to generate the arrays and 420# hash. 421my @temps = 'Makefile.PL'; 422foreach (glob('scripts/pod*.PL')) { 423 # The various pod*.PL extractors change directory. Doing that with relative 424 # paths in @INC breaks. It seems the lesser of two evils to copy (to avoid) 425 # the chdir doing anything, than to attempt to convert lib paths to 426 # absolute, and potentially run into problems with quoting special 427 # characters in the path to our build dir (such as spaces) 428 require File::Copy; 429 430 my $temp = $_; 431 $temp =~ s!scripts/!!; 432 File::Copy::copy($_, $temp) or die "Can't copy $temp to $_: $!"; 433 push @temps, $temp; 434} 435 436my $script_ext = $^O eq 'VMS' ? '.com' : ''; 437my %%pod_scripts; 438foreach (glob('pod*.PL')) { 439 my $script = $_; 440 s/.PL$/$script_ext/i; 441 $pod_scripts{$script} = $_; 442} 443my @exe_files = values %%pod_scripts; 444 445WriteMakefile( 446 NAME => '%s', 447 VERSION_FROM => '%s', 448 %-13s => '%s', 449 realclean => { FILES => "@temps" }, 450 (%%pod_scripts ? ( 451 PL_FILES => \%%pod_scripts, 452 EXE_FILES => \@exe_files, 453 clean => { FILES => "@exe_files" }, 454 ) : ()), 455); 456 457# ex: set ro: 458EOM 459 close $fh or die "Can't close Makefile.PL: $!"; 460 # As described in commit 23525070d6c0e51f: 461 # Push the atime and mtime of generated Makefile.PLs back 4 462 # seconds. In certain circumstances ( on virtual machines ) the 463 # generated Makefile.PL can produce a Makefile that is older than 464 # the Makefile.PL. Altering the atime and mtime backwards by 4 465 # seconds seems to resolve the issue. 466 eval { 467 my $ftime = (stat('Makefile.PL'))[9] - 4; 468 utime $ftime, $ftime, 'Makefile.PL'; 469 }; 470 } elsif ($mname =~ /\A(?:Carp 471 |ExtUtils::CBuilder 472 |Safe 473 |Search::Dict)\z/x) { 474 # An explicit list of dual-life extensions that have a Makefile.PL 475 # for CPAN, but we have verified can also be built using the fakery. 476 my ($problem) = just_pm_to_blib($target, $ext_dir, $mname, $return_dir); 477 # We really need to sanity test that we can fake it. 478 # Otherwise "skips" will go undetected, and the build slow down for 479 # everyone, defeating the purpose. 480 if (defined $problem) { 481 if (-d "$return_dir/.git") { 482 # Get the list of files that git isn't ignoring: 483 my @files = `git ls-files --cached --others --exclude-standard 2>/dev/null`; 484 # on error (eg no git) we get nothing, but that's not a 485 # problem. The goal is to see if git thinks that the problem 486 # file is interesting, by getting a positive match with 487 # something git told us about, and if so bail out: 488 foreach (@files) { 489 chomp; 490 # We really need to sanity test that we can fake it. 491 # The intent is that this should only fail because 492 # you've just added a file to the dual-life dist that 493 # we can't handle. In which case you should either 494 # 1) remove the dist from the regex a few lines above. 495 # or 496 # 2) add the file to regex of "safe" filenames earlier 497 # in this function, that starts with ChangeLog 498 die "FATAL - $0 has $mname in the list of simple extensions, but it now contains file '$problem' which we can't handle" 499 if $problem eq $_; 500 } 501 # There's an unexpected file, but it seems to be something 502 # that git will ignore. So fall through to the regular 503 # Makefile.PL handling code below, on the assumption that 504 # we won't get here for a clean build. 505 } 506 warn "WARNING - $0 is building $mname using EU::MM, as it found file '$problem'"; 507 } else { 508 # It faked everything for us. 509 chdir $return_dir || die "Cannot cd to $return_dir: $!"; 510 return; 511 } 512 } 513 514 # We are going to have to use Makefile.PL: 515 print "\nRunning Makefile.PL in $ext_dir\n" if $verbose; 516 517 my @args = ("-I$lib_dir", 'Makefile.PL'); 518 if (IS_VMS) { 519 my $libd = VMS::Filespec::vmspath($lib_dir); 520 push @args, "INST_LIB=$libd", "INST_ARCHLIB=$libd"; 521 } else { 522 push @args, 'INSTALLDIRS=perl', 'INSTALLMAN1DIR=none', 523 'INSTALLMAN3DIR=none'; 524 } 525 push @args, @$pass_through; 526 push @args, 'PERL=' . $perl if $perl; # use miniperl to run the Makefile later 527 _quote_args(\@args) if IS_VMS; 528 print join(' ', $perl, @args), "\n" if $verbose; 529 my $code = do { 530 local $ENV{PERL_MM_USE_DEFAULT} = 1; 531 system $perl, @args; 532 }; 533 if($code != 0){ 534 #make sure next build attempt/run of make_ext.pl doesn't succeed 535 _unlink($makefile); 536 die "Unsuccessful Makefile.PL($ext_dir): code=$code"; 537 } 538 539 # Right. The reason for this little hack is that we're sitting inside 540 # a program run by ./miniperl, but there are tasks we need to perform 541 # when the 'realclean', 'distclean' or 'veryclean' targets are run. 542 # Unfortunately, they can be run *after* 'clean', which deletes 543 # ./miniperl 544 # So we do our best to leave a set of instructions identical to what 545 # we would do if we are run directly as 'realclean' etc 546 # Whilst we're perfect, unfortunately the targets we call are not, as 547 # some of them rely on a $(PERL) for their own distclean targets. 548 # But this always used to be a problem with the old /bin/sh version of 549 # this. 550 if (IS_UNIX) { 551 foreach my $clean_target ('realclean', 'veryclean') { 552 fallback_cleanup($return_dir, $clean_target, <<"EOS"); 553cd $ext_dir 554if test ! -f Makefile -a -f Makefile.old; then 555 echo "Note: Using Makefile.old" 556 make -f Makefile.old $clean_target MAKE='@make' @pass_through 557else 558 if test ! -f Makefile ; then 559 echo "Warning: No Makefile!" 560 fi 561 @make $clean_target MAKE='@make' @pass_through 562fi 563cd $return_dir 564EOS 565 } 566 } 567 } 568 569 if (not -f $makefile) { 570 print "Warning: No Makefile!\n"; 571 } 572 573 if (IS_VMS) { 574 _quote_args($pass_through); 575 @$pass_through = ( 576 "/DESCRIPTION=$makefile", 577 '/MACRO=(' . join(',',@$pass_through) . ')' 578 ); 579 } 580 581 my @targ = ($target, @$pass_through); 582 print "Making $target in $ext_dir\n@make @targ\n" if $verbose; 583 local $ENV{PERL_INSTALL_QUIET} = 1; 584 my $code = system(@make, @targ); 585 if($code >> 8 != 0){ # probably cleaned itself, try again once more time 586 $code = system(@make, @targ); 587 } 588 die "Unsuccessful make($ext_dir): code=$code" if $code != 0; 589 590 chdir $return_dir || die "Cannot cd to $return_dir: $!"; 591} 592 593sub _quote_args { 594 my $args = shift; # must be array reference 595 596 # Do not quote qualifiers that begin with '/'. 597 map { if (!/^\//) { 598 $_ =~ s/\"/""/g; # escape C<"> by doubling 599 $_ = q(").$_.q("); 600 } 601 } @{$args} 602 ; 603} 604 605#guarentee that a file is deleted or die, void _unlink($filename) 606#xxx replace with _unlink_or_rename from EU::Install? 607sub _unlink { 608 1 while unlink $_[0]; 609 my $err = $!; 610 die "Can't unlink $_[0]: $err" if -f $_[0]; 611} 612 613# Figure out if this extension is simple enough that it would only use 614# ExtUtils::MakeMaker's pm_to_blib target. If we're confident that it would, 615# then do all the work ourselves (returning an empty list), else return the 616# name of a file that we identified as beyond our ability to handle. 617# 618# While this is clearly quite a bit more work than just letting 619# ExtUtils::MakeMaker do it, and effectively is some code duplication, the time 620# savings are impressive. 621 622sub just_pm_to_blib { 623 my ($target, $ext_dir, $mname, $return_dir) = @_; 624 my ($has_lib, $has_top, $has_topdir); 625 my ($last) = $mname =~ /([^:]+)$/; 626 my ($first) = $mname =~ /^([^:]+)/; 627 628 my $pm_to_blib = IS_VMS ? 'pm_to_blib.ts' : 'pm_to_blib'; 629 my $silent = defined $ENV{MAKEFLAGS} && $ENV{MAKEFLAGS} =~ /\b(s|silent|quiet)\b/; 630 631 foreach my $leaf (<*>) { 632 if (-d $leaf) { 633 $leaf =~ s/\.DIR\z//i 634 if IS_VMS; 635 next if $leaf =~ /\A(?:\.|\.\.|t|demo)\z/; 636 if ($leaf eq 'lib') { 637 ++$has_lib; 638 next; 639 } 640 if ($leaf eq $first) { 641 ++$has_topdir; 642 next; 643 } 644 } 645 return $leaf 646 unless -f _; 647 $leaf =~ s/\.\z// 648 if IS_VMS; 649 # Makefile.PL is "safe" to ignore because we will only be called for 650 # directories that hold a Makefile.PL if they are in the exception list. 651 next 652 if $leaf =~ /\A(ChangeLog 653 |Changes 654 |LICENSE 655 |Makefile\.PL 656 |MANIFEST 657 |META\.yml 658 |\Q$pm_to_blib\E 659 |README 660 |README\.patching 661 |README\.release 662 )\z/xi; # /i to deal with case munging systems. 663 if ($leaf eq "$last.pm") { 664 ++$has_top; 665 next; 666 } 667 return $leaf; 668 } 669 return 'no lib/' 670 unless $has_lib || $has_top; 671 die "Inconsistent module $mname has both lib/ and $first/" 672 if $has_lib && $has_topdir; 673 674 print "Running pm_to_blib for $ext_dir directly\n" 675 unless $silent; 676 677 my %pm; 678 if ($has_top) { 679 my $to = $mname =~ s!::!/!gr; 680 $pm{"$last.pm"} = "../../lib/$to.pm"; 681 } 682 if ($has_lib || $has_topdir) { 683 # strictly ExtUtils::MakeMaker uses the pm_to_blib target to install 684 # .pm, pod and .pl files. We're just going to do it for .pm and .pod 685 # files, to avoid problems on case munging file systems. Specifically, 686 # _pm.PL which ExtUtils::MakeMaker should run munges to _PM.PL, and 687 # looks a lot like a regular foo.pl (ie FOO.PL) 688 my @found; 689 require File::Find; 690 unless (eval { 691 File::Find::find({ 692 no_chdir => 1, 693 wanted => sub { 694 return if -d $_; 695 # Bail out immediately with the problem file: 696 die \$_ 697 unless -f _; 698 die \$_ 699 unless /\A[^.]+\.(?:pm|pod)\z/i; 700 push @found, $_; 701 } 702 }, $has_lib ? 'lib' : $first); 703 1; 704 }) { 705 # Problem files aren't really errors: 706 return ${$@} 707 if ref $@ eq 'SCALAR'; 708 # But anything else is: 709 die $@; 710 } 711 if ($has_lib) { 712 $pm{$_} = "../../$_" 713 foreach @found; 714 } else { 715 $pm{$_} = "../../lib/$_" 716 foreach @found; 717 } 718 } 719 # This is running under miniperl, so no autodie 720 if ($target eq 'all') { 721 my $need_update = 1; 722 if (-f $pm_to_blib) { 723 # avoid touching pm_to_blib unless there's something that 724 # needs updating, see #126710 725 $need_update = 0; 726 my $test_at = -M _; 727 while (my $from = each(%pm)) { 728 if (-M $from < $test_at) { 729 ++$need_update; 730 last; 731 } 732 } 733 keys %pm; # reset iterator 734 } 735 736 if ($need_update) { 737 local $ENV{PERL_INSTALL_QUIET} = 1; 738 require ExtUtils::Install; 739 ExtUtils::Install::pm_to_blib(\%pm, '../../lib/auto'); 740 open my $fh, '>', $pm_to_blib 741 or die "Can't open '$pm_to_blib': $!"; 742 print $fh "$0 has handled pm_to_blib directly\n"; 743 close $fh 744 or die "Can't close '$pm_to_blib': $!"; 745 if (IS_UNIX) { 746 # Fake the fallback cleanup 747 my $fallback 748 = join '', map {s!^\.\./\.\./!!; "rm -f $_\n"} sort values %pm; 749 foreach my $clean_target ('realclean', 'veryclean') { 750 fallback_cleanup($return_dir, $clean_target, $fallback); 751 } 752 } 753 } 754 } else { 755 # A clean target. 756 # For now, make the targets behave the same way as ExtUtils::MakeMaker 757 # does 758 _unlink($pm_to_blib); 759 unless ($target eq 'clean') { 760 # but cheat a bit, by relying on the top level Makefile clean target 761 # to take out our directory lib/auto/... 762 # (which it has to deal with, as cpan/foo/bar creates 763 # lib/auto/foo/bar, but the EU::MM rule will only 764 # rmdir lib/auto/foo/bar, leaving lib/auto/foo 765 _unlink($_) 766 foreach sort values %pm; 767 } 768 } 769 return; 770} 771 772sub fallback_cleanup { 773 my ($dir, $clean_target, $contents) = @_; 774 my $file = "$dir/$clean_target.sh"; 775 open my $fh, '>>', $file or die "open $file: $!"; 776 # Quite possible that we're being run in parallel here. 777 # Can't use Fcntl this early to get the LOCK_EX 778 flock $fh, 2 or warn "flock $file: $!"; 779 print $fh $contents or die "print $file: $!"; 780 close $fh or die "close $file: $!"; 781} 782