This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
typo fixes for root level scripts
[perl5.git] / configpm
index 6ac52e2..cfcc467 100755 (executable)
--- a/configpm
+++ b/configpm
@@ -1,4 +1,42 @@
 #!./miniperl -w
+#
+# configpm
+#
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007 Larry Wall and others.
+#
+#
+# Regenerate the files
+#
+#    lib/Config.pm
+#    lib/Config_heavy.pl
+#    lib/Config.pod
+#    lib/Cross.pm (optionally)
+#
+#
+# from the contents of the static files
+#
+#    Porting/Glossary
+#    myconfig.SH
+#
+# and from the contents of the Configure-generated file
+#
+#    config.sh
+#
+# Note that output directory is xlib/[cross-name]/ for cross-compiling
+#
+# It will only update Config.pm and Config_heavy.pl if the contents of
+# either file would be different. Note that *both* files are updated in
+# this case, since for example an extension makefile that has a dependency
+# on Config.pm should trigger even if only Config_heavy.pl has changed.
+
+sub usage { die <<EOF }
+usage: $0  [ options ]
+    --cross=PLATFORM    cross-compile for a different platform
+    --no-glossary       don't include Porting/Glossary in lib/Config.pod
+    --chdir=dir         change directory before writing files
+EOF
+
 use strict;
 use vars qw(%Config $Config_SH_expanded);
 
@@ -14,16 +52,50 @@ while ($how_many_common--) {
     $Common{$1} = $1;
 }
 
+# Post 37589e1eefb1bd62 DynaLoader defaults to reading these at runtime.
+# Ideally we're redo the data below, but Fotango's build system made it
+# wonderfully easy to instrument, and no longer exists.
+$Common{$_} = $_ foreach qw(dlext so);
+
 # names of things which may need to have slashes changed to double-colons
 my %Extensions = map {($_,$_)}
                  qw(dynamic_ext static_ext extensions known_extensions);
 
