Perl 5.001
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / MakeMaker.pm
index c70de4e..e09b438 100644 (file)
@@ -1,17 +1,18 @@
 package ExtUtils::MakeMaker;
 
-$Version = 4.01; # Last edited 25th Jan 1995 by Tim Bunce
+$Version = 4.086; # Last edited 9 Mar 1995 by Andy Dougherty
 
 use Config;
+check_hints();
 use Carp;
 use Cwd;
 
 require Exporter;
 @ISA = qw(Exporter);
-@EXPORT = qw(&WriteMakefile &mkbootstrap $Verbose);
+@EXPORT = qw(&WriteMakefile &mkbootstrap &mksymlists $Verbose);
 @EXPORT_OK = qw($Version %att %skip %Recognized_Att_Keys
        @MM_Sections %MM_Sections
-       &help &lsdir);
+       &help &lsdir &neatvalue);
 
 $Is_VMS = $Config{'osname'} eq 'VMS';
 require ExtUtils::MM_VMS if $Is_VMS;
@@ -29,9 +30,9 @@ ExtUtils::MakeMaker - create an extension Makefile
 
 =head1 SYNOPSIS
 
-use ExtUtils::MakeMaker;
+C<use ExtUtils::MakeMaker;>
 
-WriteMakefile( ATTRIBUTE => VALUE [, ...] );
+C<WriteMakefile( ATTRIBUTE =E<gt> VALUE [, ...] );>
 
 =head1 DESCRIPTION
 
@@ -43,6 +44,17 @@ It splits the task of generating the Makefile into several subroutines
 that can be individually overridden.  Each subroutine returns the text
 it wishes to have written to the Makefile.
 
+MakeMaker.pm uses the architecture specific information from
+Config.pm. In addition the extension may contribute to the C<%Config>
+hash table of Config.pm by supplying hints files in a C<hints/>
+directory. The hints files are expected to be named like their
+counterparts in C<PERL_SRC/hints>, but with an C<.pl> file name
+extension (eg. C<next_3_2.sh>). They are simply C<eval>ed by MakeMaker
+and can be used to execute commands as well as to include special
+variables. If there is no hintsfile for the actual system, but for
+some previous releases of the same operating system, the latest one of
+those is used.
+
 =head2 Default Makefile Behaviour
 
 The automatically generated Makefile enables the user of the extension
@@ -50,15 +62,15 @@ to invoke
 
   perl Makefile.PL
   make
-  make test
-  make install # May need to invoke as root to write into INST_LIB
+  make test # optionally set TEST_VERBOSE=1
+  make install # See below
 
 The Makefile to be produced may be altered by adding arguments of the
 form C<KEY=VALUE>. If the user wants to have the extension installed
 into a directory different from C<$Config{"installprivlib"}> it can be
 done by specifying
 
-  perl Makefile.PL INST_LIB=~/myperllib
+  perl Makefile.PL INST_LIB=~/myperllib INST_EXE=~/bin
 
 Note, that in this example MakeMaker does the tilde expansion for you
 and INST_ARCHLIB is set to either C<INST_LIB/$Config{"osname"}> if
@@ -71,21 +83,109 @@ Other interesting targets in the generated Makefile are
   make realclean  # delete all derived files (including installed files)
   make distclean  # produce a gzipped file ready for shipping
 
-The macros in the produced Makefile may be overriden on the command
-line to the make call like:
+The macros in the produced Makefile may be overridden on the command
+line to the make call as in the following example:
 
-  make INST_LIB=/some/where INST_ARCHLIB=/some/where
+  make INST_LIB=/some/where INST_ARCHLIB=/some/where INST_EXE=/u/k/bin
 
 Note, that this is a solution provided by C<make> in general, so tilde
 expansion will probably not be available and INST_ARCHLIB will not be
 set automatically when INST_LIB is given as argument.
 
-(This section is yet to be completed ...)
+The generated Makefile does not set any permissions. The installer has
+to decide, which umask should be in effect.
+
+=head2 Special case C<make install>
+
+The I<install> target of the generated Makefile is for system
+administrators only that have writing permissions on the
+system-specific directories $Config{installprivlib},
+$Config{installarchlib}, and $Config{installbin}. This works, because
+C<make> alone in fact puts all relevant files into directories that
+are named by the macros INST_LIB, INST_ARCHLIB, and INST_EXE. All
+three default to ./blib if you are not building below the perl source
+directory. C<make install> is just a recursive call to C<make> with
+the three relevant parameters set accordingly to the system-wide
+defaults.
+
+C<make install> per default writes some documentation of what has been
+done into the file C<$Config{'installarchlib'}/perllocal.pod>. This is
+an experimental feature. It can be bypassed by calling C<make
+pure_install>.
+
+Users that do not have privileges on the system but want to install
+the relevant files of the module into their private library or binary
+directories do not call C<make install>. In priciple they have the
+choice to either say
+
+    # case: trust the module
+    perl Makefile.PL INST_LIB=~/perllib INST_EXE=~/bin
+    make
+    make test
+
+or
+
+    # case: want to run tests before installation
+    perl Makefile.PL
+    make
+    make test
+    make INST_LIB=/some/where INST_ARCHLIB=/foo/bar INST_EXE=/somebin
+
+(C<make test> is not necessarily supported for all modules.)
+
+=head2 Support to Link a new Perl Binary
+
+An extension that is built with the above steps is ready to use on
+systems supporting dynamic loading. On systems that do not support
+dynamic loading, any newly created extension has to be linked together
+with the available ressources. MakeMaker supports the linking process
+by creating appropriate targets in the Makefile whenever an extension
+is built. You can invoke the corresponding section of the makefile with
+
+    make perl
+
+That produces a new perl binary in the current directory with all
+extensions linked in that can be found in INST_ARCHLIB and
+PERL_ARCHLIB.
+
+The binary can be installed into the directory where perl normally
+resides on your machine with
+
+    make inst_perl
+
+To produce a perl binary with a different name than C<perl>, either say
+
+    perl Makefile.PL MAP_TARGET=myperl
+    make myperl
+    make inst_perl
+
+or say
+
+    perl Makefile.PL
+    make myperl MAP_TARGET=myperl
+    make inst_perl MAP_TARGET=myperl
+
+In any case you will be prompted with the correct invocation of the
+C<inst_perl> target that installs the new binary into
+$Config{'installbin'}.
+
+Note, that there is a C<makeaperl> scipt in the perl distribution,
+that supports the linking of a new perl binary in a similar fashion,
+but with more options.
+
+C<make inst_perl> per default writes some documentation of what has been
+done into the file C<$Config{'installarchlib'}/perllocal.pod>. This
+can be bypassed by calling C<make pure_inst_perl>.
+
+Warning: the inst_perl: target is rather mighty and will probably
+overwrite your existing perl binary. Use with care!
 
 =head2 Determination of Perl Library and Installation Locations
 
-MakeMaker needs to know, or to guess, where certain things are located.
-Especially INST_LIB, INST_ARCHLIB, PERL_LIB, PERL_ARCHLIB and PERL_SRC.
+MakeMaker needs to know, or to guess, where certain things are
+located.  Especially INST_LIB and INST_ARCHLIB (where to install files
+into), PERL_LIB and PERL_ARCHLIB (where to read existing modules
+from), and PERL_INC (header files and C<libperl*.*>).
 
 Extensions may be built either using the contents of the perl source
 directory tree or from an installed copy of the perl library.
@@ -126,16 +226,16 @@ PERL_LIB = Directory where we read the perl library files
 PERL_ARCHLIB = Same as above for architecture dependent files
 
 INST_LIB = Directory where we put library files of this extension
-       while building it. If we are building below PERL_SRC/ext
-       we default to PERL_SRC/lib, else we default to ./blib.
+while building it. If we are building below PERL_SRC/ext
+we default to PERL_SRC/lib, else we default to ./blib.
 
 INST_ARCHLIB = Same as above for architecture dependent files
 
-INST_LIBDIR = $(INST_LIB)$(ROOTEXT)
+INST_LIBDIR = C<$(INST_LIB)$(ROOTEXT)>
 
-INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
+INST_AUTODIR = C<$(INST_LIB)/auto/$(FULLEXT)>
 
-INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
+INST_ARCHAUTODIR = C<$(INST_ARCHLIB)/auto/$(FULLEXT)>
 
 =head2 Customizing The Generated Makefile
 
@@ -149,8 +249,12 @@ or as NAME=VALUE pairs on the command line:
 
 This description is not yet documented; you can get at the description
 with the command
-    perl Makefile.PL help    (if you already have a basic Makefile.PL)
-or  perl -e 'use ExtUtils::MakeMaker qw(&help); &help;'
+
+C<perl Makefile.PL help>    (if you already have a basic Makefile.PL)
+
+or
+
+C<perl -e 'use ExtUtils::MakeMaker qw(&help); &help;'>
 
 =head2 Overriding MakeMaker Methods
 
@@ -166,140 +270,45 @@ or you can edit the default by saying something like:
 
        sub MY::c_o { $_=MM->c_o; s/old text/new text/; $_ }
 
