MM_Unix.pm : work around File::Find problem on VMS
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / MakeMaker.pm
index e7b9571..901bd13 100644 (file)
@@ -1,11 +1,11 @@
-BEGIN {require 5.004;}
-
 package ExtUtils::MakeMaker;
 
-$VERSION = "5.90_01";
+BEGIN {require 5.005_03;}
+
+$VERSION = "6.03";
 $Version_OK = "5.49";   # Makefiles older than $Version_OK will die
                         # (Will be checked from MakeMaker version 4.13 onwards)
-($Revision = substr(q$Revision: 1.37 $, 10)) =~ s/\s+$//;
+($Revision = substr(q$Revision: 1.63 $, 10)) =~ s/\s+$//;
 
 require Exporter;
 use Config;
@@ -34,18 +34,169 @@ full_setup();
 require ExtUtils::MM;  # Things like CPAN assume loading ExtUtils::MakeMaker
                        # will give them MM.
 
+require ExtUtils::MY;  # XXX pre-5.8 versions of ExtUtils::Embed expect
+                       # loading ExtUtils::MakeMaker will give them MY.
+                       # This will go when Embed is it's own CPAN module.
+
 
 sub WriteMakefile {
     Carp::croak "WriteMakefile: Need even number of args" if @_ % 2;
 
     require ExtUtils::MY;
     my %att = @_;
+
+    _verify_att(\%att);
+
     my $mm = MM->new(\%att);
     $mm->flush;
 
     return $mm;
 }
 