+# The plan is that this information is used by ExtUtils::MakeMaker to generate
+# Makefile dependencies, rather than hardcoding a list, which has become out
+# of date. However, currently, MM_Unix.pm and MM_VMS.pm have *different* lists,
+# *and* descrip_mms.template doesn't actually install all the headers.
+# The "Unix" list seems to (attempt to) avoid the generated headers, which I'm
+# not sure is the right thing to do. Also, not certain whether it would be
+# easier to parse MANIFEST to get these (adding config.h, and potentially
+# removing others), but for now, stick to a hard coded list.
+
+# Could use a map to add ".h", but I suspect that it's easier to use literals,
+# so that anyone using grep will find them
+# This is the list from MM_VMS, plus pad.h, parser.h, perlsfio.h utf8.h
+# which it installs. It *doesn't* install perliol.h - FIXME.
+my @header_files = qw(EXTERN.h INTERN.h XSUB.h av.h config.h cop.h cv.h
+                     embed.h embedvar.h form.h gv.h handy.h hv.h hv_func.h intrpvar.h
+                     iperlsys.h keywords.h mg.h nostdio.h op.h opcode.h
+                     pad.h parser.h patchlevel.h perl.h perlio.h perlsdio.h
+                     perlsfio.h perlvars.h perly.h pp.h pp_proto.h proto.h
+                     regcomp.h regexp.h regnodes.h scope.h sv.h thread.h utf8.h
+                     util.h);
+
+push @header_files,
+    $^O eq 'VMS' ? 'vmsish.h' : qw(dosish.h perliol.h time64.h unixish.h);
+
+my $header_files = '    return qw(' . join(' ', sort @header_files) . ');';
+$header_files =~ s/(?=.{64})   # If line is still overlength
+                  (.{1,64})\  # Split at the last convenient space
+                 /$1\n              /gx;
+
 # allowed opts as well as specifies default and initial values
 my %Allowed_Opts = (
     'cross'    => '', # --cross=PLATFORM - crosscompiling for PLATFORM
     'glossary' => 1,  # --no-glossary  - no glossary file inclusion,
                       #                  for compactness
-    'heavy' => '',   # pathname of the Config_heavy.pl file
+    'chdir'    => '', # --chdir=dir    - change directory before writing files
 );
 
 sub opts {
@@ -38,7 +110,8 @@ sub opts {
     my %opts = (%Allowed_Opts, %given_opts);
 
     for my $opt (grep {!exists $Allowed_Opts{$_}} keys %given_opts) {
-        die "option '$opt' is not recognized";
+        warn "option '$opt' is not recognized";
+       usage;
     }
     @ARGV = grep {!/^--/} @ARGV;
 
@@ -48,68 +121,148 @@ sub opts {
 
 my %Opts = opts();
 
-my ($Config_PM, $Config_heavy);
-my $Glossary = $ARGV[1] || 'Porting/Glossary';
+if ($Opts{chdir}) {
+    chdir $Opts{chdir} or die "$0: could not chdir $Opts{chdir}: $!"
+}
+
+my ($Config_SH, $Config_PM, $Config_heavy, $Config_POD);
+my $Glossary = 'Porting/Glossary';
 
 if ($Opts{cross}) {
   # creating cross-platform config file
   mkdir "xlib";
   mkdir "xlib/$Opts{cross}";
-  $Config_PM = $ARGV[0] || "xlib/$Opts{cross}/Config.pm";
+  $Config_PM = "xlib/$Opts{cross}/Config.pm";
+  $Config_POD = "xlib/$Opts{cross}/Config.pod";
+  $Config_SH = "Cross/config-$Opts{cross}.sh";
 }
 else {
-  $Config_PM = $ARGV[0] || 'lib/Config.pm';
-}
-if ($Opts{heavy}) {
-  $Config_heavy = $Opts{heavy};
-}
-else {
-  ($Config_heavy = $Config_PM) =~ s!\.pm$!_heavy.pl!;
-  die "Can't automatically determine name for Config_heavy.pl from '$Config_PM'"
-    if $Config_heavy eq $Config_PM;
+  $Config_PM = "lib/Config.pm";
+  $Config_POD = "lib/Config.pod";
+  $Config_SH = "config.sh";
 }
+($Config_heavy = $Config_PM) =~ s/\.pm$/_heavy.pl/;
+die "Can't automatically determine name for Config_heavy.pl from '$Config_PM'"
+  if $Config_heavy eq $Config_PM;
 
-open CONFIG, ">$Config_PM" or die "Can't open $Config_PM: $!\n";
-open CONFIG_HEAVY, ">$Config_heavy" or die "Can't open $Config_heavy: $!\n";
+my $config_txt;
+my $heavy_txt;
 
-print CONFIG_HEAVY <<'ENDOFBEG';
+my $from = $^O eq 'VMS' ? 'PERLSHR image' : 'binary (from libperl)';
+my $env_cygwin = $^O eq 'cygwin'
+    ? 'push @env, "CYGWIN=\"$ENV{CYGWIN}\"" if $ENV{CYGWIN};' . "\n" : "";
+$heavy_txt .= sprintf <<'ENDOFBEG', $^O, $^O, $from, $^O, $env_cygwin;
 # This file was created by configpm when Perl was built. Any changes
 # made to this file will be lost the next time perl is built.
 
 package Config;
 use strict;
-# use warnings; Pulls in Carp
-# use vars pulls in Carp
+use warnings;
+use vars '%%Config';
+
+sub bincompat_options {
+    return split ' ', (Internals::V())[0];
+}
+
+sub non_bincompat_options {
+    return split ' ', (Internals::V())[1];
+}
+
+sub compile_date {
+    return (Internals::V())[2]
+}
+
+sub local_patches {
+    my (undef, undef, undef, @patches) = Internals::V();
+    return @patches;
+}
+
+sub _V {
+    die "Perl lib was built for '%s' but is being run on '$^O'"
+        unless "%s" eq $^O;
+
+    my ($bincompat, $non_bincompat, $date, @patches) = Internals::V();
+
+    my $opts = join ' ', sort split ' ', "$bincompat $non_bincompat";
+
+    # wrap at 76 columns.
+
+    $opts =~ s/(?=.{53})(.{1,53}) /$1\n                        /mg;
+
+    print Config::myconfig();
+    print "\nCharacteristics of this %s: \n";
+
+    print "  Compile-time options: $opts\n";
+
+    if (@patches) {
+        print "  Locally applied patches:\n";
+        print "\t$_\n" foreach @patches;
+    }
+
+    print "  Built under %s\n";
+
+    print "  $date\n" if defined $date;
+
+    my @env = map { "$_=\"$ENV{$_}\"" } sort grep {/^PERL/} keys %%ENV;
+%s
+    if (@env) {
+        print "  \%%ENV:\n";
+        print "    $_\n" foreach @env;
+    }
+    print "  \@INC:\n";
+    print "    $_\n" foreach @INC;
+}
+
+sub header_files {
 ENDOFBEG
 
-my $myver = sprintf "v%vd", $^V;
+$heavy_txt .= $header_files . "\n}\n\n";
+
+my $export_funcs = <<'EOT';
+my %Export_Cache = (myconfig => 1, config_sh => 1, config_vars => 1,
+                   config_re => 1, compile_date => 1, local_patches => 1,
+                   bincompat_options => 1, non_bincompat_options => 1,
+                   header_files => 1);
+EOT
+
+my %export_ok = eval $export_funcs or die;
 
-printf CONFIG <<'ENDOFBEG', ($myver) x 3;
+$config_txt .= sprintf << 'EOT', $], $export_funcs;
 # This file was created by configpm when Perl was built. Any changes
 # made to this file will be lost the next time perl is built.
 
+# for a description of the variables, please have a look at the
+# Glossary file, as written in the Porting folder, or use the url:
+# http://perl5.git.perl.org/perl.git/blob/HEAD:/Porting/Glossary
+
 package Config;
 use strict;
-# use warnings; Pulls in Carp
-# use vars pulls in Carp
+use warnings;
+use vars '%%Config', '$VERSION';
+
+$VERSION = "%s";
+
+# Skip @Config::EXPORT because it only contains %%Config, which we special
+# case below as it's not a function. @Config::EXPORT won't change in the
+# lifetime of Perl 5.
+%s
 @Config::EXPORT = qw(%%Config);
-@Config::EXPORT_OK = qw(myconfig config_sh config_vars config_re);
+@Config::EXPORT_OK = keys %%Export_Cache;
 
 # Need to stub all the functions to make code such as print Config::config_sh
 # keep working
 
-sub myconfig;
-sub config_sh;
-sub config_vars;
-sub config_re;
+EOT
+
+$config_txt .= "sub $_;\n" foreach sort keys %export_ok;
 
-my %%Export_Cache = map {($_ => 1)} (@Config::EXPORT, @Config::EXPORT_OK);
+my $myver = sprintf "%vd", $^V;
 
-our %%Config;
+$config_txt .= sprintf <<'ENDOFBEG', ($myver) x 3;
 
 # Define our own import method to avoid pulling in the full Exporter:
 sub import {
-    my $pkg = shift;
+    shift;
     @_ = @Config::EXPORT unless @_;
 
     my @funcs = grep $_ ne '%%Config', @_;
@@ -118,8 +271,8 @@ sub import {
     no strict 'refs';
     my $callpkg = caller(0);
     foreach my $func (@funcs) {
-       die sprintf qq{"%%s" is not exported by the %%s module\n},
-           $func, __PACKAGE__ unless $Export_Cache{$func};
+       die qq{"$func" is not exported by the Config module\n}
+           unless $Export_Cache{$func};
        *{$callpkg.'::'.$func} = \&{$func};
     }
 
@@ -127,11 +280,11 @@ sub import {
     return;
 }
 
-die "Perl lib version (%s) doesn't match executable version ($])"
+die "Perl lib version (%s) doesn't match executable '$0' version ($])"
     unless $^V;
 
 $^V eq %s
-    or die "Perl lib version (%s) doesn't match executable version (" .
+    or die "Perl lib version (%s) doesn't match executable '$0' version (" .
        sprintf("v%%vd",$^V) . ")";
 
 ENDOFBEG
@@ -141,12 +294,13 @@ my @non_v    = ();
 my @v_others = ();
 my $in_v     = 0;
 my %Data     = ();
+my $quote;
 
 
 my %seen_quotes;
 {
   my ($name, $val);
-  open(CONFIG_SH, 'config.sh') || die "Can't open config.sh: $!";
+  open(CONFIG_SH, $Config_SH) || die "Can't open $Config_SH: $!";
   while (<CONFIG_SH>) {
     next if m:^#!/bin/sh:;
 
@@ -172,11 +326,11 @@ my %seen_quotes;
        push(@non_v, "#$_"); # not a name='value' line
        next;
     }
-    my $quote = $2;
     if ($in_v) { 
         $val .= $_;
     }
     else { 
+       $quote = $2;
         ($name,$val) = ($1,$3); 
     }
     $in_v = $val !~ /$quote\n/;
@@ -206,63 +360,41 @@ EOT
 
 if ($seen_quotes{'"'}) {
     # We need the full ' and " code
-    $fetch_string .= <<'EOT';
-    my $quote_type = "'";
-    my $marker = "$key=";
-
-    # Check for the common case, ' delimited
-    my $start = index($Config_SH_expanded, "\n$marker$quote_type");
-    # If that failed, check for " delimited
-    if ($start == -1) {
-        $quote_type = '"';
-        $start = index($Config_SH_expanded, "\n$marker$quote_type");
-    }
-EOT
-} else {
-    $fetch_string .= <<'EOT';
-    # We only have ' delimted.
-    my $start = index($Config_SH_expanded, "\n$key=\'");
-EOT
-}
-$fetch_string .= <<'EOT';
-    # Start can never be -1 now, as we've rigged the long string we're
-    # searching with an initial dummy newline.
-    return undef if $start == -1;
 
-    $start += length($key) + 3;
-
-EOT
-if (!$seen_quotes{'"'}) {
-    # Don't need the full ' and " code, or the eval expansion.
-    $fetch_string .= <<'EOT';
-    my $value = substr($Config_SH_expanded, $start,
-                       index($Config_SH_expanded, "'\n", $start)
-                      - $start);
-EOT
-} else {
-    $fetch_string .= <<'EOT';
-    my $value = substr($Config_SH_expanded, $start,
-                       index($Config_SH_expanded, "$quote_type\n", $start)
-                      - $start);
+$fetch_string .= <<'EOT';
+    return undef unless my ($quote_type, $value) = $Config_SH_expanded =~ /\n$key=(['"])(.*?)\1\n/s;
 
     # If we had a double-quote, we'd better eval it so escape
     # sequences and such can be interpolated. Since the incoming
     # value is supposed to follow shell rules and not perl rules,
     # we escape any perl variable markers
+
+    # Historically, since " 'support' was added in change 1409, the
+    # interpolation was done before the undef. Stick to this arguably buggy
+    # behaviour as we're refactoring.
     if ($quote_type eq '"') {
        $value =~ s/\$/\\\$/g;
        $value =~ s/\@/\\\@/g;
        eval "\$value = \"$value\"";
     }
-EOT
+
+    # So we can say "if $Config{'foo'}".
+    $self->{$key} = $value eq 'undef' ? undef : $value; # cache it
 }
+EOT
+
+} else {
+    # We only have ' delimited.
+
 $fetch_string .= <<'EOT';
+    return undef unless $Config_SH_expanded =~ /\n$key=\'(.*?)\'\n/s;
     # So we can say "if $Config{'foo'}".
-    $value = undef if $value eq 'undef';
-    $self->{$key} = $value; # cache it
+    $self->{$key} = $1 eq 'undef' ? undef : $1;
 }
 EOT
 
+}
+
 eval $fetch_string;
 die if $@;
 
@@ -282,13 +414,12 @@ my $f = $t eq 'long' ? 'L!' : $s == 8 ? 'Q': 'I';
 
 my $byteorder_code;
 if ($s == 4 || $s == 8) {
-    my $list = join ',', reverse(2..$s);
+    my $list = join ',', reverse(1..$s-1);
     my $format = 'a'x$s;
     $byteorder_code = <<"EOT";
 
-my \$i = 0;
-foreach my \$c ($list) { \$i |= ord(\$c); \$i <<= 8 }
-\$i |= ord(1);
+my \$i = ord($s);
+foreach my \$c ($list) { \$i <<= 8; \$i |= ord(\$c); }
 our \$byteorder = join('', unpack('$format', pack('$f', \$i)));
 EOT
 } else {
@@ -298,14 +429,62 @@ EOT
 my @need_relocation;
 
 if (fetch_string({},'userelocatableinc')) {
-    foreach my $what (qw(archlibexp
+    foreach my $what (qw(prefixexp
+
+                        archlibexp
+                        html1direxp
+                        html3direxp
+                        man1direxp
+                        man3direxp
                         privlibexp
+                        scriptdirexp
                         sitearchexp
+                        sitebinexp
+                        sitehtml1direxp
+                        sitehtml3direxp
                         sitelibexp
-                        sitelib_stem
+                        siteman1direxp
+                        siteman3direxp
+                        sitescriptexp
                         vendorarchexp
+                        vendorbinexp
+                        vendorhtml1direxp
+                        vendorhtml3direxp
                         vendorlibexp
-                        vendorlib_stem)) {
+                        vendorman1direxp
+                        vendorman3direxp
+                        vendorscriptexp
+
+                        siteprefixexp
+                        sitelib_stem
+                        vendorlib_stem
+
+                        installarchlib
+                        installhtml1dir
+                        installhtml3dir
+                        installman1dir
+                        installman3dir
+                        installprefix
+                        installprefixexp
+                        installprivlib
+                        installscript
+                        installsitearch
+                        installsitebin
+                        installsitehtml1dir
+                        installsitehtml3dir
+                        installsitelib
+                        installsiteman1dir
+                        installsiteman3dir
+                        installsitescript
+                        installvendorarch
+                        installvendorbin
+                        installvendorhtml1dir
+                        installvendorhtml3dir
+                        installvendorlib
+                        installvendorman1dir
+                        installvendorman3dir
+                        installvendorscript
+                        )) {
        push @need_relocation, $what if fetch_string({}, $what) =~ m!^\.\.\./!;
     }
 }
@@ -353,32 +532,40 @@ if (%need_relocation) {
     $relocations_in_common++ if $Common{$_};
   }
   if ($relocations_in_common) {
-    print CONFIG $relocation_code;
+    $config_txt .= $relocation_code;
   } else {
-    print CONFIG_HEAVY $relocation_code;
+    $heavy_txt .= $relocation_code;
   }
 }
 
-print CONFIG_HEAVY @non_v, "\n";
+$heavy_txt .= join('', @non_v) . "\n";
 
 # copy config summary format from the myconfig.SH script
-print CONFIG_HEAVY "our \$summary : unique = <<'!END!';\n";
+$heavy_txt .= "our \$summary = <<'!END!';\n";
 open(MYCONFIG,"<myconfig.SH") || die "open myconfig.SH failed: $!";
 1 while defined($_ = <MYCONFIG>) && !/^Summary of/;
-do { print CONFIG_HEAVY $_ } until !defined($_ = <MYCONFIG>) || /^\s*$/;
+do { $heavy_txt .= $_ } until !defined($_ = <MYCONFIG>) || /^\s*$/;
 close(MYCONFIG);
 
-# NB. as $summary is unique, we need to copy it in a lexical variable
-# before expanding it, because may have been made readonly if a perl
-# interpreter has been cloned.
-
-print CONFIG_HEAVY "\n!END!\n", <<'EOT';
+$heavy_txt .= "\n!END!\n" . <<'EOT';
 my $summary_expanded;
 
 sub myconfig {
     return $summary_expanded if $summary_expanded;
     ($summary_expanded = $summary) =~ s{\$(\w+)}
-                { my $c = $Config::Config{$1}; defined($c) ? $c : 'undef' }ge;
+                { 
+                       my $c;
+                       if ($1 eq 'git_ancestor_line') {
+                               if ($Config::Config{git_ancestor}) {
+                                       $c= "\n  Ancestor: $Config::Config{git_ancestor}";
+                               } else {
+                                       $c= "";
+                               }
+                       } else {
+                               $c = $Config::Config{$1}; 
+                       }
+                       defined($c) ? $c : 'undef' 
+               }ge;
     $summary_expanded;
 }
 
@@ -386,19 +573,19 @@ local *_ = \my $a;
 $_ = <<'!END!';
 EOT
 
-print CONFIG_HEAVY join('', sort @v_others), "!END!\n";
+$heavy_txt .= join('', sort @v_others) . "!END!\n";
 
 # Only need the dynamic byteorder code in Config.pm if 'byteorder' is one of
 # the precached keys
 if ($Common{byteorder}) {
-    print CONFIG $byteorder_code;
+    $config_txt .= $byteorder_code;
 } else {
-    print CONFIG_HEAVY $byteorder_code;
+    $heavy_txt .= $byteorder_code;
 }
 
 if (@need_relocation) {
-print CONFIG_HEAVY 'foreach my $what (qw(', join (' ', @need_relocation),
-      ")) {\n", <<'EOT';
+$heavy_txt .= 'foreach my $what (qw(' . join (' ', @need_relocation) .
+      ")) {\n" . <<'EOT';
     s/^($what=)(['"])(.*?)\2/$1 . $2 . relocate_inc($3) . $2/me;
 }
 EOT
@@ -406,19 +593,19 @@ EOT
 # no need to emulate the "which separator for this platform" logic in perl.c -
 # ':' will always be applicable
 if ($need_relocation{otherlibdirs}) {
-print CONFIG_HEAVY << 'EOT';
+$heavy_txt .= << 'EOT';
 s{^(otherlibdirs=)(['"])(.*?)\2}
  {$1 . $2 . join ':', map {relocate_inc($_)} split ':', $3 . $2}me;
 EOT
 }
 }
 
-print CONFIG_HEAVY <<'EOT';
+$heavy_txt .= <<'EOT';
 s/(byteorder=)(['"]).*?\2/$1$2$Config::byteorder$2/m;
 
 my $config_sh_len = length $_;
 
-our $Config_SH_expanded : unique = "\n$_" . << 'EOVIRTUAL';
+our $Config_SH_expanded = "\n$_" . << 'EOVIRTUAL';
 EOT
 
 foreach my $prefix (qw(ccflags ldflags)) {
@@ -426,7 +613,7 @@ foreach my $prefix (qw(ccflags ldflags)) {
     my $withlargefiles = fetch_string ({}, $prefix . "_uselargefiles");
     if (defined $withlargefiles) {
         $value =~ s/\Q$withlargefiles\E\b//;
-        print CONFIG_HEAVY "${prefix}_nolargefiles='$value'\n";
+        $heavy_txt .= "${prefix}_nolargefiles='$value'\n";
     }
 }
 
@@ -450,26 +637,34 @@ foreach my $prefix (qw(libs libswanted)) {
            $value = join(' ', @libswanted);
        }
     }
-    print CONFIG_HEAVY "${prefix}_nolargefiles='$value'\n";
+    $heavy_txt .= "${prefix}_nolargefiles='$value'\n";
 }
 
-print CONFIG_HEAVY "EOVIRTUAL\n";
+$heavy_txt .= "EOVIRTUAL\n";
+
+$heavy_txt .= <<'ENDOFGIT';
+eval {
+       # do not have hairy conniptions if this isnt available
+       require 'Config_git.pl';
+       $Config_SH_expanded .= $Config::Git_Data;
+       1;
+} or warn "Warning: failed to load Config_git.pl, something strange about this perl...\n";
+ENDOFGIT
 
-print CONFIG_HEAVY $fetch_string;
+$heavy_txt .= $fetch_string;
 
-print CONFIG <<'ENDOFEND';
+$config_txt .= <<'ENDOFEND';
 
 sub FETCH {
     my($self, $key) = @_;
 
     # check for cached value (which may be undef so we use exists not defined)
-    return $self->{$key} if exists $self->{$key};
-
-    return $self->fetch_string($key);
+    return exists $self->{$key} ? $self->{$key} : $self->fetch_string($key);
 }
+
 ENDOFEND
 
-print CONFIG_HEAVY <<'ENDOFEND';
+$heavy_txt .= <<'ENDOFEND';
 
 my $prevpos = 0;
 
@@ -481,7 +676,7 @@ sub FIRSTKEY {
 sub NEXTKEY {
 ENDOFEND
 if ($seen_quotes{'"'}) {
-print CONFIG_HEAVY <<'ENDOFEND';
+$heavy_txt .= <<'ENDOFEND';
     # Find out how the current key's quoted so we can skip to its end.
     my $quote = substr($Config_SH_expanded,
                       index($Config_SH_expanded, "=", $prevpos)+1, 1);
@@ -489,11 +684,11 @@ print CONFIG_HEAVY <<'ENDOFEND';
 ENDOFEND
 } else {
     # Just ' quotes, so it's much easier.
-print CONFIG_HEAVY <<'ENDOFEND';
+$heavy_txt .= <<'ENDOFEND';
     my $pos = index($Config_SH_expanded, qq('\n), $prevpos) + 2;
 ENDOFEND
 }
-print CONFIG_HEAVY <<'ENDOFEND';
+$heavy_txt .= <<'ENDOFEND';
     my $len = index($Config_SH_expanded, "=", $pos) - $pos;
     $prevpos = $pos;
     $len > 0 ? substr($Config_SH_expanded, $pos, $len) : undef;
@@ -505,18 +700,16 @@ sub EXISTS {
     return(index($Config_SH_expanded, "\n$_[1]='") != -1
 ENDOFEND
 if ($seen_quotes{'"'}) {
-print CONFIG_HEAVY <<'ENDOFEND';
+$heavy_txt .= <<'ENDOFEND';
            or index($Config_SH_expanded, "\n$_[1]=\"") != -1
 ENDOFEND
 }
-print CONFIG_HEAVY <<'ENDOFEND';
+$heavy_txt .= <<'ENDOFEND';
           );
 }
 
 sub STORE  { die "\%Config::Config is read-only\n" }
-*DELETE = \&STORE;
-*CLEAR  = \&STORE;
-
+*DELETE = *CLEAR = \*STORE; # Typeglob aliasing uses less space
 
 sub config_sh {
     substr $Config_SH_expanded, 1, $config_sh_len;
@@ -561,7 +754,7 @@ sub launcher {
 ENDOFEND
 
 if ($^O eq 'os2') {
-    print CONFIG <<'ENDOFSET';
+    $config_txt .= <<'ENDOFSET';
 my %preconfig;
 if ($OS2::is_aout) {
     my ($value, $v) = $Config_SH_expanded =~ m/^used_aout='(.*)'\s*$/m;
@@ -581,11 +774,11 @@ ENDOFSET
            $dll = $1, last if /^PERL_DLL_BASE\s*=\s*(\S*)\s*$/;
        }
     }
-    print CONFIG <<ENDOFSET if $dll;
+    $config_txt .= <<ENDOFSET if $dll;
 \$preconfig{dll_name} = '$dll';
 ENDOFSET
 } else {
-    print CONFIG <<'ENDOFSET';
+    $config_txt .= <<'ENDOFSET';
 sub TIEHASH {
     bless $_[1], $_[0];
 }
@@ -617,13 +810,15 @@ if ($Common{byteorder}) {
 }
 my $fast_config = join '', map { "    $_,\n" } sort values %Common;
 
-print CONFIG sprintf <<'ENDOFTIE', $fast_config;
+# Sanity check needed to stop an infinite loop if Config_heavy.pl fails to
+# define &launcher for some reason (eg it got truncated)
+$config_txt .= sprintf <<'ENDOFTIE', $fast_config;
 
 sub DESTROY { }
 
 sub AUTOLOAD {
     require 'Config_heavy.pl';
-    goto \&launcher;
+    goto \&launcher unless $Config::AUTOLOAD =~ /launcher$/;
     die "&Config::AUTOLOAD failed on $Config::AUTOLOAD";
 }
 
@@ -633,7 +828,7 @@ tie %%Config, 'Config', {
 ENDOFTIE
 
 
-open(CONFIG_POD, ">lib/Config.pod") or die "Can't open lib/Config.pod: $!";
+open(CONFIG_POD, ">$Config_POD") or die "Can't open $Config_POD: $!";
 print CONFIG_POD <<'ENDOFTAIL';
 =head1 NAME
 
@@ -669,12 +864,16 @@ Values stored in config.sh as 'undef' are returned as undefined
 values.  The perl C<exists> function can be used to check if a
 named variable exists.
 
+For a description of the variables, please have a look at the
+Glossary file, as written in the Porting folder, or use the url:
+http://perl5.git.perl.org/perl.git/blob/HEAD:/Porting/Glossary
+
 =over 4
 
 =item myconfig()
 
 Returns a textual summary of the major perl configuration values.
-See also C<-V> in L<perlrun/Switches>.
+See also C<-V> in L<perlrun/Command Switches>.
 
 =item config_sh()
 
@@ -694,7 +893,34 @@ printed on a separate line in the form:
   name='value';
 
 Names which are unknown are output as C<name='UNKNOWN';>.
-See also C<-V:name> in L<perlrun/Switches>.
+See also C<-V:name> in L<perlrun/Command Switches>.
+
+=item bincompat_options()
+
+Returns a list of C pre-processor options used when compiling this F<perl>
+binary, which affect its binary compatibility with extensions.
+C<bincompat_options()> and C<non_bincompat_options()> are shown together in
+the output of C<perl -V> as I<Compile-time options>.
+
+=item non_bincompat_options()
+
+Returns a list of C pre-processor options used when compiling this F<perl>
+binary, which do not affect binary compatibility with extensions.
+
+=item compile_date()
+
+Returns the compile date (as a string), equivalent to what is shown by
+C<perl -V>
+
+=item local_patches()
+
+Returns a list of the names of locally applied patches, equivalent to what
+is shown by C<perl -V>.
+
+=item header_files()
+
+Returns a list of the header files that should be used as dependencies for
+XS code, for this version of Perl on this platform.
 
 =back
 
@@ -750,6 +976,8 @@ some of the variables described below, or may have extraneous variables
 specific to that particular port.  See the port specific documentation
 in such cases.
 
+=cut
+
 ENDOFTAIL
 
 if ($Opts{glossary}) {
@@ -766,12 +994,16 @@ sub process {
       print CONFIG_POD <<EOF if $text;
 =back
 
+=cut
+
 EOF
       print CONFIG_POD <<EOF;
 =head2 $c
 
 =over 4
 
+=cut
+
 EOF
      $text = 1;
     }
@@ -821,6 +1053,21 @@ print CONFIG_POD <<'ENDOFTAIL';
 
 =back
 
+=head1 GIT DATA
+
+Information on the git commit from which the current perl binary was compiled
+can be found in the variable C<$Config::Git_Data>.  The variable is a
+structured string that looks something like this:
+
+  git_commit_id='ea0c2dbd5f5ac6845ecc7ec6696415bf8e27bd52'
+  git_describe='GitLive-blead-1076-gea0c2db'
+  git_branch='smartmatch'
+  git_uncommitted_changes=''
+  git_commit_id_title='Commit id:'
+  git_commit_date='2009-05-09 17:47:31 +0200'
+
+Its format is not guaranteed not to change over time.
+
 =head1 NOTE
 
 This module contains a good example of how to use tie to implement a
@@ -831,10 +1078,30 @@ outside of it.
 
 ENDOFTAIL
 
-close(CONFIG_HEAVY);
-close(CONFIG);
-close(GLOS);
+close(GLOS) if $Opts{glossary};
 close(CONFIG_POD);
+print "written $Config_POD\n";
+
+my $orig_config_txt = "";
+my $orig_heavy_txt = "";
+{
+    local $/;
+    my $fh;
+    $orig_config_txt = <$fh> if open $fh, "<", $Config_PM;
+    $orig_heavy_txt  = <$fh> if open $fh, "<", $Config_heavy;
+}
+
+if ($orig_config_txt ne $config_txt or $orig_heavy_txt ne $heavy_txt) {
+    open CONFIG, ">", $Config_PM or die "Can't open $Config_PM: $!\n";
+    open CONFIG_HEAVY, ">", $Config_heavy or die "Can't open $Config_heavy: $!\n";
+    print CONFIG $config_txt;
+    print CONFIG_HEAVY $heavy_txt;
+    close(CONFIG_HEAVY);
+    close(CONFIG);
+    print "updated $Config_PM\n";
+    print "updated $Config_heavy\n";
+}
+
 
 # Now create Cross.pm if needed
 if ($Opts{cross}) {
@@ -861,6 +1128,8 @@ EOS
   $cross =~ s/\*\*\*replace-marker\*\*\*/$Opts{cross}/g;
   print CROSS $cross;
   close CROSS;
+  print "written lib/Cross.pm\n";
+  unshift(@INC,"xlib/$Opts{cross}");
 }
 
 # Now do some simple tests on the Config.pm file we have created