-If you still need a different solution, try to develop another 
-subroutine, that fits your needs and submit the diffs to 
-perl5-porters@nicoh.com or comp.lang.perl as appropriate.
-
-
-=head1 AUTHORS
-
-Andy Dougherty <doughera@lafcol.lafayette.edu>, Andreas Koenig
-<k@franz.ww.TU-Berlin.DE>, Tim Bunce <Tim.Bunce@ig.co.uk>
-
-=head1 MODIFICATION HISTORY
-
-v1, August 1994; by Andreas Koenig. Based on Andy Dougherty's Makefile.SH.
-v2, September 1994 by Tim Bunce.
-v3.0 October  1994 by Tim Bunce.
-v3.1 November 11th 1994 by Tim Bunce.
-v3.2 November 18th 1994 by Tim Bunce.
-v3.3 November 27th 1994 by Andreas Koenig.
-v3.4 December  7th 1994 by Andreas Koenig and Tim Bunce.
-v3.5 December 15th 1994 by Tim Bunce.
-v3.6 December 15th 1994 by Tim Bunce.
-v3.7 December 30th 1994 By Tim Bunce
-v3.8 January  17th 1995 By Andreas Koenig and Tim Bunce
-
-- Introduces ./blib as the directory, where the ready-to-use module
-will live for the time of the building process if PERL_SRC/lib is not
-available. ./blib is turned into an absolute pathname and gets passed
-to subdirectories when writing the Makefile.
-
-- INST_ARCHLIB will now be set equal to INST_LIB if we cannot
-determine it with the methods near line 620 (in the intialize
-subroutine).
-
-- Introduced the install subroutine, that calls another make
-recursively with INST_LIB, and INST_ARCHLIB set according to the local
-conventions.
-
-- Since version 3.6 all *.al and *.ix files are installed into
-$installprivlib. In perl5.000 they were installed into
-$installarchlib. Version 3.8 takes precautions to delete old *.{al,ix}
-files that are left over in $installarchlib. Installperl is also
-patched to both delete old *.al and *.ix files, that were put into
-$installarchlib, and to install them properly from now on.
-
-- h2xs is patched by Dean Roehrich to reintroduce the C<-A> option and
-reconsiders the use of the AutoLoader. Also podifies h2xs.
-
-- Patches to {DB_File,Fcntl,GDBM_File,POSIX,Socket}.pm, eliminating
-AutoLoader from @ISA (by Dean Roehrich).
-
-- A patch to AutoSplit.pm makes sure, the target directory of the
-split exists.
-
-- installperl now installs all *.h files into $installarchlib/CORE.
-
-- added a simple help function
-
-- AutoSplit:
-
-       Turned two constants into package variables.
-       Modified the default for &autosplit to be $CheckModTime=1.
-       Added warning and comment if auto dir does not exist.
-       Enhanced AutoLoader check (POSIX.pm was not getting AutoSplit!)
-       Improved logging if $Verbose>=2.
-
-- MakeMaker:
-
-       EXPORT_OK lsdir(), it's very handy.
-       Deleted much of the early revision history.
-       Changed LDTARGET (bad name) to LDFROM (better, but not great :)
-       INST_ARCHLIB for ./blib found via mapping from INST_LIB ./blib
-         (this allows error message if INST_ARCHLIB still undefined)
-       Added optional regex filter to &lsdir.
-       Added cute auto handling of a ./$(BASEEXT)/*.pm directory as
-         per recent messages with Nick re ext/nTk/nTk/Text.pm
-       Added NOOP, RM_F, RM_RF, TOUCH, CP to %att.
-       NOOP is now "" on Unix, "<tab>" caused problems (see makefile section)
-       RM_F etc now expanded when Makefile written.
-       Old AUTOSPLITLIB definition deleted.
-       See new dynamic_lib section for new ARMAYBE handling.
-       install section now uses $(INSTALLPRIVLIB) because on some
-       systems INSTALLPRIVLIB != PRIVLIB (ditto for archlib)
-
-v3.9 January 19th 1995 By Tim Bunce
-
-Added ~ processing to parse_args to allow perl Makefile.PL X=~/path.
-Added warning about LDTARGET to LDFROM attribute name change.
-Fallback INST_ARCHLIB is INST_LIB, or INST_LIB/$archname if it exists.
-Tightened up dependency checking of Makefile against config.sh etc.
-INST_STATIC is now INST_ARCHLIBDIR/BASEEXT.a for later make-a-perl.
-AUTOSPLITFILE tidied up (AutoSplit patch included in this version).
-MKPATH now skips inner loop if directory already exists.
-The dynamic_lib section was revised with explicit dec_osf support added.
-Make clean now renames Makefile to Makefile.old (make_ext also patched).
-The large initialize function has been split into smaller pieces.
-Added I_PERL_LIBS to simplify -I paths for PERL_*LIB.
-
-v3.10 January 23rd 1995 By Tim Bunce
-
-miniperl now given preference when defining PERL. This improves the
-reliability of ext/*/Makefile's recreating themselves if needed.
-$(XS), $(C) and $(H) renamed to XS_FILES C_FILES and H_FILES.
-INST_STATIC now INST_ARCHLIBDIR/BASEEXT.a (alongside INST_DYNAMIC).
-Static lib no longer copied back to local directory.
-
-v3.11 January 24th 1995 By Andreas Koenig
-
-DynaLoader.c was not deleted by clean target, now fixed.
-Added PMDIR attribute that allows directories to be named that contain
-only *.p[pl] files to be installed into INST_LIB. Added some documentation.
-
-v4.00 January 24th 1995 By Tim Bunce
-
-Revised some of the documentation. Changed version number to 4.00 to
-avoid problems caused by my earlier poor choice of 3.10!  Renamed PMDIR
-to PMLIBDIRS and restructured find code to use inherited MY->libscan.
-Added ability to say: "perl Makefile.PL help"  to get help.
-Added ability to say: "perl Makefile.PL verbose"  to get debugging.
-Added MakeMaker version number to generated Makefiles.
-
-=head1 NOTES
-
-MakeMaker development work still to be done:
-
-Needs more complete documentation.
-
-Add method to take a list of files and wrap it in a Makefile
-compatible way (<space><backslash><newline><tab>).
-
-Add a html: target when there has been found a general solution to
-installing html files.
+If you still need a different solution, try to develop another
+subroutine, that fits your needs and submit the diffs to
+F<perl5-porters@nicoh.com> or F<comp.lang.perl> as appropriate.
 
 =cut
 
+sub check_hints {
+    # We allow extension-specific hints files. If we find one we act as if Config.pm
+    # had read the contents
+
+    # First we look for the best hintsfile we have
+    my(@goodhints);
+    my($hint)="$Config{'osname'}_$Config{'osvers'}";
+    $hint =~ s/\./_/g;
+    $hint =~ s/_$//;
+    opendir DIR, "hints";
+    while (defined ($_ = readdir DIR)) {
+       next if /^\./;
+       next unless s/\.pl$//;
+       next unless /^$Config{'osname'}/;
+       # Don't trust a hintfile for a later OS version:
+       next if $_ gt $hint;
+       push @goodhints, $_;
+       if ($_ eq $hint){
+           @goodhints=$_;
+           last;
+       }
+    }
+    closedir DIR;
+    return unless @goodhints; # There was no hintsfile
+    # the last one in lexical ordering is our choice:
+    $hint=(reverse sort @goodhints)[0];
+
+    # execute the hintsfile:
+    open HINTS, "hints/$hint.pl";
+    @goodhints = <HINTS>;
+    close HINTS;
+    eval join('',@goodhints);
+}
 
 # Setup dummy package:
 # MY exists for overriding methods to be defined within
@@ -360,7 +369,7 @@ $Attrib_Help = <<'END';
 
  PMLIBDIRS:    Ref to array of subdirectories containing library files.
                Defaults to [ 'lib', $(BASEEXT) ]. The directories will
-               be scanned and any *.pm and *.pl files they contain will
+               be scanned and any files they contain will
                be installed in the corresponding location in the library.
                A MY::libscan() function can be used to alter the behaviour.
                Defining PM in the Makefile.PL will override PMLIBDIRS.
@@ -383,12 +392,41 @@ $Attrib_Help = <<'END';
 
  H:            Ref to array of *.h file names. Similar to C: above.
 
+ EXE_FILES:    Ref to array of executable files. The files will be copied to 
+               the INST_EXE directory. The installed files will be deleted 
+               by a make realclean.
+
+ INST_EXE:     Directory, where executable scripts should be installed. Defaults
+               to "./blib", just to have a dummy location during testing.
+               C<make install> will set INST_EXE to $Config{'installbin'}.
+
  LINKTYPE:     =>'static' or 'dynamic' (default unless usedl=undef in config.sh)
                Should only be used to force static linking (also see linkext below).
 
+ DL_FUNCS:     Hashref of symbol names for routines to be made available as
+               universal symbols.  Each key/value pair consists of the package
+               name and an array of routine names in that package.  Used only
+               under AIX (export lists) and VMS (linker options) at present.
+               The routine names supplied will be expanded in the same way
+               as XSUB names are expanded by the XS() macro.
+               Defaults to { "$(NAME)" => [ "boot_$(NAME)" ] }.
+               (e.g. { "RPC" => [qw( boot_rpcb rpcb_gettime getnetconfigent )],
+                       "NetconfigPtr" => [ 'DESTROY'] } )
+
+ DL_VARS:      Array of symbol names for variables to be made available as
+               universal symbols.  Used only under AIX (export lists) and VMS
+               (linker options) at present.  Defaults to [].
+               (e.g. [ qw( Foo_version Foo_numstreams Foo_tree ) ])
+
  CONFIG:       =>[qw(archname manext)] defines ARCHNAME & MANEXT from config.sh
  SKIP:         =>[qw(name1 name2)] skip (do not write) sections of the Makefile
 
+ MAP_TARGET:   If it is intended, that a new perl binary be produced, this variable
+               may hold a name for that binary. Defaults to C<perl>
+
+ LIBPERL_A:    The filename of the perllibrary that will be used together
+               with this extension. Defaults to C<libperl.a>.
+
  PERL:
  FULLPERL:
 
@@ -409,8 +447,8 @@ sub help {print $Attrib_Help;}
 
 @MM_Sections_spec = (
     'post_initialize'  => {},
-    'constants'                => {},
     'const_config'     => {},
+    'constants'                => {},
     'const_loadlibs'   => {},
     'const_cccmd'      => {},
     'tool_autosplit'   => {},
@@ -422,12 +460,14 @@ sub help {print $Attrib_Help;}
     'xs_o'             => {},
     'top_targets'      => {},
     'linkext'          => {},
+    'dlsyms'           => {},
     'dynamic'          => {},
     'dynamic_bs'       => {},
     'dynamic_lib'      => {},
     'static'           => {},
     'static_lib'       => {},
     'installpm'                => {},
+    'installbin'       => {},
     'subdirs'          => {},
     'clean'            => {},
     'realclean'                => {},
@@ -438,6 +478,7 @@ sub help {print $Attrib_Help;}
     'perldepend'       => {},
     'makefile'         => {},
     'postamble'                => {},
+    'staticmake'       => {},
 );
 %MM_Sections = @MM_Sections_spec; # looses section ordering
 @MM_Sections = grep(!ref, @MM_Sections_spec); # keeps order