+
+# Basic signatures of the attributes WriteMakefile takes.  Each is the
+# reference type.  Empty value indicate it takes a non-reference
+# scalar.
+my %Att_Sigs =
+(
+ ABSTRACT           => '',
+ ABSTRACT_FROM      => '',
+ AUTHOR             => '',
+ BINARY_LOCATION    => '',
+ C                  => 'array',
+ CCFLAGS            => '',
+ CONFIG             => 'array',
+ CONFIGURE          => 'code',
+ DEFINE             => '',
+ DIR                => 'array',
+ DISTNAME           => '',
+ DL_FUNCS           => 'hash',
+ DL_VARS            => 'array',
+ EXCLUDE_EXT        => 'array',
+ EXE_FILES          => 'array',
+ FIRST_MAKEFILE     => '',
+ FULLPERL           => '',
+ FULLPERLRUN        => '',
+ FULLPERLRUNINST    => '',
+ FUNCLIST           => 'array',
+ H                  => 'array',
+ IMPORTS            => 'hash',
+ INC                => '',
+ INCLUDE_EXT        => 'array',
+ INSTALLARCHLIB     => '',
+ INSTALLBIN         => '',
+ INSTALLDIRS        => '',
+ INSTALLMAN1DIR     => '',
+ INSTALLMAN3DIR     => '',
+ INSTALLPRIVLIB     => '',
+ INSTALLSCRIPT      => '',
+ INSTALLSITEARCH    => '',
+ INSTALLSITEBIN     => '',
+ INSTALLSITELIB     => '',
+ INSTALLSITEMAN1DIR => '',
+ INSTALLSITEMAN3DIR => '',
+ INSTALLVENDORARCH  => '',
+ INSTALLVENDORBIN   => '',
+ INSTALLVENDORLIB   => '',
+ INSTALLVENDORMAN1DIR   => '',
+ INSTALLVENDORMAN3DIR   => '',
+ INST_ARCHLIB       => '',
+ INST_BIN           => '',
+ INST_LIB           => '',
+ INST_MAN1DIR       => '',
+ INST_MAN3DIR       => '',
+ INST_SCRIPT        => '',
+ _KEEP_AFTER_FLUSH  => '',
+ LDDLFLAGS          => '',
+ LDFROM             => '',
+ LIB                => '',
+ LIBPERL_A          => '',
+ LIBS               => ['array',''],
+ LINKTYPE           => '',
+ MAKEAPERL          => '',
+ MAKEFILE           => '',
+ MAN1PODS           => 'hash',
+ MAN3PODS           => 'hash',
+ MAP_TARGET         => '',
+ MYEXTLIB           => '',
+ NAME               => '',
+ NEEDS_LINKING      => '',
+ NOECHO             => '',
+ NORECURS           => '',
+ NO_VC              => '',
+ OBJECT             => '',
+ OPTIMIZE           => '',
+ PERL               => '',
+ PERL_CORE          => '',
+ PERLMAINCC         => '',
+ PERL_ARCHLIB       => '',
+ PERL_LIB           => '',
+ PERL_MALLOC_OK     => '',
+ PERLRUN            => '',
+ PERLRUNINST        => '',
+ PERL_SRC           => '',
+ PERM_RW            => '',
+ PERM_RWX           => '',
+ PL_FILES           => 'hash',
+ PM                 => 'hash',
+ PMLIBDIRS          => 'array',
+ PM_FILTER          => '',
+ POLLUTE            => '',
+ PPM_INSTALL_EXEC   => '',
+ PPM_INSTALL_SCRIPT => '',
+ PREFIX             => '',
+ PREREQ_FATAL       => '',
+ PREREQ_PM          => 'hash',
+ PREREQ_PRINT       => '',
+ PRINT_PREREQ       => '',
+ SITEPREFIX         => '',
+ SKIP               => 'array',
+ TYPEMAPS           => 'array',
+ VENDORPREFIX       => '',
+ VERBINST           => '',
+ VERSION            => '',
+ VERSION_FROM       => '',
+ XS                 => 'hash',
+ XSOPT              => '',
+ XSPROTOARG         => '',
+ XS_VERSION         => '',
+
+ clean      => 'hash',
+ depend     => 'hash',
+ dist       => 'hash',
+ dynamic_lib=> 'hash',
+ linkext    => 'hash',
+ macro      => 'hash',
+ realclean  => 'hash',
+ test       => 'hash',
+ tool_autosplit => 'hash',
+);
+
+
+sub _verify_att {
+    my($att) = @_;
+
+    while( my($key, $val) = each %$att ) {
+        my $sig = $Att_Sigs{$key};
+        unless( defined $sig ) {
+            warn "WARNING: $key is not a known parameter.\n";
+            next;
+        }
+
+        my @sigs   = ref $sig ? @$sig : $sig;
+        my $given = lc ref $val;
+        unless( grep $given eq $_, @sigs ) {
+            my $takes = join " or ", map { $_ ne '' ? "$_ reference"
+                                                    : "string/number"
+                                         } @sigs;
+            my $has   = $given ne '' ? "$given reference"
+                                     : "string/number";
+            warn "WARNING: $key takes a $takes not a $has.\n".
+                 "         Please inform the author.\n";
+        }
+    }
+}
+
 sub prompt ($;$) {
     my($mess,$def)=@_;
     $ISA_TTY = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ;   # Pipe?
@@ -75,7 +226,8 @@ sub prompt ($;$) {
 sub eval_in_subdirs {
     my($self) = @_;
     use Cwd qw(cwd abs_path);
-    my $pwd = cwd();
+    my $pwd = cwd() || die "Can't figure out your cwd!";
+
     local @INC = map eval {abs_path($_) if -e} || $_, @INC;
     push @INC, '.';     # '.' has to always be at the end of @INC
 
@@ -100,7 +252,7 @@ sub eval_in_x {
 #         } else {
 #             warn "WARNING from evaluation of $dir/Makefile.PL: $@";
 #         }
-        warn "WARNING from evaluation of $dir/Makefile.PL: $@";
+        die "ERROR from evaluation of $dir/Makefile.PL: $@";
     }
 }
 
@@ -117,12 +269,16 @@ sub full_setup {
     EXCLUDE_EXT EXE_FILES FIRST_MAKEFILE 
     FULLPERL FULLPERLRUN FULLPERLRUNINST
     FUNCLIST H IMPORTS
-    INST_ARCHLIB INST_SCRIPT INST_BIN INST_LIB
+    INST_ARCHLIB INST_SCRIPT INST_BIN INST_LIB INST_MAN1DIR INST_MAN3DIR
     INSTALLDIRS
     PREFIX          SITEPREFIX      VENDORPREFIX
     INSTALLPRIVLIB  INSTALLSITELIB  INSTALLVENDORLIB
     INSTALLARCHLIB  INSTALLSITEARCH INSTALLVENDORARCH
-    INSTALLBIN      INSTALLSITEBIN  INSTALLVENDORBIN  INSTALLSCRIPT 
+    INSTALLBIN      INSTALLSITEBIN  INSTALLVENDORBIN
+    INSTALLMAN1DIR          INSTALLMAN3DIR
+    INSTALLSITEMAN1DIR      INSTALLSITEMAN3DIR
+    INSTALLVENDORMAN1DIR    INSTALLVENDORMAN3DIR
+    INSTALLSCRIPT 
     PERL_LIB        PERL_ARCHLIB 
     SITELIBEXP      SITEARCHEXP 
     INC INCLUDE_EXT LDFROM LIB LIBPERL_A LIBS
@@ -281,7 +437,7 @@ sub new {
                    unless $self->{PREREQ_FATAL};
             $unsatisfied{$prereq} = 'not installed';
         } elsif ($pr_version < $self->{PREREQ_PM}->{$prereq} ){
-            warn "Warning: prerequisite %s %s not found. We have %s.\n",
+            warn sprintf "Warning: prerequisite %s %s not found. We have %s.\n",
               $prereq, $self->{PREREQ_PM}{$prereq}, 
                 ($pr_version || 'unknown version') 
                   unless $self->{PREREQ_FATAL};
@@ -489,7 +645,7 @@ sub WriteEmptyMakefile {
     rename $self->{MAKEFILE}, "$self->{MAKEFILE}.old"
       or warn "rename $self->{MAKEFILE} $self->{MAKEFILE}.old: $!"
         if -f $self->{MAKEFILE};
-    open MF, '>', $self->{MAKEFILE} or die "open $self->{MAKEFILE} for write: $!";
+    open MF, '>'.$self->{MAKEFILE} or die "open $self->{MAKEFILE} for write: $!";
     print MF <<'EOP';
 all:
 
@@ -615,7 +771,7 @@ sub check_hints {
 }
 
 sub _run_hintfile {
-    our $self;
+    no strict 'vars';
     local($self) = shift;       # make $self available to the hint file.
     my($hint_file) = shift;
 
@@ -637,7 +793,10 @@ sub mv_all_methods {
     # still trying to reduce the list to some reasonable minimum --
     # because I want to make it easier for the user. A.K.
 
-    no warnings 'redefine';
+    local $SIG{__WARN__} = sub { 
+        # can't use 'no warnings redefined', 5.6 only
+        warn @_ unless $_[0] =~ /^Subroutine .* redefined/ 
+    };
     foreach my $method (@Overridable) {
 
         # We cannot say "next" here. Nick might call MY->makeaperl
@@ -712,21 +871,16 @@ sub skipcheck {
 sub flush {
     my $self = shift;
     my($chunk);
-#    use FileHandle ();
-#    my $fh = new FileHandle;
     local *FH;
     print STDOUT "Writing $self->{MAKEFILE} for $self->{NAME}\n";
 
     unlink($self->{MAKEFILE}, "MakeMaker.tmp", $Is_VMS ? 'Descrip.MMS' : '');
-#    $fh->open(">MakeMaker.tmp") or die "Unable to open MakeMaker.tmp: $!";
     open(FH,">MakeMaker.tmp") or die "Unable to open MakeMaker.tmp: $!";
 
     for $chunk (@{$self->{RESULT}}) {
-#       print $fh "$chunk\n";
         print FH "$chunk\n";
     }
 
-#    $fh->close;
     close FH;
     my($finalname) = $self->{MAKEFILE};
     rename("MakeMaker.tmp", $finalname);
@@ -878,14 +1032,17 @@ Other interesting targets in the generated Makefile are
 =head2 make test
 
 MakeMaker checks for the existence of a file named F<test.pl> in the
-current directory and if it exists it adds commands to the test target
-of the generated Makefile that will execute the script with the proper
-set of perl C<-I> options.
+current directory and if it exists it execute the script with the
+proper set of perl C<-I> options.
 
 MakeMaker also checks for any files matching glob("t/*.t"). It will
-add commands to the test target of the generated Makefile that execute
-all matching files via the L<Test::Harness> module with the C<-I>
-switches set correctly.
+execute all matching files in alphabetical order via the
+L<Test::Harness> module with the C<-I> switches set correctly.
+
+If you'd like to see the raw output of your tests, set the
+C<TEST_VERBOSE> variable to true.
+
+  make test TEST_VERBOSE=1
 
 =head2 make testdb
 
@@ -893,13 +1050,13 @@ A useful variation of the above is the target C<testdb>. It runs the
 test under the Perl debugger (see L<perldebug>). If the file
 F<test.pl> exists in the current directory, it is used for the test.
 
-If you want to debug some other testfile, set C<TEST_FILE> variable
+If you want to debug some other testfile, set the C<TEST_FILE> variable
 thusly:
 
   make testdb TEST_FILE=t/mytest.t
 
 By default the debugger is called using C<-d> option to perl. If you
-want to specify some other option, set C<TESTDB_SW> variable:
+want to specify some other option, set the C<TESTDB_SW> variable:
 
   make testdb TESTDB_SW=-Dx
 
@@ -1127,8 +1284,8 @@ recommends it (or you know what you're doing).
 
 =head2 Using Attributes and Parameters
 
-The following attributes can be specified as arguments to WriteMakefile()
-or as NAME=VALUE pairs on the command line:
+The following attributes may be specified as arguments to WriteMakefile()
+or as NAME=VALUE pairs on the command line.
 
 =over 2
 
@@ -1282,7 +1439,9 @@ Ref to array of *.h file names. Similar to C.
 =item IMPORTS
 
 This attribute is used to specify names to be imported into the
-extension. It is only used on OS/2 and Win32.
+extension. Takes a hash ref.
+
+It is only used on OS/2 and Win32.
 
 =item INC
 
@@ -1417,9 +1576,17 @@ Directory, where executable files should be installed during
 testing. make install will copy the files in INST_SCRIPT to
 INSTALLSCRIPT.
 
+=item LDDLFLAGS
+
+Any special flags that might need to be passed to ld to create a
+shared library suitable for dynamic loading.  It is up to the makefile
+to use it.  (See L<Config/lddlflags>)
+
+Defaults to $Config{lddlflags}.
+
 =item LDFROM
 
-defaults to "$(OBJECT)" and is used in the ld command to specify
+Defaults to "$(OBJECT)" and is used in the ld command to specify
 what files to link/load from (also see dynamic_lib below for how to
 specify ld flags)
 
@@ -1717,13 +1884,6 @@ by the PREFIX.
 
 Defaults to $Config{installprefixexp}.
 
-=item PREREQ_PM
-
-Hashref: Names of modules that need to be available to run this
-extension (e.g. Fcntl for SDBM_File) are the keys of the hash and the
-desired version is the value. If the required version number is 0, we
-only check if any version is installed already.
-
 =item PREREQ_FATAL
 
 Bool. If this parameter is true, failing to have the required modules
@@ -1738,6 +1898,13 @@ at a later time, e.g. after an unsuccessful B<make test> of your module.
 
 It is I<extremely> rare to have to use C<PREREQ_FATAL> at all!
 
+=item PREREQ_PM
+
+Hashref: Names of modules that need to be available to run this
+extension (e.g. Fcntl for SDBM_File) are the keys of the hash and the
+desired version is the value. If the required version number is 0, we
+only check if any version is installed already.
+
 =item PREREQ_PRINT
 
 Bool.  If this parameter is true, the prerequisites will be printed to
@@ -1759,7 +1926,9 @@ RedHatism for C<PREREQ_PRINT>.  The output format is different, though:
 
 Like PREFIX, but only for the site install locations.
 
-Defaults to PREFIX (if set) or $Config{siteprefixexp}
+Defaults to PREFIX (if set) or $Config{siteprefixexp}.  Perls prior to
+5.6.0 didn't have an explicit siteprefix in the Config.  In those
+cases $Config{installprefix} will be used.
 
 =item SKIP
 
@@ -1783,6 +1952,10 @@ Like PREFIX, but only for the vendor install locations.
 
 Defaults to PREFIX (if set) or $Config{vendorprefixexp}
 
+=item VERBINST
+
+If true, make install will be verbose
+
 =item VERSION
 
 Your version number for distributing the package.  This defaults to
@@ -1804,7 +1977,7 @@ MakeMaker object. The following lines will be parsed o.k.:
 
     $VERSION = '1.00';
     *VERSION = \'1.01';
-    ( $VERSION ) = '$Revision: 1.37 $ ' =~ /\$Revision:\s+([^\s]+)/;
+    ( $VERSION ) = '$Revision: 1.63 $ ' =~ /\$Revision:\s+([^\s]+)/;
     $FOO::VERSION = '1.10';
     *FOO::VERSION = \'1.11';
     our $VERSION = 1.2.3;       # new for perl5.6.0 
@@ -1962,6 +2135,27 @@ Makefile:
     MAKE_FRAG
     }
 
+=head2 The End Of Cargo Cult Programming
+
+WriteMakefile() now does some basic sanity checks on its parameters to
+protect against typos and malformatted values.  This means some things
+which happened to work in the past will now throw warnings and
+possibly produce internal errors.
+
+Some of the most common mistakes:
+
+=over 2
+
+=item C<<MAN3PODS => ' '>>
+
+This is commonly used to supress the creation of man pages.  MAN3PODS
+takes a hash ref not a string, but the above worked by accident in old
+versions of MakeMaker.
+
+The correct code is C<<MAN3PODS => { }>>.
+
+=back
+
 
 =head2 Hintsfile support