@@ -455,6 +496,24 @@ foreach(split(/\n/,$Attrib_Help)){
 
 sub skipcheck{
     my($section) = @_;
+    if ($section eq 'dynamic') {
+       print STDOUT "Warning (non-fatal): Target 'dynamic' depends on targets "
+         . "in skipped section 'dynamic_bs'\n"
+            if $skip{'dynamic_bs'} && $Verbose;
+        print STDOUT "Warning (non-fatal): Target 'dynamic' depends on targets "
+         . "in skipped section 'dynamic_lib'\n"
+            if $skip{'dynamic_lib'} && $Verbose;
+    }
+    if ($section eq 'dynamic_lib') {
+        print STDOUT "Warning (non-fatal): Target '\$(INST_DYNAMIC)' depends on "
+         . "targets in skipped section 'dynamic_bs'\n"
+            if $skip{'dynamic_bs'} && $Verbose;
+    }
+    if ($section eq 'static') {
+        print STDOUT "Warning (non-fatal): Target 'static' depends on targets "
+         . "in skipped section 'static_lib'\n"
+            if $skip{'static_lib'} && $Verbose;
+    }
     return 'skipped' if $skip{$section};
     return '';
 }
@@ -533,6 +592,11 @@ sub mkbootstrap{
     MY->mkbootstrap(@_);
 }
 
+sub mksymlists{
+    %att = @_;
+    parse_args(\%att, @ARGV);
+    MY->mksymlists(@_);
+}
 
 sub parse_args{
     my($attr, @args) = @_;
@@ -553,9 +617,9 @@ sub parse_args{
     if (defined $$attr{'potential_libs'}){
        my($msg)="'potential_libs' => '$$attr{potential_libs}' should be";
        if ($$attr{'potential_libs'}){
-           print STDERR "$msg changed to:\n\t'LIBS' => ['$$attr{potential_libs}']\n";
+           print STDOUT "$msg changed to:\n\t'LIBS' => ['$$attr{potential_libs}']\n";
        } else {
-           print STDERR "$msg deleted.\n";
+           print STDOUT "$msg deleted.\n";
        }
        $$attr{LIBS} = [$$attr{'potential_libs'}];
        delete $$attr{'potential_libs'};
@@ -563,20 +627,20 @@ sub parse_args{
     # catch old-style 'ARMAYBE' and inform user how to 'upgrade'
     if (defined $$attr{'ARMAYBE'}){
        my($armaybe) = $$attr{'ARMAYBE'};
-       print STDERR "ARMAYBE => '$armaybe' should be changed to:\n",
+       print STDOUT "ARMAYBE => '$armaybe' should be changed to:\n",
                        "\t'dynamic_lib' => {ARMAYBE => '$armaybe'}\n";
        my(%dl) = %{$$attr{'dynamic_lib'} || {}};
        $$attr{'dynamic_lib'} = { %dl, ARMAYBE => $armaybe};
        delete $$attr{'ARMAYBE'};
     }
     if (defined $$attr{'LDTARGET'}){
-       print STDERR "LDTARGET should be changed to LDFROM\n";
+       print STDOUT "LDTARGET should be changed to LDFROM\n";
        $$attr{'LDFROM'} = $$attr{'LDTARGET'};
        delete $$attr{'LDTARGET'};
     }
     foreach(sort keys %{$attr}){
        print STDOUT "  $_ => ".neatvalue($$attr{$_}) if ($Verbose);
-       warn "'$_' is not a known MakeMaker parameter name.\n"
+       print STDOUT "'$_' is not a known MakeMaker parameter name.\n"
            unless exists $Recognized_Att_Keys{$_};
     }
 }
@@ -584,6 +648,7 @@ sub parse_args{
 
 sub neatvalue{
     my($v) = @_;
+    return "undef" unless defined $v;
     my($t) = ref $v;
     return "'$v'" unless $t;
     return "[ ".join(', ',map("'$_'",@$v))." ]" if ($t eq 'ARRAY');
@@ -610,8 +675,8 @@ Exporter::import('ExtUtils::MakeMaker',
 @Other_Att_Keys{qw(EXTRALIBS BSLOADLIBS LDLOADLIBS)} = (1) x 3;
 
 if ($Is_VMS = $Config{'osname'} eq 'VMS') {
-    require File::VMSspec;
-    import File::VMSspec 'vmsify';
+    require VMS::Filespec;
+    import VMS::Filespec 'vmsify';
 }
 
 
@@ -643,13 +708,13 @@ sub init_main {
        }
     }
     unless ($att{PERL_SRC}){
-       warn "Unable to locate perl source.\n";
        # we should also consider $ENV{PERL5LIB} here
        $att{PERL_LIB}     = $Config{'privlib'} unless $att{PERL_LIB};
        $att{PERL_ARCHLIB} = $Config{'archlib'} unless $att{PERL_ARCHLIB};
        $att{PERL_INC}     = "$att{PERL_ARCHLIB}/CORE"; # wild guess for now
-       die "Try setting PERL_SRC in Makefile.PL or on command line.\n"
+       die "Unable to locate Perl source. Try setting PERL_SRC in Makefile.PL or on command line.\n"
                unless (-f "$att{PERL_INC}/perl.h");
+       print STDOUT "Using header files found in $att{PERL_INC}" if $Verbose;
     } else {
        $att{PERL_LIB}     = "$att{PERL_SRC}/lib" unless $att{PERL_LIB};
        $att{PERL_ARCHLIB} = $att{PERL_LIB};
@@ -681,13 +746,17 @@ sub init_main {
            my($archname) = $Config{'archname'};
            if (-d "$att{INST_LIB}/$archname"){
                $att{INST_ARCHLIB} = "$att{INST_LIB}/$archname";
-               warn "Defaulting INST_ARCHLIB to INST_LIB/$archname\n";
+               print STDOUT "Defaulting INST_ARCHLIB to INST_LIB/$archname\n";
            } else {
                $att{INST_ARCHLIB} = $att{INST_LIB};
-               warn "Warning: Defaulting INST_ARCHLIB to INST_LIB ",
+               print STDOUT "Warning: Defaulting INST_ARCHLIB to INST_LIB ",
                        "(not architecture independent).\n";
            }
        }
+       $att{INST_EXE} = "./blib" unless $att{INST_EXE};
+       $att{MAP_TARGET} = "perl" unless $att{MAP_TARGET};
+       $att{LIBPERL_A} = $Is_VMS ? 'libperl.olb' : 'libperl.a'
+           unless $att{LIBPERL_A};
     }
 
     # make a few simple checks
@@ -703,7 +772,7 @@ sub init_main {
     unless($att{NAME}){ # we have to guess our name
        my($name) = $pwd;
        if ($Is_VMS) {
-         $name =~ s:.*?([^.\]]+)\]:$1: unless ($name =~ s:.*[.\[]ext\.::);
+         $name =~ s:.*?([^.\]]+)\]:$1: unless ($name =~ s:.*[.\[]ext\.(.*)\]:$1:i);
          ($att{NAME}=$name) =~ s#[.\]]#::#g;
        } else {
          $name =~ s:.*/:: unless ($name =~ s:^.*/ext/::);
@@ -713,10 +782,9 @@ sub init_main {
     ($att{FULLEXT} =$att{NAME}) =~ s#::#/#g ;          #eg. BSD/Foo/Socket
     ($att{BASEEXT} =$att{NAME}) =~ s#.*::##;           #eg. Socket
     ($att{ROOTEXT} =$att{FULLEXT}) =~ s#/?\Q$att{BASEEXT}\E$## ; # eg. /BSD/Foo
-    $att{ROOTEXT} = "/$att{ROOTEXT}" if $att{ROOTEXT};
-    $att{ROOTEXT} = "" if $Is_VMS;
+    $att{ROOTEXT} = ($Is_VMS ? '' : '/') . $att{ROOTEXT} if $att{ROOTEXT};
 
-    ($att{DISTNAME}=$att{NAME}) =~ s#(::)#-#g;
+    ($att{DISTNAME}=$att{NAME}) =~ s#(::)#-#g unless $att{DISTNAME};
     $att{VERSION} = "0.1" unless $att{VERSION};
 
 
@@ -726,7 +794,7 @@ sub init_main {
     # will be working versions of perl 5. miniperl has priority over perl
     # for PERL to ensure that $(PERL) is usable while building ./ext/*
     $att{'PERL'} = MY->find_perl(5.0, [ qw(miniperl perl) ],
-           [ $att{PERL_SRC}, split(":", $ENV{PATH}), $Config{'bin'} ], 0 )
+           [ grep defined $_, $att{PERL_SRC}, split(":", $ENV{PATH}), $Config{'bin'} ], $Verbose )
        unless ($att{'PERL'} && -x $att{'PERL'});
 
     # Define 'FULLPERL' to be a non-miniperl (used in test: target)
@@ -734,8 +802,8 @@ sub init_main {
        unless ($att{'FULLPERL'} && -x $att{'FULLPERL'});
 
     if ($Is_VMS) {
-       ($att{'PERL'} = 'MCR ' . vmsify($att{'PERL'})) =~ s:.*/::;
-       ($att{'FULLPERL'} = 'MCR ' . vmsify($att{'FULLPERL'})) =~ s:.*/::;
+       $att{'PERL'} = 'MCR ' . vmsify($att{'PERL'});
+       $att{'FULLPERL'} = 'MCR ' . vmsify($att{'FULLPERL'});
     }
 }
 
@@ -799,14 +867,18 @@ sub init_dirscan {        # --- File and Directory Lists (.xs .pm etc)
            if ($Verbose >= 2);
        use File::Find;         # try changing to require !
        File::Find::find(sub {
-               return unless m/\.p[ml]$/;
+# We now allow any file in PMLIBDIRS to be installed. nTk needs that, and
+# we should allow it.
+#               return unless m/\.p[ml]$/;
+               return if -d $_; # anything else that Can't be copied?
                my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)');
-               $prefix =  '$(INST_LIB)' if ($path =~ s:^lib/::);
-               local($_) = "$prefix/$path";
+               my $striplibpath;
+               $prefix =  '$(INST_LIB)' if (($striplibpath = $path) =~ s:^lib/::);
+               local($_) = "$prefix/$striplibpath";
                my($inst) = MY->libscan();
                print "libscan($path) => '$inst'" if ($Verbose >= 2);
                return unless $inst;
-               $pm{$path} = "$inst";
+               $pm{$path} = $inst;
             }, @{$att{PMLIBDIRS}});
     }
 
@@ -814,15 +886,18 @@ sub init_dirscan {        # --- File and Directory Lists (.xs .pm etc)
     $att{XS}  = \%xs             unless $att{XS};
     $att{PM}  = \%pm             unless $att{PM};
     $att{C}   = [sort keys %c]   unless $att{C};
+    my(@o_files) = @{$att{C}};
+    my($sufx) = $Is_VMS ? '.obj' : '.o';
+    $att{O_FILES} = [grep s/\.c$/$sufx/, @o_files] ;
     $att{H}   = [sort keys %h]   unless $att{H};
 }
 
 
 sub libscan {
+    return undef if m:/RCS/: ;
     $_;
 }
 
-
 sub init_others {      # --- Initialize Other Attributes
 
     for $key (keys(%Recognized_Att_Keys), keys(%Other_Att_Keys)){
@@ -845,7 +920,7 @@ sub init_others {   # --- Initialize Other Attributes
        }
     }
 
-    warn "CONFIG must be an array ref\n"
+    print STDOUT "CONFIG must be an array ref\n"
        if ($att{CONFIG} and ref $att{CONFIG} ne 'ARRAY');
     $att{CONFIG} = [] unless (ref $att{CONFIG});
     push(@{$att{CONFIG}},
@@ -855,12 +930,10 @@ sub init_others { # --- Initialize Other Attributes
     push(@{$att{CONFIG}}, 'shellflags') if $Config{'shellflags'};
 
     if ($Is_VMS) {
-      # This will not make other Makefile.PLs portable. Any Makefile.PL
-      # which says OBJECT => "foo.o bar.o" will fail on VMS. It might
-      # be better to fix the c_o section to produce .o files.
       $att{OBJECT} = '$(BASEEXT).obj' unless $att{OBJECT};
       $att{OBJECT} =~ s/[^,\s]\s+/, /g;
       $att{OBJECT} =~ s/\n+/, /g;
+      $att{OBJECT} =~ s#\.o,#\.obj,#;
     } else {
       $att{OBJECT} = '$(BASEEXT).o' unless $att{OBJECT};
       $att{OBJECT} =~ s/\n+/ \\\n\t/g;
@@ -868,11 +941,19 @@ sub init_others { # --- Initialize Other Attributes
     $att{BOOTDEP}  = (-f "$att{BASEEXT}_BS") ? "$att{BASEEXT}_BS" : "";
     $att{LD}       = ($Config{'ld'} || 'ld') unless $att{LD};
     $att{LDFROM} = '$(OBJECT)' unless $att{LDFROM};
-    $att{LINKTYPE} = ($Config{'usedl'}) ? 'dynamic' : 'static'
-       unless $att{LINKTYPE};
+    # Sanity check: don't define LINKTYPE = dynamic if we're skipping
+    # the 'dynamic' section of MM.  We don't have this problem with
+    # 'static', since we either must use it (%Config says we can't
+    # use dynamic loading) or the caller asked for it explicitly.
+    if (!$att{LINKTYPE}) {
+       $att{LINKTYPE} = grep(/dynamic/,@{$att{SKIP} || []})
+                        ? 'static'
+                        : ($Config{'usedl'} ? 'dynamic' : 'static');
+    };
 
     # These get overridden for VMS and maybe some other systems
     $att{NOOP}  = "";
+    $att{MAKEFILE} = "Makefile";
     $att{RM_F}  = "rm -f";
     $att{RM_RF} = "rm -rf";
     $att{TOUCH} = "touch";
@@ -895,17 +976,21 @@ sub lsdir{
 sub find_perl{
     my($self, $ver, $names, $dirs, $trace) = @_;
     my($name, $dir);
-    print "Looking for perl $ver by these names: @$names, in these dirs: @$dirs\n"
-       if ($trace);
+    if ($trace){
+       print "Looking for perl $ver by these names: ";
+       print "@$names, ";
+       print "in these dirs:";
+       print "@$dirs";
+    }
     foreach $dir (@$dirs){
        next unless defined $dir; # $att{PERL_SRC} may be undefined
        foreach $name (@$names){
-           print "checking $dir/$name\n" if ($trace >= 2);
+           print "Checking $dir/$name " if ($trace >= 2);
            if ($Is_VMS) {
              $name .= ".exe" unless -x "$dir/$name";
            }
            next unless -x "$dir/$name";
-           print "executing $dir/$name\n" if ($trace);
+           print "Executing $dir/$name" if ($trace);
            my($out);
            if ($Is_VMS) {
              my($vmscmd) = 'MCR ' . vmsify("$dir/$name");
@@ -916,7 +1001,7 @@ sub find_perl{
            return "$dir/$name" if $out =~ /VER_OK/;
        }
     }
-    warn "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
+    print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
     0; # false and not empty
 }
 
@@ -924,7 +1009,7 @@ sub find_perl{
 sub post_initialize{
     "";
 }
+
 
 sub constants {
     my(@m);
@@ -939,10 +1024,12 @@ VERSION = $att{VERSION}
 # (also see INST_LIBDIR and relationship to ROOTEXT)
 INST_LIB = $att{INST_LIB}
 INST_ARCHLIB = $att{INST_ARCHLIB}
+INST_EXE = $att{INST_EXE}
 
 # Perl library to use when building the extension
 PERL_LIB = $att{PERL_LIB}
 PERL_ARCHLIB = $att{PERL_ARCHLIB}
+LIBPERL_A = $att{LIBPERL_A}
 ";
 
     # Define I_PERL_LIBS to include the required -Ipaths
@@ -957,10 +1044,10 @@ PERL_ARCHLIB = $att{PERL_ARCHLIB}
     }
 
     push @m, "
-# Where is the perl source code located? (Eventually we should
-# be able to build extensions without requiring the perl source
-# but that's a way off yet).
-PERL_SRC = $att{PERL_SRC}
+# Where is the perl source code located?
+PERL_SRC = $att{PERL_SRC}\n" if $att{PERL_SRC};
+
+    push @m, "
 # Perl header files (will eventually be under PERL_LIB)
 PERL_INC = $att{PERL_INC}
 # Perl binaries
@@ -985,6 +1072,7 @@ LINKTYPE = $att{LINKTYPE}
 # Handy lists of source code files:
 XS_FILES= ".join(" \\\n\t", sort keys %{$att{XS}})."
 C_FILES = ".join(" \\\n\t", @{$att{C}})."
+O_FILES = ".join(" \\\n\t", @{$att{O_FILES}})."
 H_FILES = ".join(" \\\n\t", @{$att{H}})."
 
 .SUFFIXES: .xs
@@ -1021,28 +1109,56 @@ INST_PM = '.join(" \\\n\t", sort values %{$att{PM}}).'
 
 
 sub const_cccmd{
+    my($self,$libperl)=@_;
+    $libperl or $libperl = $att{LIBPERL_A} || "libperl.a" ;
     # This is implemented in the same manner as extliblist,
     # e.g., do both and compare results during the transition period.
     my($cc,$ccflags,$optimize,$large,$split, $shflags)
        = @Config{qw(cc ccflags optimize large split shellflags)};
     $shflags = '' unless $shflags;
-    my($prog, $old);
+    my($prog, $old, $uc, $perltype);
 
-    chop($old = `cd $att{PERL_SRC}; sh $shflags ./cflags $att{BASEEXT}.c 2>/dev/null`)
+    chop($old = `cd $att{PERL_SRC}; sh $shflags ./cflags $libperl $att{BASEEXT}.c 2>/dev/null`)
        if $att{PERL_SRC};
 
-    if ($prog = $Config{"$att{BASEEXT}_cflags"}) {
+    my(%map) =  (
+               D =>   '-DDEBUGGING',
+               E =>   '-DEMBED',
+               DE =>  '-DDEBUGGING -DEMBED',
+               M =>   '-DEMBED -DMULTIPLICITY',
+               DM =>  '-DDEBUGGING -DEMBED -DMULTIPLICITY',
+               );
+
+    if ($libperl =~ /libperl(\w*)\.a/){
+       $uc = uc($1);
+    } else {
+       $uc = ""; # avoid warning
+    }
+    $perltype = $map{$uc} ? $map{$uc} : "";
+
+    if ($uc =~ /^D/) {
+       $optdebug = "-g";
+    }
+
+
+    my($name);
+    ( $name = $att{NAME} . "_cflags" ) =~ s/:/_/g ;
+    if ($prog = $Config{$name}) {
        # Expand hints for this extension via the shell
-       print STDERR "Processing $att{BASEEXT}_cflags hint:\n" if $Verbose;
+       print STDOUT "Processing $name hint:\n" if $Verbose;
        my(@o)=`cc=\"$cc\"
          ccflags=\"$ccflags\"
          optimize=\"$optimize\"
+         perltype=\"$perltype\"
+         optdebug=\"$optdebug\"
          large=\"$large\"
          split=\"$split\"
          eval '$prog'
          echo cc=\$cc
          echo ccflags=\$ccflags
          echo optimize=\$optimize
+         echo perltype=\$perltype
+         echo optdebug=\$optdebug
          echo large=\$large
          echo split=\$split
          `;
@@ -1051,17 +1167,22 @@ sub const_cccmd{
            chomp $line;
            if ($line =~ /(.*?)=\s*(.*)\s*$/){
                $cflags{$1} = $2;
-               print STDERR "  $1 = $2" if $Verbose;
+               print STDOUT "  $1 = $2" if $Verbose;
            } else {
-               print STDERR "Unrecognised result from hint: '$line'\n";
+               print STDOUT "Unrecognised result from hint: '$line'\n";
            }
        }
-       ($cc,$ccflags,$optimize,$large,$split)=@cflags{qw(cc ccflags optimize large split)};
+       (    $cc,$ccflags,$perltype,$optdebug,$optimize,$large,$split )=@cflags{
+          qw( cc  ccflags  perltype  optdebug  optimize  large  split)};
+    }
+
+    if ($optdebug) {
+       $optimize = $optdebug;
     }
 
-    my($new) = "$cc -c $ccflags $optimize  $large $split";
+    my($new) = "$cc -c $ccflags $optimize $perltype $large $split";
     if (defined($old) and $new ne $old) {
-       warn "Warning (non-fatal): cflags evaluation in MakeMaker differs from shell output\n"
+       print STDOUT "Warning (non-fatal): cflags evaluation in MakeMaker differs from shell output\n"
        ."   package: $att{NAME}\n"
        ."   old: $old\n"
        ."   new: $new\n"
@@ -1081,7 +1202,7 @@ sub const_config{
     my(%once_only);
     foreach $m (@{$att{'CONFIG'}}){
        next if $once_only{$m};
-       warn "CONFIG key '$m' does not exist in Config.pm\n"
+       print STDOUT "CONFIG key '$m' does not exist in Config.pm\n"
                unless exists $Config{$m};
        push @m, "\U$m\E = $Config{$m}\n";
        $once_only{$m} = 1;
@@ -1136,8 +1257,7 @@ sub tool_autosplit{
     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
     q{
 # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
-# Remark: the "" around the -I switches are helpful for the VMS support
-AUTOSPLITFILE = $(PERL) $(I_PERL_LIBS) -e 'use AutoSplit;}.$asl.q{ autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1) ;'
+AUTOSPLITFILE = $(PERL) $(I_PERL_LIBS) -e 'use AutoSplit;}.$asl.q{autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1) ;'
 };
 }
 
@@ -1182,16 +1302,18 @@ sub post_constants{
 # --- Translation Sections ---
 
 sub c_o {
-    '
+    my(@m);
+    push @m, '
 .c.o:
        $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $(INC) $*.c
 ';
+    join "", @m;
 }
 
 sub xs_c {
     '
 .xs.c:
-       $(PERL) $(XSUBPP) $(XSUBPPARGS) $*.xs >xstmp.c && mv xstmp.c $@
+       $(PERL) $(XSUBPP) $(XSUBPPARGS) $*.xs >$*.tc && mv $*.tc $@
 ';
 }
 
@@ -1207,13 +1329,19 @@ sub xs_o {      # many makes are too dumb to use xs_c then c_o
 # --- Target Sections ---
 
 sub top_targets{
-    '
+    my(@m);
+    push @m, '
 all :: config linkext $(INST_PM)
 '.$att{NOOP}.'
 
-config :: Makefile
-       @$(MKPATH) $(INST_LIBDIR) $(INST_ARCHAUTODIR)
+config :: '.$att{MAKEFILE}.'
+       @ $(MKPATH) $(INST_LIBDIR) $(INST_ARCHAUTODIR)
 ';
+
+    push @m, '
+$(O_FILES): $(H_FILES)
+' if @{$att{O_FILES} || []} && @{$att{H} || []};
+    join('',@m);
 }
 
 sub linkext {
@@ -1226,6 +1354,35 @@ $att{NOOP}
 ";
 }
 
+sub dlsyms {
+    my($self,%attribs) = @_;
+
+    return '' if ($Config{'osname'} ne 'aix');
+
+    my($funcs) = $attribs{DL_FUNCS} || $att{DL_FUNCS} || {};
+    my($vars)  = $attribs{DL_VARS} || $att{DL_VARS} || [];
+    my(@m);
+
+    push(@m,"
+dynamic :: $att{BASEEXT}.exp
+
+") unless $skip{'dynamic'};
+
+    push(@m,"
+static :: $att{BASEEXT}.exp
+
+") unless $skip{'static'};
+
+    push(@m,"
+$att{BASEEXT}.exp: Makefile.PL
+",'    $(PERL) $(I_PERL_LIBS) -e \'use ExtUtils::MakeMaker; \\
+       mksymlists(DL_FUNCS => ',
+       %$funcs ? neatvalue($funcs) : '""',', DL_VARS => ',
+       @$vars  ? neatvalue($vars)  : '""', ", NAME => \"$att{NAME}\")'
+");
+
+    join('',@m);
+}
 
 # --- Dynamic Loading Sections ---
 
@@ -1233,7 +1390,7 @@ sub dynamic {
     '
 # $(INST_PM) has been moved to the all: target.
 # It remains here for awhile to allow for old usage: "make dynamic"
-dynamic :: Makefile $(INST_DYNAMIC) $(INST_BOOT) $(INST_PM)
+dynamic :: '.$att{MAKEFILE}.' $(INST_DYNAMIC) $(INST_BOOT) $(INST_PM)
 '.$att{NOOP}.'
 ';
 }
@@ -1246,15 +1403,16 @@ BOOTSTRAP = '."$att{BASEEXT}.bs".'
 # As MakeMaker mkbootstrap might not write a file (if none is required)
 # we use touch to prevent make continually trying to remake it.
 # The DynaLoader only reads a non-empty file.
-$(BOOTSTRAP): Makefile '.$att{BOOTDEP}.'
-       $(PERL) $(I_PERL_LIBS) \
+$(BOOTSTRAP): '."$att{MAKEFILE} $att{BOOTDEP}".'
+       @ echo "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
+       @ $(PERL) $(I_PERL_LIBS) \
                -e \'use ExtUtils::MakeMaker; &mkbootstrap("$(BSLOADLIBS)");\' \
                INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) PERL_SRC=$(PERL_SRC) NAME=$(NAME)
-       @$(TOUCH) $(BOOTSTRAP)
+       @ $(TOUCH) $(BOOTSTRAP)
 
 $(INST_BOOT): $(BOOTSTRAP)
-       @'.$att{RM_RF}.' $(INST_BOOT)
-       '.$att{CP}.' $(BOOTSTRAP) $(INST_BOOT)
+       @ '.$att{RM_RF}.' $(INST_BOOT)
+       -'.$att{CP}.' $(BOOTSTRAP) $(INST_BOOT)
 ';
 }
 
@@ -1274,7 +1432,7 @@ ARMAYBE = '.$armaybe.'
 OTHERLDFLAGS = '.$otherldflags.'
 
 $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP)
-       @$(MKPATH) $(INST_ARCHAUTODIR)
+       @ $(MKPATH) $(INST_ARCHAUTODIR)
 ');
     if ($armaybe ne ':'){
        $ldfrom = "tmp.a";
@@ -1294,7 +1452,7 @@ sub static {
     '
 # $(INST_PM) has been moved to the all: target.
 # It remains here for awhile to allow for old usage: "make static"
-static :: Makefile $(INST_STATIC) $(INST_PM) 
+static :: '.$att{MAKEFILE}.' $(INST_STATIC) $(INST_PM)
 '.$att{NOOP}.'
 ';
 }
@@ -1303,6 +1461,7 @@ sub static_lib{
     my(@m);
     push(@m, <<'END');
 $(INST_STATIC): $(OBJECT) $(MYEXTLIB)
+       @ $(MKPATH) $(INST_ARCHAUTODIR)
 END
     # If this extension has it's own library (eg SDBM_File)
     # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
@@ -1312,9 +1471,11 @@ END
        ar cr $@ $(OBJECT) && $(RANLIB) $@
        @echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)/extralibs.ld
 END
+
+# Old mechanism - still available:
+
     push(@m, <<'END') if $att{PERL_SRC};
-       @: Old mechanism - still needed:
-       @echo "$(EXTRALIBS)" >> $(PERL_SRC)/ext.libs
+       @ echo "$(EXTRALIBS)" >> $(PERL_SRC)/ext.libs
 END
     join('', "\n",@m);
 }
@@ -1345,17 +1506,47 @@ sub installpm_x { # called by installpm per file
     my($instdir) = $inst =~ m|(.*)/|;
     my(@m);
     push(@m,"
-$inst: $dist
-".'    @'.$att{RM_F}.' $@
-       @$(MKPATH) '.$instdir.'
-       '.$att{CP}.' $? $@
+$inst: $dist Makefile
+".'    @ '.$att{RM_F}.' $@
+       @ $(MKPATH) '.$instdir.'
+       '."$att{CP} $dist".' $@
 ');
-    push(@m, "\t\$(AUTOSPLITFILE) \$@ $splitlib/auto\n")
+    push(@m, "\t\@\$(AUTOSPLITFILE) \$@ $splitlib/auto\n")
        if ($splitlib and $inst =~ m/\.pm$/);
     join('', @m);
 }
 
+sub installbin {
+    return "" unless $att{EXE_FILES} && ref $att{EXE_FILES} eq "ARRAY";
+    my(@m, $from, $to, %fromto, @to);
+    for $from (@{$att{EXE_FILES}}) {
+       local($_)= '$(INST_EXE)/' . basename($from);
+       $to = MY->exescan();
+       print "exescan($from) => '$to'" if ($Verbose >=2);
+       $fromto{$from}=$to;
+    }
+    @to   = values %fromto;
+    push(@m, "
+EXE_FILES = @{$att{EXE_FILES}}
+
+all :: @to
+
+realclean ::
+       $att{RM_F} @to
+");
+
+    while (($from,$to) = each %fromto) {
+       push @m, "
+$to: $from $att{MAKEFILE}
+       $att{CP} $from $to
+";
+    }
+    join "", @m;
+}
 
+sub exescan {
+    $_;
+}
 # --- Sub-directory Sections ---
 
 sub subdirs {
@@ -1384,6 +1575,7 @@ all :: subdirs
 sub runsubdirpl{       # Experimental! See subdir_x section
     my($self,$subdir) = @_;
     chdir($subdir) or die "chdir($subdir): $!";
+    ExtUtils::MakeMaker::check_hints();
     require "Makefile.PL";
 }
 
@@ -1396,14 +1588,16 @@ sub subdir_x {
     # If this does not suit your needs you'll need to write your own
     # MY::subdir_x() method to override this one.
     qq{
-config :: $subdir/Makefile
-       cd $subdir ; \$(MAKE) config INST_LIB=\$(INST_LIB) INST_ARCHLIB=\$(INST_ARCHLIB)  LINKTYPE=\$(LINKTYPE)
+config :: $subdir/$att{MAKEFILE}
+       cd $subdir ; \$(MAKE) config INST_LIB=\$(INST_LIB) INST_ARCHLIB=\$(INST_ARCHLIB)  \\
+               INST_EXE=\$(INST_EXE) LINKTYPE=\$(LINKTYPE) LIBPERL_A=\$(LIBPERL_A) \$(SUBDIR_MAKEFILE_PL_ARGS)
 
-$subdir/Makefile: $subdir/Makefile.PL \$(CONFIGDEP)
+$subdir/$att{MAKEFILE}: $subdir/Makefile.PL \$(CONFIGDEP)
 }.'    @echo "Rebuilding $@ ..."
        $(PERL) $(I_PERL_LIBS) \\
                -e "use ExtUtils::MakeMaker; MM->runsubdirpl(qw('.$subdir.'))" \\
-               INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) $(SUBDIR_MAKEFILE_PL_ARGS)
+               INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) \\
+               INST_EXE=$(INST_EXE) LINKTYPE=\$(LINKTYPE) LIBPERL_A=$(LIBPERL_A) $(SUBDIR_MAKEFILE_PL_ARGS)
        @echo "Rebuild of $@ complete."
 '.qq{
 
@@ -1426,13 +1620,14 @@ sub clean {
 clean ::
 ');
     # clean subdirectories first
-    push(@m, map("\t-cd $_ && test -f Makefile && \$(MAKE) clean\n",@{$att{DIR}}));
+    push(@m, map("\t-cd $_ && test -f $att{MAKEFILE} && \$(MAKE) clean\n",@{$att{DIR}}));
     my(@otherfiles) = values %{$att{XS}}; # .c files from *.xs files
     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
+    push(@otherfiles, "./blib");
     push(@m, " -$att{RM_RF} *~ t/*~ *.o *.a mon.out core so_locations "
-                       ."\$(BOOTSTRAP) \$(BASEEXT).bso @otherfiles\n");
+                       ."\$(BOOTSTRAP) \$(BASEEXT).bso \$(BASEEXT).exp @otherfiles\n");
     # See realclean and ext/utils/make_ext for usage of Makefile.old
-    push(@m, " -$att{MV} Makefile Makefile.old 2>/dev/null\n");
+    push(@m, " -$att{MV} $att{MAKEFILE} $att{MAKEFILE}.old 2>/dev/null\n");
     push(@m, " $attribs{POSTOP}\n")   if $attribs{POSTOP};
     join("", @m);
 }
@@ -1447,13 +1642,14 @@ realclean purge ::  clean
     # realclean subdirectories first (already cleaned)
     $sub = "\t-cd %s && test -f %s && \$(MAKE) %s realclean\n";
     foreach(@{$att{DIR}}){
-       push(@m, sprintf($sub,$_,'Makefile.old','-f Makefile.old'));
-       push(@m, sprintf($sub,$_,'Makefile',''));
+       push(@m, sprintf($sub,$_,"$att{MAKEFILE}.old","-f $att{MAKEFILE}.old"));
+       push(@m, sprintf($sub,$_,"$att{MAKEFILE}",''));
     }
     push(@m, " $att{RM_RF} \$(INST_AUTODIR) \$(INST_ARCHAUTODIR)\n");
     push(@m, " $att{RM_F} \$(INST_DYNAMIC) \$(INST_BOOT)\n");
     push(@m, " $att{RM_F} \$(INST_STATIC) \$(INST_PM)\n");
-    my(@otherfiles) = qw(Makefile Makefile.old); # Makefiles last
+    my(@otherfiles) = ($att{MAKEFILE}, 
+                      "$att{MAKEFILE}.old"); # Makefiles last
     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
     push(@m, " $att{RM_RF} @otherfiles\n") if @otherfiles;
     push(@m, " $attribs{POSTOP}\n")       if $attribs{POSTOP};
@@ -1469,7 +1665,7 @@ sub distclean {
     my($compress) = $attribs{COMPRESS} || 'compress'; # eg gzip
     my($preop)    = $attribs{PREOP}  || '@:'; # e.g., update MANIFEST
     my($postop)   = $attribs{POSTOP} || '@:';
-    my($mkfiles)  = join(' ', map("$_/Makefile", ".", @{$att{DIR}}));
+    my($mkfiles)  = join(' ', map("$_/$att{MAKEFILE} $_/$att{MAKEFILE}.old", ".", @{$att{DIR}}));
     "
 distclean:     clean
        $preop
@@ -1488,15 +1684,18 @@ sub test {
     my($tests) = $attribs{TESTS} || (-d "t" ? "t/*.t" : "");
     my(@m);
     push(@m,"
+TEST_VERBOSE=0
+
 test :: all
 ");
     push(@m, <<"END") if $tests;
-       \$(FULLPERL) -I\$(INST_ARCHLIB) -I\$(INST_LIB) -I\$(PERL_ARCHLIB) -I\$(PERL_LIB) -e 'use Test::Harness; runtests \@ARGV;' $tests
+       \$(FULLPERL) -I\$(INST_ARCHLIB) -I\$(INST_LIB) -I\$(PERL_ARCHLIB) -I\$(PERL_LIB) -e 'use Test::Harness qw(&runtests \$\$verbose); \$\$verbose=\$(TEST_VERBOSE); runtests \@ARGV;' $tests
 END
     push(@m, <<'END') if -f "test.pl";
-       $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) $(I_PERL_LIBS) test.pl
+       $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) test.pl
 END
-    push(@m, map("\tcd $_ && test -f Makefile && \$(MAKE) test LINKTYPE=\$(LINKTYPE)\n",@{$att{DIR}}));
+    push(@m, map("\tcd $_ && test -f $att{MAKEFILE} && \$(MAKE) test LINKTYPE=\$(LINKTYPE)\n",
+                @{$att{DIR}}));
     push(@m, "\t\@echo 'No tests defined for \$(NAME) extension.'\n") unless @m > 1;
     join("", @m);
 }
@@ -1505,15 +1704,25 @@ END
 sub install {
     my($self, %attribs) = @_;
     my(@m);
+    push @m, q{
+doc_install ::
+       @ $(PERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB)  \\
+               -e 'use ExtUtils::MakeMaker; MM->writedoc("Module", "$(NAME)", \\
+               "LINKTYPE=$(LINKTYPE)", "VERSION=$(VERSION)", "EXE_FILES=$(EXE_FILES)")'
+};
+
     push(@m, "
-install :: all
+install :: pure_install doc_install
+
+pure_install :: all
 ");
     # install subdirectories first
-    push(@m, map("\tcd $_ && test -f Makefile && \$(MAKE) install\n",@{$att{DIR}}));
+    push(@m, map("\tcd $_ && test -f $att{MAKEFILE} && \$(MAKE) install\n",@{$att{DIR}}));
 
     push(@m, "\t: perl5.000 and MM pre 3.8 autosplit into INST_ARCHLIB, we delete these old files here
-       $att{RM_F} \$(INSTALLARCHLIB)/auto/\$(FULLEXT)/*.al \$(INSTALLARCHLIB)/auto/\$(FULLEXT)/*.ix
-       \$(MAKE) INST_LIB=\$(INSTALLPRIVLIB) INST_ARCHLIB=\$(INSTALLARCHLIB)
+       $att{RM_F} $Config{'installarchlib'}/auto/\$(FULLEXT)/*.al
+       $att{RM_F} $Config{'installarchlib'}/auto/\$(FULLEXT)/*.ix
+       \$(MAKE) INST_LIB=$Config{'installprivlib'} INST_ARCHLIB=$Config{'installarchlib'} INST_EXE=$Config{'installbin'}
 ");
 
     join("",@m);
@@ -1550,10 +1759,9 @@ $(OBJECT) : $(PERL_HDRS)
 $(PERL_INC)/config.h: $(PERL_SRC)/config.sh
        -@echo "Warning: $(PERL_INC)/config.h out of date with $(PERL_SRC)/config.sh"; false
 
-# An out of date Config.pm is fatal.
 $(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh
-       @echo "$(PERL_ARCHLIB)/Config.pm out of date with $(PERL_SRC)/config.sh"
-       @false
+       @echo "Warning: $(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh"
+       cd $(PERL_SRC); $(MAKE) lib/Config.pm
 ') if $att{PERL_SRC};
 
     push(@m, join(" ", values %{$att{XS}})." : \$(XSUBPPDEPS)\n")
@@ -1567,15 +1775,15 @@ sub makefile {
     # must force a manual rerun to be sure. But as it should only
     # happen very rarely it is not a significant problem.
     '
-$(OBJECT) : Makefile
+$(OBJECT) : '.$att{MAKEFILE}.'
 
 # We take a very conservative approach here, but it\'s worth it.
 # We move Makefile to Makefile.old here to avoid gnu make looping.
-Makefile:      Makefile.PL $(CONFIGDEP) 
+'.$att{MAKEFILE}.':    Makefile.PL $(CONFIGDEP)
        @echo "Makefile out-of-date with respect to $?"
        @echo "Cleaning current config before rebuilding Makefile..."
-       -@mv Makefile Makefile.old
-       -$(MAKE) -f Makefile.old clean >/dev/null 2>&1 || true
+       -@mv '."$att{MAKEFILE} $att{MAKEFILE}.old".'
+       -$(MAKE) -f '.$att{MAKEFILE}.'.old clean >/dev/null 2>&1 || true
        $(PERL) $(I_PERL_LIBS) Makefile.PL
        @echo "Now you must rerun make."; false
 ';
@@ -1586,62 +1794,148 @@ sub postamble{
     "";
 }
 
+# --- Make-A-Perl section ---
 
-# --- Determine libraries to use and how to use them ---
+sub staticmake {
+    my($self, %attribs) = @_;
 
-sub extliblist{
-    my($self, $libs) = @_;
-    return ("", "", "") unless $libs;
-    print STDERR "Potential libraries are '$libs':" if $Verbose;
-    my(@new) = MY->new_extliblist($libs);
-
-    if ($att{PERL_SRC}){
-       my(@old) = MY->old_extliblist($libs);
-       my($oldlibs) = join(" : ",@old);
-       my($newlibs) = join(" : ",@new);
-       warn "Warning (non-fatal): $att{NAME} extliblist consistency check failed:\n".
-           "  old: $oldlibs\n".
-           "  new: $newlibs\n".
-           "Using 'new' set. Please notify perl5-porters\@nicoh.com.\n"
-               if ("$newlibs" ne "$oldlibs");
-    }
-    @new;
+    my(%searchdirs)=($att{PERL_ARCHLIB} => 1,  $att{INST_ARCHLIB} => 1);
+    my(@searchdirs)=keys %searchdirs;
+    # And as it's not yet built, we add the current extension
+    my(@static)="$att{INST_ARCHLIB}/auto/$att{FULLEXT}/$att{BASEEXT}.a";
+    my(@perlinc) = ($att{INST_ARCHLIB}, $att{INST_LIB}, $att{PERL_ARCHLIB}, $att{PERL_LIB});
+    MY->makeaperl('MAKE' => $att{MAKEFILE}, 
+                            'DIRS' => \@searchdirs, 
+                            'STAT' => \@static, 
+                            'INCL' => \@perlinc,
+                            'TARGET' => $att{MAP_TARGET},
+                            'TMP' => "",
+                            'LIBPERL' => $att{LIBPERL_A}
+                            );
 }
 
+sub makeaperl {
+    my($self, %attribs) = @_;
+    my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
+      @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
+    my(@m);
+    my($cccmd, $linkcmd);
+
+    # This emulates cflags to get the compiler invocation...
+    $cccmd = MY->const_cccmd($libperl);
+    $cccmd =~ s/^CCCMD\s*=\s*//;
+    chomp $cccmd;
+    $cccmd =~ s/\s/ -I$att{PERL_INC} /;
+    $cccmd .= " $Config{'cccdlflags'}" if ($Config{'d_shrplib'});
+
+    # The front matter of the linkcommand...
+    $linkcmd = join ' ', $Config{'cc'},
+           grep($_, @Config{qw(large split ldflags ccdlflags)});
+    $linkcmd =~ s/\s+/ /g;
+
+    # Which *.a files could we make use of...
+    local(%static);
+    File::Find::find(sub {
+       return unless m/\.a$/;
+       return if m/^libperl/;
+       $static{fastcwd() . "/" . $_}++;
+    }, grep( -d $_, @{$searchdirs || []}) );
+
+    # We trust that what has been handed in as argument, will be buildable
+    $static = [] unless $static;
+    @static{@{$static}} = (1) x @{$static};
+
+    $extra = [] unless $extra && ref $extra eq 'ARRAY';
+    for (sort keys %static) {
+       next unless /\.a$/;
+       $_ = dirname($_) . "/extralibs.ld";
+       push @$extra, "`cat $_`";
+    }
 
-sub old_extliblist {
-    my($self, $potential_libs)=@_;
-    return ("", "", "") unless $potential_libs;
-    die "old_extliblist requires PERL_SRC" unless $att{PERL_SRC};
-
-    my(%attrib, @w);
-    # Now run ext/util/extliblist to discover what *libs definitions
-    # are required for the needs of $potential_libs
-    $ENV{'potential_libs'} = $potential_libs;
-    my(@o)=`. $att{PERL_SRC}/config.sh
-           . $att{PERL_SRC}/ext/util/extliblist;
-           echo EXTRALIBS=\$extralibs
-           echo BSLOADLIBS=\$dynaloadlibs
-           echo LDLOADLIBS=\$statloadlibs
-           `;
-    foreach $line (@o){
-       chomp $line;
-       if ($line =~ /(.*)\s*=\s*(.*)\s*$/){
-           $attrib{$1} = $2;
-           print STDERR "      $1 = $2" if $Verbose;
-       }else{
-           push(@w, $line);
+    grep(s/^/-I/, @$perlinc);
+
+    $target = "perl" unless $target;
+    $tmp = "." unless $tmp;
+
+    push @m, "
+# --- MakeMaker makeaperl section ---
+MAP_TARGET    = $target
+FULLPERL      = $att{'FULLPERL'}
+MAP_LINKCMD   = $linkcmd
+MAP_PERLINC   = @{$perlinc}
+MAP_STATIC    = ",
+join(" ", sort keys %static), "
+MAP_EXTRA     = @{$extra}
+MAP_PRELIBS   = $Config{'libs'} $Config{'cryptlib'}
+";
+    if ($libperl) {
+       unless (-f $libperl || -f ($libperl = "$Config{'installarchlib'}/CORE/$libperl")){
+           print STDOUT "Warning: $libperl not found";
+           undef $libperl;
        }
     }
-    print STDERR "Messages from extliblist:\n", join("\n",@w,'')
-       if @w ;
-    @attrib{qw(EXTRALIBS BSLOADLIBS LDLOADLIBS)};
+    unless ($libperl) {
+       if (defined $att{PERL_SRC}) {
+           $libperl = "$att{PERL_SRC}/libperl.a";
+       } elsif ( -f ( $libperl = "$Config{'installarchlib'}/CORE/libperl.a" )) {
+       } else {
+           print STDOUT "Warning: $libperl not found";
+       }
+    }
+
+    push @m, "
+MAP_LIBPERL = $libperl
+";
+
+    push @m, "
+\$(MAP_TARGET): $tmp/perlmain.o \$(MAP_LIBPERL) \$(MAP_STATIC)
+       \$(MAP_LINKCMD) -o \$\@ $tmp/perlmain.o \$(MAP_LIBPERL) \$(MAP_STATIC) \$(MAP_EXTRA) \$(MAP_PRELIBS)
+       @ echo 'To install the new \"\$(MAP_TARGET)\" binary, call'
+       @ echo '    make -f $makefilename inst_perl MAP_TARGET=\$(MAP_TARGET)'
+       @ echo 'To remove the intermediate files say'
+       @ echo '    make -f $makefilename map_clean'
+
+$tmp/perlmain.o: $tmp/perlmain.c
+";
+    push @m, "\tcd $tmp && $cccmd perlmain.c\n";
+
+    push @m, qq{
+$tmp/perlmain.c: $makefilename}, q{
+       @ echo Writing $@
+       @ $(FULLPERL) $(MAP_PERLINC) -e 'use ExtUtils::Miniperl; \\
+               writemain(grep s#.*/auto/##, qw|$(MAP_STATIC)|)' > $@.tmp && mv $@.tmp $@
+
+};
+
+# We write MAP_EXTRA outside the perl program to have it eval'd by the shell
+    push @m, q{
+doc_inst_perl:
+       @ $(FULLPERL) -e 'use ExtUtils::MakeMaker; MM->writedoc("Perl binary", \\
+               "$(MAP_TARGET)", "MAP_STATIC=$(MAP_STATIC)", \\
+               "MAP_EXTRA=@ARGV", "MAP_LIBPERL=$(MAP_LIBPERL)")' -- $(MAP_EXTRA)
+};
+
+    push @m, qq{
+inst_perl: pure_inst_perl doc_inst_perl
+
+pure_inst_perl: \$(MAP_TARGET)
+       $att{CP} \$(MAP_TARGET) $Config{'installbin'}/\$(MAP_TARGET)
+
+realclean :: map_clean
+
+map_clean :
+       $att{RM_F} $tmp/perlmain.o $tmp/perlmain.c $makefilename
+};
+
+    join '', @m;
 }
 
+# --- Determine libraries to use and how to use them ---
 
-sub new_extliblist {
+sub extliblist{
     my($self, $potential_libs)=@_;
     return ("", "", "") unless $potential_libs;
+    print STDOUT "Potential libraries are '$potential_libs':" if $Verbose;
 
     my($so)   = $Config{'so'};
     my($libs) = $Config{'libs'};
@@ -1653,11 +1947,10 @@ sub new_extliblist {
 
     my(@searchpath); # from "-L/path" entries in $potential_libs
     my(@libpath) = split " ", $Config{'libpth'};
-    my(@ldloadlibs);
-    my(@bsloadlibs);
-    my(@extralibs);
-    my($fullname);
+    my(@ldloadlibs, @bsloadlibs, @extralibs);
+    my($fullname, $thislib, $thispth, @fullname);
     my($pwd) = fastcwd(); # from Cwd.pm
+    my($found) = 0;
 
     foreach $thislib (split ' ', $potential_libs){
 
@@ -1665,12 +1958,12 @@ sub new_extliblist {
        if ($thislib =~ s/^(-[LR])//){  # save path flag type
            my($ptype) = $1;
            unless (-d $thislib){
-               warn "$ptype$thislib ignored, directory does not exist\n"
+               print STDOUT "$ptype$thislib ignored, directory does not exist\n"
                        if $Verbose;
                next;
            }
            if ($thislib !~ m|^/|) {
-             warn "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n";
+             print STDOUT "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n";
              $thislib = "$pwd/$thislib";
            }
            push(@searchpath, $thislib);
@@ -1681,25 +1974,33 @@ sub new_extliblist {
 
        # Handle possible library arguments.
        unless ($thislib =~ s/^-l//){
-         warn "Unrecognized argument in LIBS ignored: '$thislib'\n";
+         print STDOUT "Unrecognized argument in LIBS ignored: '$thislib'\n";
          next;
        }
 
        my($found_lib)=0;
        foreach $thispth (@searchpath, @libpath){
 
+               # Try to find the full name of the library.  We need this to
+               # determine whether it's a dynamically-loadable library or not.
+               # This tends to be subject to various os-specific quirks.
+               # For gcc-2.6.2 on linux (March 1995), DLD can not load
+               # .sa libraries, with the exception of libm.sa, so we
+               # deliberately skip them.
            if (@fullname=<${thispth}/lib${thislib}.${so}.[0-9]*>){
                $fullname=$fullname[-1]; #ATTN: 10 looses against 9!
-           } elsif (-f ($fullname="$thispth/lib$thislib.$so")){
-          } elsif (-f ($fullname="$thispth/lib${thislib}_s.a")
-              && ($thislib .= "_s") ){ # we must explicitly ask for _s version
+           } elsif (-f ($fullname="$thispth/lib$thislib.$so")
+                    && (($Config{'dlsrc'} ne "dl_dld.xs") || ($thislib eq "m"))){
+           } elsif (-f ($fullname="$thispth/lib${thislib}_s.a")
+                    && ($thislib .= "_s") ){ # we must explicitly ask for _s version
            } elsif (-f ($fullname="$thispth/lib$thislib.a")){
            } elsif (-f ($fullname="$thispth/Slib$thislib.a")){
-           } else { 
-               warn "$thislib not found in $thispth\n" if $Verbose;
+           } else {
+               print STDOUT "$thislib not found in $thispth" if $Verbose;
                next;
            }
-           warn "'-l$thislib' found at $fullname\n" if $Verbose;
+           print STDOUT "'-l$thislib' found at $fullname" if $Verbose;
+           $found++;
            $found_lib++;
 
            # Now update library lists
@@ -1714,7 +2015,7 @@ sub new_extliblist {
            unless ( $in_perl || ($Config{'osname'} eq 'next' && $thislib eq 'm') ){
                push(@extralibs, "-l$thislib");
            }
-                       
+
 
            # We might be able to load this archive file dynamically
            if ( $Config{'dlsrc'} =~ /dl_next|dl_dld/){
@@ -1722,8 +2023,9 @@ sub new_extliblist {
                # it avoids hardwiring a fixed path into the .bs file.
                # mkbootstrap will automatically add dl_findfile() to
                # the .bs file if it sees a name in the -l format.
-               # USE THIS LATER: push(@bsloadlibs, "-l$thislib"); # " $fullname";
-               # USE THIS while checking results against old_extliblist
+               # USE THIS, when dl_findfile() is fixed: 
+               # push(@bsloadlibs, "-l$thislib");
+               # OLD USE WAS while checking results against old_extliblist
                push(@bsloadlibs, "$fullname");
            } else {
                if ($is_dyna){
@@ -1737,8 +2039,9 @@ sub new_extliblist {
            }
            last;       # found one here so don't bother looking further
        }
-       warn "Warning (non-fatal): No library found for -l$thislib\n" unless $found_lib>0;
+       print STDOUT "Warning (non-fatal): No library found for -l$thislib" unless $found_lib>0;
     }
+    return ('','','') unless $found;
     ("@extralibs", "@bsloadlibs", "@ldloadlibs");
 }
 
@@ -1747,39 +2050,32 @@ sub new_extliblist {
 
 sub mkbootstrap {
 
-=head1 NAME
-
-mkbootstrap
+=head1 USEFUL SUBROUTINES
 
-=head1 DESCRIPTION
+=head2 mkbootstrap()
 
-Make a bootstrap file for use by this system's DynaLoader.
-It typically gets called from an extension Makefile.
+Make a bootstrap file for use by this system's DynaLoader.  It
+typically gets called from an extension Makefile.
 
-There is no .bs file supplied with the extension. Instead a _BS file
-which has code for the special cases, like posix for berkeley db on the
-NeXT.
+There is no C<*.bs> file supplied with the extension. Instead a
+C<*_BS> file which has code for the special cases, like posix for
+berkeley db on the NeXT.
 
 This file will get parsed, and produce a maybe empty
-@DynaLoader::dl_resolve_using array for the current architecture.
+C<@DynaLoader::dl_resolve_using> array for the current architecture.
 That will be extended by $BSLOADLIBS, which was computed by Andy's
 extliblist script. If this array still is empty, we do nothing, else
-we write a .bs file with an @DynaLoader::dl_resolve_using array, but
+we write a .bs file with an C<@DynaLoader::dl_resolve_using> array, but
 without any C<if>s, because there is no longer a need to deal with
 special cases.
 
-The _BS file can put some code into the generated .bs file by placing
-it in $bscode. This is a handy 'escape' mechanism that may prove
+The C<*_BS> file can put some code into the generated C<*.bs> file by placing
+it in C<$bscode>. This is a handy 'escape' mechanism that may prove
 useful in complex situations.
 
 If @DynaLoader::dl_resolve_using contains C<-L*> or C<-l*> entries then
 mkbootstrap will automatically add a dl_findfile() call to the
-generated .bs file.
-
-=head1 AUTHORS
-
-Andreas Koenig <k@otto.ww.TU-Berlin.DE>, Tim Bunce
-<Tim.Bunce@ig.co.uk>, Andy Dougherty <doughera@lafcol.lafayette.edu>
+generated C<*.bs> file.
 
 =cut
 
@@ -1787,7 +2083,7 @@ Andreas Koenig <k@otto.ww.TU-Berlin.DE>, Tim Bunce
 
     @bsloadlibs = grep($_, @bsloadlibs); # strip empty libs
 
-    print STDERR "     bsloadlibs=@bsloadlibs\n" if $Verbose;
+    print STDOUT "     bsloadlibs=@bsloadlibs\n" if $Verbose;
 
     # We need DynaLoader here because we and/or the *_BS file may
     # call dl_findfile(). We don't say `use' here because when
@@ -1840,26 +2136,154 @@ Andreas Koenig <k@otto.ww.TU-Berlin.DE>, Tim Bunce
        print BS "\n1;\n";
        close BS;
     }
+}
+
+sub mksymlists {
+    my($self) = shift;
 
-    # special handling for systems which needs a list of all global
-    # symbols exported by a modules to be dynamically linked.
-    if ($Config{'dlsrc'} =~ /^dl_aix/){
-       my($bootfunc);
-       ($bootfunc = $att{NAME}) =~ s/\W/_/g;
-       open EXP, ">$att{BASEEXT}.exp";
-       print EXP "#!\nboot_$bootfunc\n";
-       close EXP;
+    # only AIX requires a symbol list at this point
+    # (so does VMS, but that's handled by the MM_VMS package)
+    return '' unless $Config{'osname'} eq 'aix';
+
+    init_main(@ARGV) unless defined $att{'BASEEXT'};
+    if (! $att{DL_FUNCS}) {
+       my($bootfunc);
+       ($bootfunc = $att{NAME}) =~ s/\W/_/g;
+       $att{DL_FUNCS} = {$att{BASEEXT} => ["boot_$bootfunc"]};
+    }
+    rename "$att{BASEEXT}.exp", "$att{BASEEXT}.exp_old";
+
+    open(EXP,">$att{BASEEXT}.exp") or die $!;
+    print EXP join("\n",@{$att{DL_VARS}}) if $att{DL_VARS};
+    foreach $pkg (keys %{$att{DL_FUNCS}}) {
+        (my($prefix) = $pkg) =~ s/\W/_/g;
+        foreach $func (@{$att{DL_FUNCS}->{$pkg}}) {
+            $func = "XS_${prefix}_$func" unless $func =~ /^boot_/;
+            print EXP "$func\n";
+        }
     }
+    close EXP;
 }
 
-
 # --- Output postprocessing section ---
 #nicetext is included to make VMS support easier
 sub nicetext { # Just return the input - no action needed
     my($self,$text) = @_;
     $text;
 }
+
+# --- perllocal.pod section ---
+sub writedoc {
+    my($self,$what,$name,@attribs)=@_;
+    -w $Config{'installarchlib'} or die "No write permission to $Config{'installarchlib'}";
+    my($localpod) = "$Config{'installarchlib'}/perllocal.pod";
+    my($time);
+    if (-f $localpod) {
+       print "Appending installation info to $localpod\n";
+       open POD, ">>$localpod" or die "Couldn't open $localpod";
+    } else {
+       print "Writing new file $localpod\n";
+       open POD, ">$localpod" or die "Couldn't open $localpod";
+       print POD "=head1 NAME
+
+perllocal - locally installed modules and perl binaries
+\n=head1 HISTORY OF LOCAL INSTALLATIONS
+
+";
+    }
+    require "ctime.pl";
+    chop($time = ctime(time));
+    print POD "=head2 $time: $what C<$name>\n\n=over 4\n\n=item *\n\n";
+    print POD join "\n\n=item *\n\n", map("C<$_>",@attribs);
+    print POD "\n\n=back\n\n";
+    close POD;
+}
+
+=head1 AUTHORS
+
+Andy Dougherty F<E<lt>doughera@lafcol.lafayette.eduE<gt>>, Andreas
+Koenig F<E<lt>k@franz.ww.TU-Berlin.DEE<gt>>, Tim Bunce
+F<E<lt>Tim.Bunce@ig.co.ukE<gt>>.  VMS support by Charles Bailey
+F<E<lt>bailey@HMIVAX.HUMGEN.UPENN.EDUE<gt>>.
+
+=head1 MODIFICATION HISTORY
+
+v1, August 1994; by Andreas Koenig. Based on Andy Dougherty's Makefile.SH.
+v2, September 1994 by Tim Bunce.
+v3.0 October  1994 by Tim Bunce.
+v3.1 November 11th 1994 by Tim Bunce.
+v3.2 November 18th 1994 by Tim Bunce.
+v3.3 November 27th 1994 by Andreas Koenig.
+v3.4 December  7th 1994 by Andreas Koenig and Tim Bunce.
+v3.5 December 15th 1994 by Tim Bunce.
+v3.6 December 15th 1994 by Tim Bunce.
+v3.7 December 30th 1994 By Tim Bunce
+v3.8 January  17th 1995 By Andreas Koenig and Tim Bunce
+v3.9 January 19th 1995 By Tim Bunce
+v3.10 January 23rd 1995 By Tim Bunce
+v3.11 January 24th 1995 By Andreas Koenig
+v4.00 January 24th 1995 By Tim Bunce
+v4.01 January 25th 1995 By Tim Bunce
+v4.02 January 29th 1995 By Andreas Koenig
+v4.03 January 30th 1995 By Andreas Koenig
+v4.04 Februeary 5th 1995 By Andreas Koenig
+v4.05 February 8th 1995 By Andreas Koenig
+v4.06 February 10th 1995 By Andreas Koenig
+
+Cleaning up the new interface. Suggestion to freeze now until 5.001.
+
+v4.061 February 12th 1995 By Andreas Koenig
+
+Fixes of some my() declarations and of @extra computing in makeaperl().
+
+v4.08 - 4.085  February 14th-21st 1995 by Andreas Koenig
+
+Introduces EXE_FILES and INST_EXE for installing executable scripts 
+and fixes documentation to reflect the new variable.
+
+Introduces the automated documentation of the installation history. Every
+  make install
+and
+  make inst_perl
+add some documentation to the file C<$installarchlib/perllocal.pod>.
+This is done by the writedoc() routine in the MM_Unix class. The
+documentation is rudimentary until we find an agreement, what 
+information is supposed to go into the pod.
+
+Added ability to specify the another name than C<perl> for a new binary.
+
+Both C<make perl> and C<makeaperl> now prompt the user, how to install
+the new binary after the build.
+
+Reduced noise during the make.
+
+Variable LIBPERL_A enables indirect setting of the switches -DEMBED,
+-DDEBUGGING and -DMULTIPLICITY in the same way as done by cflags.
+
+old_extliblist() code deleted, new_extliblist() renamed to extliblist().
+
+Improved algorithm in extliblist, that returns ('','','') if no
+library has been found, even if a -L directory has been found.
+
+Fixed a bug that didn't allow lib/ directory work as documented.
+
+Allowed C<make test TEST_VERBOSE=1>
+
+v4.086 March 9 1995 by Andy Dougherty
+
+Fixed some AIX buglets.  Fixed DLD support for Linux with gcc 2.6.2.
+
+=head1 NOTES
+
+MakeMaker development work still to be done:
+
+Needs more complete documentation.
+
+Add a html: target when there has been found a general solution to
+installing html files.
+
+=cut
+
 # the following keeps AutoSplit happy
 package ExtUtils::MakeMaker;
 1;