Update ExtUtils-CBuilder to CPAN version 0.2800
authorChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Tue, 7 Dec 2010 13:25:37 +0000 (13:25 +0000)
committerChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Tue, 7 Dec 2010 13:27:35 +0000 (13:27 +0000)
  [DELTA]

  0.2800 - Mon Dec  6 16:05:46 EST 2010

    - No changes from 0.27_07

  0.27_07 - Wed Sep 29 21:48:55 EDT 2010

    Fixed:

    - Fixed t/02-link.t on perl < 5.8

  0.27_06 - Mon Sep 27 15:29:54 EDT 2010

    Fixed:

    - Preserves exit status on VMS [Craig Berry]

    - Fix Win32 split_like_shell escaping [Christian Walde]

  0.27_05 - Wed Jul 28 15:29:59 EDT 2010

    Fixed:

    - Tests no longer fail if user has set the CC environment variable

  0.27_04 - Mon Jul 26 22:41:43 EDT 2010

    Added:
    - handle c compiler and c++ compiler separately
      (adds requirement for IPC::Cmd) [Jens Rehsack]

    Others:
    - rely on File::Temp::tempfile and File::Spec::tmpdir to
      get unique file name for checking for compiler
      [Jens Rehsack]

    - Code base modernization and substantial code coverage improvments
      [Jim Keenan]

22 files changed:
MANIFEST
Porting/Maintainers.pl
cpan/ExtUtils-CBuilder/Changes
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Base.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/Unix.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/VMS.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/Windows.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/Windows/BCC.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/Windows/GCC.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/Windows/MSVC.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/aix.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/cygwin.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/darwin.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/dec_osf.pm
cpan/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/os2.pm
cpan/ExtUtils-CBuilder/t/00-have-compiler.t
cpan/ExtUtils-CBuilder/t/01-basic.t
cpan/ExtUtils-CBuilder/t/02-link.t
cpan/ExtUtils-CBuilder/t/03-cplusplus.t
cpan/ExtUtils-CBuilder/t/04-base.t [new file with mode: 0644]
pod/perldelta.pod

index ad0660d..41e19be 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -877,6 +877,7 @@ cpan/ExtUtils-CBuilder/t/00-have-compiler.t                 ExtUtils::CBuilder tests
 cpan/ExtUtils-CBuilder/t/01-basic.t                            tests for ExtUtils::CBuilder
 cpan/ExtUtils-CBuilder/t/02-link.t                             tests for ExtUtils::CBuilder
 cpan/ExtUtils-CBuilder/t/03-cplusplus.t                                tests for ExtUtils::CBuilder
+cpan/ExtUtils-CBuilder/t/04-base.t                             tests for ExtUtils::CBuilder
 cpan/ExtUtils-Constant/lib/ExtUtils/Constant/Base.pm           generate XS code to import C header constants
 cpan/ExtUtils-Constant/lib/ExtUtils/Constant.pm                        generate XS code to import C header constants
 cpan/ExtUtils-Constant/lib/ExtUtils/Constant/ProxySubs.pm      generate XS code for proxy constants
index 773258a..4a96b5c 100755 (executable)
@@ -527,7 +527,7 @@ use File::Glob qw(:case);
     'ExtUtils::CBuilder' =>
        {
        'MAINTAINER'    => 'kwilliams',
-       'DISTRIBUTION'  => 'DAGOLDEN/ExtUtils-CBuilder-0.2703.tar.gz',
+       'DISTRIBUTION'  => 'DAGOLDEN/ExtUtils-CBuilder-0.2800.tar.gz',
        'FILES'         => q[cpan/ExtUtils-CBuilder],
        'UPSTREAM'      => 'cpan',
        },
index e3e709d..b2d95fe 100644 (file)
@@ -1,5 +1,43 @@
 Revision history for Perl extension ExtUtils::CBuilder.
 
+0.2800 - Mon Dec  6 16:05:46 EST 2010
+
+  - No changes from 0.27_07
+
+0.27_07 - Wed Sep 29 21:48:55 EDT 2010
+
+  Fixed:
+
+  - Fixed t/02-link.t on perl < 5.8
+
+0.27_06 - Mon Sep 27 15:29:54 EDT 2010
+
+  Fixed:
+
+  - Preserves exit status on VMS [Craig Berry]
+
+  - Fix Win32 split_like_shell escaping [Christian Walde]
+
+0.27_05 - Wed Jul 28 15:29:59 EDT 2010
+
+  Fixed:
+
+  - Tests no longer fail if user has set the CC environment variable
+
+0.27_04 - Mon Jul 26 22:41:43 EDT 2010
+
+  Added:
+  - handle c compiler and c++ compiler separately
+    (adds requirement for IPC::Cmd) [Jens Rehsack]
+
+  Others:
+  - rely on File::Temp::tempfile and File::Spec::tmpdir to
+    get unique file name for checking for compiler
+    [Jens Rehsack]
+
+  - Code base modernization and substantial code coverage improvments
+    [Jim Keenan]
+
 0.2703 - Tue Mar 16 17:10:55 EDT 2010
 
  Bugs fixed:
@@ -239,7 +277,7 @@ Revision history for Perl extension ExtUtils::CBuilder.
 
  - Various parts of the code were looking for the CORE/ directory in
    $Config{archlib}, $Config{installarchlib}, and $Config{archlibexp}.
-   Only the latter is correct, so we use that everywhere now. 
+   Only the latter is correct, so we use that everywhere now.
    [Curt Tilmes]
 
  - For Unix-ish platforms, link_executable() will now prefer
index 7620daf..75fb366 100644 (file)
@@ -5,7 +5,7 @@ use File::Path ();
 use File::Basename ();
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 $VERSION = eval $VERSION;
 
 # Okay, this is the brute-force method of finding out what kind of
index ea3e7de..83319e8 100644 (file)
@@ -7,9 +7,27 @@ use Cwd ();
 use Config;
 use Text::ParseWords;
 use IO::File;
+use Data::Dumper;$Data::Dumper::Indent=1;
+use IPC::Cmd qw(can_run);
+use File::Temp qw(tempfile);
 
 use vars qw($VERSION);
-$VERSION = '0.2703_01';
+$VERSION = '0.2800';
+
+# More details about C/C++ compilers:
+# http://developers.sun.com/sunstudio/documentation/product/compiler.jsp
+# http://gcc.gnu.org/
+# http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp
+# http://msdn.microsoft.com/en-us/vstudio/default.aspx
+
+my %cc2cxx = (
+    # first line order is important to support wrappers like in pkgsrc
+    cc => [ 'c++', 'CC', 'aCC', 'cxx', ], # Sun Studio, HP ANSI C/C++ Compilers
+    gcc => [ 'g++' ], # GNU Compiler Collection
+    xlc => [ 'xlC' ], # IBM C/C++ Set, xlc without thread-safety
+    xlc_r => [ 'xlC_r' ], # IBM C/C++ Set, xlc with thread-safety
+    cl    => [ 'cl' ], # Microsoft Visual Studio
+);
 
 sub new {
   my $class = shift;
@@ -21,7 +39,37 @@ sub new {
   while (my ($k,$v) = each %Config) {
     $self->{config}{$k} = $v unless exists $self->{config}{$k};
   }
-  $self->{config}{cc} = $ENV{CC} if exists $ENV{CC};
+  $self->{config}{cc} = $ENV{CC} if defined $ENV{CC};
+  $self->{config}{ccflags} = $ENV{CFLAGS} if defined $ENV{CFLAGS};
+  $self->{config}{cxx} = $ENV{CXX} if defined $ENV{CXX};
+  $self->{config}{cxxflags} = $ENV{CXXFLAGS} if defined $ENV{CXXFLAGS};
+  $self->{config}{ld} = $ENV{LD} if defined $ENV{LD};
+  $self->{config}{ldflags} = $ENV{LDFLAGS} if defined $ENV{LDFLAGS};
+
+  unless ( exists $self->{config}{cxx} ) {
+    my ($ccpath, $ccbase, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/);
+    foreach my $cxx (@{$cc2cxx{$ccbase}}) {
+      if( can_run( File::Spec->catfile( $ccpath, $cxx, $ccsfx ) ) ) {
+        $self->{config}{cxx} = File::Spec->catfile( $ccpath, $cxx, $ccsfx );
+       last;
+      }
+      if( can_run( File::Spec->catfile( $cxx, $ccsfx ) ) ) {
+        $self->{config}{cxx} = File::Spec->catfile( $cxx, $ccsfx );
+       last;
+      }
+      if( can_run( $cxx ) ) {
+        $self->{config}{cxx} = $cxx;
+       last;
+      }
+    }
+    unless ( exists $self->{config}{cxx} ) {
+      $self->{config}{cxx} = $self->{config}{cc};
+      my $cflags = $self->{config}{cflags};
+      $self->{config}{cxxflags} = '-x c++';
+      $self->{config}{cxxflags} .= " $cflags" if defined $cflags;
+    }
+  }
+
   return $self;
 }
 
@@ -29,7 +77,7 @@ sub find_perl_interpreter {
   my $perl;
   File::Spec->file_name_is_absolute($perl = $^X)
     or -f ($perl = $Config::Config{perlpath})
-    or ($perl = $^X);
+    or ($perl = $^X); # XXX how about using IPC::Cmd::can_run here?
   return $perl;
 }
 
@@ -47,6 +95,10 @@ sub cleanup {
   }
 }
 
+sub get_config {
+    return %{ $_[0]->{config} };
+}
+
 sub object_file {
   my ($self, $filename) = @_;
 
@@ -87,81 +139,80 @@ sub compile {
   die "Missing 'source' argument to compile()" unless defined $args{source};
   
   my $cf = $self->{config}; # For convenience
-
-  $args{object_file} ||= $self->object_file($args{source});
-
-  $args{include_dirs} = [ $args{include_dirs} ]
-    if exists($args{include_dirs}) && ref($args{include_dirs}) ne "ARRAY";
-
-  my @include_dirs = $self->arg_include_dirs
-    (@{$args{include_dirs} || []},
-     $self->perl_inc());
+  
+  my $object_file = $args{object_file}
+    ? $args{object_file}
+    : $self->object_file($args{source});
+
+  my $include_dirs_ref = 
+    (exists($args{include_dirs}) && ref($args{include_dirs}) ne "ARRAY")
+      ? [ $args{include_dirs} ]
+      : $args{include_dirs};
+  my @include_dirs = $self->arg_include_dirs(
+    @{ $include_dirs_ref || [] },
+    $self->perl_inc(),
+  );
   
   my @defines = $self->arg_defines( %{$args{defines} || {}} );
   
-  my @extra_compiler_flags = $self->split_like_shell($args{extra_compiler_flags});
+  my @extra_compiler_flags =
+    $self->split_like_shell($args{extra_compiler_flags});
   my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
-  my @ccflags = $self->split_like_shell($cf->{ccflags});
-  push @ccflags, qw/-x c++/ if $args{'C++'};
+  my @ccflags = $self->split_like_shell($args{'C++'} ? $cf->{cxxflags} : $cf->{ccflags});
   my @optimize = $self->split_like_shell($cf->{optimize});
-  my @flags = (@include_dirs, @defines, @cccdlflags, @extra_compiler_flags,
-              $self->arg_nolink,
-              @ccflags, @optimize,
-              $self->arg_object_file($args{object_file}),
-             );
-  
-  my @cc = $self->split_like_shell($cf->{cc});
+  my @flags = (
+    @include_dirs,
+    @defines,
+    @cccdlflags,
+    @extra_compiler_flags,
+    $self->arg_nolink,
+    @ccflags,
+    @optimize,
+    $self->arg_object_file($object_file),
+  );
+  my @cc = $self->split_like_shell($args{'C++'} ? $cf->{cxx} : $cf->{cc});
   
   $self->do_system(@cc, @flags, $args{source})
-    or die "error building $args{object_file} from '$args{source}'";
+    or die "error building $object_file from '$args{source}'";
 
-  return $args{object_file};
+  return $object_file;
 }
 
 sub have_compiler {
   my ($self, $is_cplusplus) = @_;
-  return $self->{have_compiler} if defined $self->{have_compiler};
+  my $have_compiler_flag = $is_cplusplus ? "have_cxx" : "have_cc";
+  my $suffix = $is_cplusplus ? ".cc" : ".c";
+  return $self->{$have_compiler_flag} if defined $self->{$have_compiler_flag};
 
   my $result;
   my $attempts = 3;
   # tmpdir has issues for some people so fall back to current dir
-  DIR: for my $dir ( File::Spec->tmpdir, '.' ) {
-
-    # don't clobber existing files (rare, but possible)
-    my $rand = int(rand(2**31));
-    my $tmpfile = File::Spec->catfile($dir, "compilet-$rand.c");
-    $tmpfile .= "c" if $is_cplusplus;
-    if ( -e $tmpfile ) {
-      redo DIR if $attempts--;
-      next DIR;
-    }
 
-    {
-      my $FH = IO::File->new("> $tmpfile") or die "Can't create $tmpfile: $!";
-      if ( $is_cplusplus ) {
-        print $FH "class Bogus { public: int boot_compilet() { return 1; } };\n";
-      }
-      else {
-        print $FH "int boot_compilet() { return 1; }\n";
-      }
-    }
+  # don't clobber existing files (rare, but possible)
+  my ( $FH, $tmpfile ) = tempfile( "compilet-XXXXX", SUFFIX => $suffix );
+  binmode $FH;
 
-    my ($obj_file, @lib_files);
-    eval {
-      local $^W = 0;
-      local $self->{quiet} = 1;
-      $obj_file = $self->compile('C++' => $is_cplusplus, source => $tmpfile);
-      @lib_files = $self->link(objects => $obj_file, module_name => 'compilet');
-    };
-    $result = $@ ? 0 : 1;
-
-    foreach (grep defined, $tmpfile, $obj_file, @lib_files) {
-      1 while unlink;
-    }
-    last DIR if $result;
+  if ( $is_cplusplus ) {
+    print $FH "class Bogus { public: int boot_compilet() { return 1; } };\n";
+  }
+  else {
+    print $FH "int boot_compilet() { return 1; }\n";
+  }
+
+  my ($obj_file, @lib_files);
+  eval {
+    local $^W = 0;
+    local $self->{quiet} = 1;
+    $obj_file = $self->compile('C++' => $is_cplusplus, source => $tmpfile);
+    @lib_files = $self->link(objects => $obj_file, module_name => 'compilet');
+  };
+  $result = $@ ? 0 : 1;
+
+  foreach (grep defined, $tmpfile, $obj_file, @lib_files) {
+    1 while unlink;
   }
 
-  return $self->{have_compiler} = $result;
+  return $self->{$have_compiler_flag} = $result;
 }
 
 sub have_cplusplus {
@@ -190,23 +241,32 @@ sub extra_link_args_after_prelink { return }
 
 sub prelink {
   my ($self, %args) = @_;
-  
-  ($args{dl_file} = $args{dl_name}) =~ s/.*::// unless $args{dl_file};
-  
+
+  my ($dl_file_out, $mksymlists_args) = _prepare_mksymlists_args(\%args);
+
   require ExtUtils::Mksymlists;
-  ExtUtils::Mksymlists::Mksymlists( # dl. abbrev for dynamic library
-    DL_VARS  => $args{dl_vars}      || [],
-    DL_FUNCS => $args{dl_funcs}     || {},
-    FUNCLIST => $args{dl_func_list} || [],
-    IMPORTS  => $args{dl_imports}   || {},
-    NAME     => $args{dl_name},                # Name of the Perl module
-    DLBASE   => $args{dl_base},                # Basename of DLL file
-    FILE     => $args{dl_file},                # Dir + Basename of symlist file
-    VERSION  => (defined $args{dl_version} ? $args{dl_version} : '0.0'),
-  );
-  
+  # dl. abbrev for dynamic library
+  ExtUtils::Mksymlists::Mksymlists( %{ $mksymlists_args } );
+
   # Mksymlists will create one of these files
-  return grep -e, map "$args{dl_file}.$_", qw(ext def opt);
+  return grep -e, map "$dl_file_out.$_", qw(ext def opt);
+}
+
+sub _prepare_mksymlists_args {
+  my $args = shift;
+  ($args->{dl_file} = $args->{dl_name}) =~ s/.*::// unless $args->{dl_file};
+  
+  my %mksymlists_args = (
+    DL_VARS  => $args->{dl_vars}      || [],
+    DL_FUNCS => $args->{dl_funcs}     || {},
+    FUNCLIST => $args->{dl_func_list} || [],
+    IMPORTS  => $args->{dl_imports}   || {},
+    NAME     => $args->{dl_name},    # Name of the Perl module
+    DLBASE   => $args->{dl_base},    # Basename of DLL file
+    FILE     => $args->{dl_file},    # Dir + Basename of symlist file
+    VERSION  => (defined $args->{dl_version} ? $args->{dl_version} : '0.0'),
+  );
+  return ($args->{dl_file}, \%mksymlists_args);
 }
 
 sub link {
@@ -230,14 +290,19 @@ sub _do_link {
   
   my @temp_files;
   @temp_files =
-    $self->prelink(%args,
-                  dl_name => $args{module_name}) if $args{lddl} && $self->need_prelink;
+    $self->prelink(%args, dl_name => $args{module_name})
+      if $args{lddl} && $self->need_prelink;
   
-  my @linker_flags = ($self->split_like_shell($args{extra_linker_flags}),
-                     $self->extra_link_args_after_prelink(%args, dl_name => $args{module_name},
-                                                          prelink_res => \@temp_files));
+  my @linker_flags = (
+    $self->split_like_shell($args{extra_linker_flags}),
+    $self->extra_link_args_after_prelink(
+       %args, dl_name => $args{module_name}, prelink_res => \@temp_files
+    )
+  );
 
-  my @output = $args{lddl} ? $self->arg_share_object_file($out) : $self->arg_exec_file($out);
+  my @output = $args{lddl}
+    ? $self->arg_share_object_file($out)
+    : $self->arg_exec_file($out);
   my @shrp = $self->split_like_shell($cf->{shrpenv});
   my @ld = $self->split_like_shell($cf->{ld});
   
@@ -262,6 +327,11 @@ sub split_like_shell {
   $string =~ s/^\s+|\s+$//g;
   return () unless length($string);
   
+  # Text::ParseWords replaces all 'escaped' characters with themselves, which completely
+  # breaks paths under windows. As such, we forcibly replace backwards slashes with forward
+  # slashes on windows.
+  $string =~ s@\\@/@g if $^O eq 'MSWin32';
+  
   return Text::ParseWords::shellwords($string);
 }
 
@@ -278,12 +348,12 @@ sub perl_src {
   # Try up to 5 levels upwards
   for (0..10) {
     if (
-       -f File::Spec->catfile($dir,"config_h.SH")
-       &&
-       -f File::Spec->catfile($dir,"perl.h")
-       &&
-       -f File::Spec->catfile($dir,"lib","Exporter.pm")
-       ) {
+      -f File::Spec->catfile($dir,"config_h.SH")
+      &&
+      -f File::Spec->catfile($dir,"perl.h")
+      &&
+      -f File::Spec->catfile($dir,"lib","Exporter.pm")
+    ) {
       return Cwd::realpath( $dir );
     }
 
@@ -308,3 +378,5 @@ sub DESTROY {
 }
 
 1;
+
+# vim: ts=2 sw=2 et:
index a3e9b3c..8665ac9 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use ExtUtils::CBuilder::Base;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Base);
 
 sub link_executable {
index e31eca9..8800f8a 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use ExtUtils::CBuilder::Base;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Base);
 
 use File::Spec::Functions qw(catfile catdir);
index e26d1f8..97576c8 100644 (file)
@@ -10,7 +10,7 @@ use ExtUtils::CBuilder::Base;
 use IO::File;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Base);
 
 =begin comment
@@ -101,7 +101,7 @@ sub compile {
     builddir    => $srcdir,
     basename    => $basename,
     source      => $args{source},
-    output      => File::Spec->catfile($srcdir, $basename) . $cf->{obj_ext},
+    output      => $args{object_file} || File::Spec->catfile($srcdir, $basename) . $cf->{obj_ext},
     cc          => $cf->{cc},
     cflags      => [
                      $self->split_like_shell($cf->{ccflags}),
index 0764f93..6abade1 100644 (file)
@@ -1,7 +1,7 @@
 package ExtUtils::CBuilder::Platform::Windows::BCC;
 
 use vars qw($VERSION);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 
 sub format_compiler_cmd {
   my ($self, %spec) = @_;
index 84cdd5c..d5ff8f4 100644 (file)
@@ -1,7 +1,7 @@
 package ExtUtils::CBuilder::Platform::Windows::GCC;
 
 use vars qw($VERSION);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 
 sub format_compiler_cmd {
   my ($self, %spec) = @_;
index 72c3c00..d5d5e26 100644 (file)
@@ -1,7 +1,7 @@
 package ExtUtils::CBuilder::Platform::Windows::MSVC;
 
 use vars qw($VERSION);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 
 sub arg_exec_file {
   my ($self, $file) = @_;
index c4848ab..4fdcfa8 100644 (file)
@@ -5,7 +5,7 @@ use ExtUtils::CBuilder::Platform::Unix;
 use File::Spec;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 sub need_prelink { 1 }
index e886682..e02c13d 100644 (file)
@@ -5,7 +5,7 @@ use File::Spec;
 use ExtUtils::CBuilder::Platform::Unix;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 # TODO: If a specific exe_file name is requested, if the exe created
index 6253788..19ec013 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use ExtUtils::CBuilder::Platform::Unix;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 sub compile {
index 38205a9..b613cd6 100644 (file)
@@ -6,7 +6,7 @@ use File::Spec;
 
 use vars qw($VERSION @ISA);
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 
 sub link_executable {
   my $self = shift;
index bb590ee..3624d5f 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use ExtUtils::CBuilder::Platform::Unix;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2703';
+$VERSION = '0.2800';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 sub need_prelink { 1 }
index f20f891..581a214 100644 (file)
@@ -16,7 +16,7 @@ BEGIN {
   }
 }
 
-plan tests => 6;
+plan tests => 7;
 
 require_ok "ExtUtils::CBuilder";
 
@@ -29,17 +29,29 @@ my $run_perl = "$perl -e1 --";
 $b->{config}{cc} = $bogus_path;
 $b->{config}{ld} = $bogus_path;
 
-$b->{have_compiler} = undef;
+$b->{have_cc} = undef;
 is( $b->have_compiler, 0, "have_compiler: fake missing cc" );
-$b->{have_compiler} = undef;
+$b->{have_cxx} = undef;
 is( $b->have_cplusplus, 0, "have_cplusplus: fake missing c++" );
 
 # test found compiler
 $b->{config}{cc} = $run_perl;
 $b->{config}{ld} = $run_perl;
-$b->{have_compiler} = undef;
+$b->{config}{cxx} = $run_perl;
+$b->{have_cc} = undef;
 is( $b->have_compiler, 1, "have_compiler: fake present cc" );
-$b->{have_compiler} = undef;
+$b->{have_cxx} = undef;
 is( $b->have_cplusplus, 1, "have_cpp_compiler: fake present c++" );
 
 # test missing cpp compiler
+
+# test one non-exported subroutine
+{
+    my $type = ExtUtils::CBuilder::os_type();
+    if ($type) {
+        pass( "OS type $type located for $^O" );
+    }
+    else {
+        pass( "OS type not yet listed for $^O" );
+    }
+}
index c1eab9e..ffcd60c 100644 (file)
@@ -12,7 +12,7 @@ BEGIN {
 use ExtUtils::CBuilder;
 use File::Spec;
 
-# TEST doesn't like extraneous output
+# TEST does not like extraneous output
 my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
 my ($source_file, $object_file, $lib_file);
 
index f67ebe6..822b071 100644 (file)
@@ -12,7 +12,7 @@ BEGIN {
 use ExtUtils::CBuilder;
 use File::Spec;
 
-# TEST doesn't like extraneous output
+# TEST does not like extraneous output
 my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
 my ($source_file, $object_file, $exe_file);
 
@@ -33,10 +33,9 @@ ok $b, "created EU::CB object";
 
 $source_file = File::Spec->catfile('t', 'compilet.c');
 {
-  local *FH;
-  open FH, "> $source_file" or die "Can't create $source_file: $!";
-  print FH "int main(void) { return 11; }\n";
-  close FH;
+  open my $FH, "> $source_file" or die "Can't create $source_file: $!";
+  print $FH "int main(void) { return 11; }\n";
+  close $FH;
 }
 ok -e $source_file, "generated '$source_file'";
 
@@ -86,11 +85,13 @@ sub my_system {
   my $cmd = shift;
   my $ec;
   if ($^O eq 'VMS') {
-    # Preserve non-posixified status and don't bit shift the result.
-    use vmsish 'status';
+    # Preserve non-posixified status and don't bit shift the result
+    # because we're running under "use vmsish";
     $ec = system("mcr $cmd");
     return $ec;
   }
-  $ec = system($cmd);
-  return $ec == -1 ? -1 : $ec >> 8;
+  else {
+    $ec = system($cmd);
+    return $ec == -1 ? -1 : $ec >> 8;
+  }
 }
index 4e13381..02555df 100644 (file)
@@ -12,7 +12,7 @@ BEGIN {
 use ExtUtils::CBuilder;
 use File::Spec;
 
-# TEST doesn't like extraneous output
+# TEST does not like extraneous output
 my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
 my ($source_file, $object_file, $lib_file);
 
@@ -32,10 +32,9 @@ ok $b->have_cplusplus, "have_cplusplus";
 
 $source_file = File::Spec->catfile('t', 'compilet.cc');
 {
-  local *FH;
-  open FH, "> $source_file" or die "Can't create $source_file: $!";
-  print FH "class Bogus { public: int boot_compilet() { return 1; } };\n";
-  close FH;
+  open my $FH, "> $source_file" or die "Can't create $source_file: $!";
+  print $FH "class Bogus { public: int boot_compilet() { return 1; } };\n";
+  close $FH;
 }
 ok -e $source_file, "source file '$source_file' created";
 
diff --git a/cpan/ExtUtils-CBuilder/t/04-base.t b/cpan/ExtUtils-CBuilder/t/04-base.t
new file mode 100644 (file)
index 0000000..025b53b
--- /dev/null
@@ -0,0 +1,411 @@
+#! perl -w
+
+use strict;
+use Test::More tests => 58;
+BEGIN { 
+  if ($^O eq 'VMS') {
+    # So we can get the return value of system()
+    require vmsish;
+    import vmsish;
+  }
+}
+use Config;
+use Cwd;
+use File::Path qw( mkpath );
+use File::Temp qw( tempdir );
+use ExtUtils::CBuilder::Base;
+
+# XXX protect from user CC as we mock everything here
+local $ENV{CC};
+
+my ( $base, $phony, $cwd );
+my ( $source_file, $object_file, $lib_file );
+
+$base = ExtUtils::CBuilder::Base->new();
+ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+
+{
+  $phony = 'foobar';
+  $base = ExtUtils::CBuilder::Base->new(
+      config  => { cc => $phony },
+  );
+  ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+  isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+  is( $base->{config}->{cc}, $phony,
+      "Got expected value when 'config' argument passed to new()" );
+}
+
+{
+    $phony = 'barbaz';
+    local $ENV{CC} = $phony;
+    $base = ExtUtils::CBuilder::Base->new();
+    ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+    isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+    is( $base->{config}->{cc}, $phony,
+        "Got expected value \$ENV{CC} set" );
+}
+
+{
+    my $path_to_perl = File::Spec->catfile( '', qw| usr bin perl | );
+    local $^X = $path_to_perl;
+    is(
+        ExtUtils::CBuilder::Base::find_perl_interpreter(),
+        $path_to_perl,
+        "find_perl_interpreter() returned expected absolute path"
+    );
+}
+
+{
+    my $path_to_perl = 'foobar';
+    local $^X = $path_to_perl;
+    # %Config is read-only.  We cannot assign to it and we therefore cannot
+    # simulate the condition that would occur were its value something other
+    # than an existing file.
+    if ( !$ENV{PERL_CORE} and $Config::Config{perlpath}) {
+        is(
+            ExtUtils::CBuilder::Base::find_perl_interpreter(),
+            $Config::Config{perlpath},
+            "find_perl_interpreter() returned expected file"
+        );
+    }
+    else {
+        is(
+            ExtUtils::CBuilder::Base::find_perl_interpreter(),
+            $path_to_perl,
+            "find_perl_interpreter() returned expected name"
+        );
+    }
+}
+
+{
+    $cwd = cwd();
+    my $tdir = tempdir();
+    chdir $tdir;
+    $base = ExtUtils::CBuilder::Base->new();
+    ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+    isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+    is( scalar keys %{$base->{files_to_clean}}, 0,
+        "No files needing cleaning yet" );
+
+    my $file_for_cleaning = File::Spec->catfile( $tdir, 'foobar' );
+    open my $IN, '>', $file_for_cleaning
+        or die "Unable to open dummy file: $!";
+    print $IN "\n";
+    close $IN or die "Unable to close dummy file: $!";
+
+    $base->add_to_cleanup( $file_for_cleaning );
+    is( scalar keys %{$base->{files_to_clean}}, 1,
+        "One file needs cleaning" );
+
+    $base->cleanup();
+    ok( ! -f $file_for_cleaning, "File was cleaned up" );
+
+    chdir $cwd;
+}
+
+# fake compiler is perl and will always succeed
+$base = ExtUtils::CBuilder::Base->new(
+    config  => {
+        cc => File::Spec->rel2abs($^X) . " -e1 --",
+        ld => File::Spec->rel2abs($^X) . " -e1 --",
+    }
+);
+ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+eval {
+    $base->compile(foo => 'bar');
+};
+like(
+    $@,
+    qr/Missing 'source' argument to compile/,
+    "Got expected error message when lacking 'source' argument to compile()"
+);
+
+$base = ExtUtils::CBuilder::Base->new( quiet => 1 );
+ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+
+$source_file = File::Spec->catfile('t', 'compilet.c');
+create_c_source_file($source_file);
+ok(-e $source_file, "source file '$source_file' created");
+
+# object filename automatically assigned
+my $obj_ext = $base->{config}{obj_ext};
+is( $base->object_file($source_file),
+    File::Spec->catfile('t', "compilet$obj_ext"),
+    "object_file(): got expected automatically assigned name for object file"
+);
+
+# object filename explicitly assigned
+$object_file = File::Spec->catfile('t', 'my_special_compilet.o' );
+is( $object_file,
+    $base->compile(
+        source      => $source_file,
+        object_file => $object_file,
+    ),
+    "compile(): returned object file with specified name"
+);
+
+$lib_file = $base->lib_file($object_file);
+ok( $lib_file, "lib_file() returned true value" );
+
+my ($lib, @temps);
+($lib, @temps) = $base->link(
+    objects     => $object_file,
+    module_name => 'compilet',
+);
+$lib =~ tr/"'//d; #"
+is($lib_file, $lib, "lib_file(): got expected value for $lib");
+
+($lib, @temps) = $base->link(
+    objects     => [ $object_file ],
+    module_name => 'compilet',
+);
+$lib =~ tr/"'//d; #"
+is($lib_file, $lib, "lib_file(): got expected value for $lib");
+
+($lib, @temps) = $base->link(
+    lib_file    => $lib_file,
+    objects     => [ $object_file ],
+    module_name => 'compilet',
+);
+$lib =~ tr/"'//d; #"
+is($lib_file, $lib, "lib_file(): got expected value for $lib");
+
+$lib = $base->link(
+    objects     => $object_file,
+    module_name => 'compilet',
+);
+$lib =~ tr/"'//d; #"
+is($lib_file, $lib, "lib_file(): got expected value for $lib");
+
+{
+    local $ENV{PERL_CORE} = '' unless $ENV{PERL_CORE};
+    my $include_dir = $base->perl_inc();
+    ok( $include_dir, "perl_inc() returned true value" );
+    ok( -d $include_dir, "perl_inc() returned directory" );
+}
+
+#
+$base = ExtUtils::CBuilder::Base->new( quiet => 1 );
+ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
+isa_ok( $base, 'ExtUtils::CBuilder::Base' );
+
+$source_file = File::Spec->catfile('t', 'compilet.c');
+create_c_source_file($source_file);
+ok(-e $source_file, "source file '$source_file' created");
+$object_file = File::Spec->catfile('t', 'my_special_compilet.o' );
+is( $object_file,
+    $base->compile(
+        source      => $source_file,
+        object_file => $object_file,
+        defines     => { alpha => 'beta', gamma => 'delta' },
+    ),
+    "compile() completed when 'defines' provided; returned object file with specified name"
+);
+
+my $exe_file = $base->exe_file($object_file);
+my $ext = $base->{config}{_exe};
+my $expected = File::Spec->catfile('t', qq|my_special_compilet$ext| );
+is(
+    $exe_file,
+    $expected,
+    "exe_file(): returned expected name of executable"
+);
+
+my %args = ();
+my @defines = $base->arg_defines( %args );
+ok( ! @defines, "Empty hash passed to arg_defines() returns empty list" );
+
+%args = ( alpha => 'beta', gamma => 'delta' );
+my $defines_seen_ref = { map { $_ => 1 } $base->arg_defines( %args ) };
+is_deeply(
+    $defines_seen_ref,
+    { '-Dalpha=beta' => 1, '-Dgamma=delta' => 1 },
+    "arg_defines(): got expected defines",
+);
+
+my $include_dirs_seen_ref =
+    { map {$_ => 1} $base->arg_include_dirs( qw| alpha beta gamma | ) };
+is_deeply(
+    $include_dirs_seen_ref,
+    { '-Ialpha' => 1, '-Ibeta' => 1, '-Igamma' => 1 },
+    "arg_include_dirs(): got expected include_dirs",
+);
+
+is( '-c', $base->arg_nolink(), "arg_nolink(): got expected value" );
+
+my $seen_ref =
+    { map {$_ => 1} $base->arg_object_file('alpha') };
+is_deeply(
+    $seen_ref,
+    { '-o'  => 1, 'alpha' => 1 },
+    "arg_object_file(): got expected option flag and value",
+);
+
+$seen_ref = { map {$_ => 1} $base->arg_share_object_file('alpha') };
+my %exp = map {$_ => 1} $base->split_like_shell($base->{config}{lddlflags});
+$exp{'-o'} = 1;
+$exp{'alpha'} = 1; 
+
+is_deeply(
+    $seen_ref,
+    \%exp,
+    "arg_share_object_file(): got expected option flag and value",
+);
+
+$seen_ref =
+    { map {$_ => 1} $base->arg_exec_file('alpha') };
+is_deeply(
+    $seen_ref,
+    { '-o'  => 1, 'alpha' => 1 },
+    "arg_exec_file(): got expected option flag and value",
+);
+
+ok(! $base->split_like_shell(undef),
+    "split_like_shell(): handled undefined argument as expected" );
+
+my $array_ref = [ qw| alpha beta gamma | ];
+my %split_seen = map { $_ => 1 } $base->split_like_shell($array_ref);
+%exp = ( alpha => 1, beta => 1, gamma => 1 );
+is_deeply( \%split_seen, \%exp,
+    "split_like_shell(): handled array ref as expected" );
+
+{
+    $cwd = cwd();
+    my $tdir = tempdir();
+    my $subdir = File::Spec->catdir(
+        $tdir, qw| alpha beta gamma delta epsilon 
+            zeta eta theta iota kappa lambda |
+    );
+    mkpath($subdir, { mode => 0711 } );
+    chdir $subdir
+        or die "Unable to change to temporary directory for testing";
+    local $ENV{PERL_CORE} = 1;
+    my $capture = q{};
+    local $SIG{__WARN__} = sub { $capture = $_[0] };
+    my $expected_message =
+        qr/PERL_CORE is set but I can't find your perl source!/; #'
+    my $rv;
+
+    $rv = $base->perl_src();
+    is( $rv, q{}, "perl_src(): returned empty string as expected" );
+    like( $capture, $expected_message,
+        "perl_src(): got expected warning" );
+    $capture = q{};
+
+    my $config = File::Spec->catfile( $subdir, 'config_h.SH' );
+    touch_file($config);
+    $rv = $base->perl_src();
+    is( $rv, q{}, "perl_src(): returned empty string as expected" );
+    like( $capture, $expected_message,
+        "perl_src(): got expected warning" );
+    $capture = q{};
+
+    my $perlh = File::Spec->catfile( $subdir, 'perl.h' );
+    touch_file($perlh);
+    $rv = $base->perl_src();
+    is( $rv, q{}, "perl_src(): returned empty string as expected" );
+    like( $capture, $expected_message,
+        "perl_src(): got expected warning" );
+    $capture = q{};
+
+    my $libsubdir = File::Spec->catdir( $subdir, 'lib' );
+    mkpath($libsubdir, { mode => 0711 } );
+    my $exporter = File::Spec->catfile( $libsubdir, 'Exporter.pm' );
+    touch_file($exporter);
+    $rv = $base->perl_src();
+    ok( -d $rv, "perl_src(): returned a directory" );
+    is( $rv, Cwd::realpath($subdir), "perl_src(): identified directory" );
+    is( $capture, q{}, "perl_src(): no warning, as expected" );
+
+    chdir $cwd
+        or die "Unable to change from temporary directory after testing";
+}
+
+my ($dl_file_out, $mksymlists_args);
+my $dlf = 'Kappa';
+%args = (
+    dl_vars         => [ qw| alpha beta gamma | ],
+    dl_funcs        => {
+        'Homer::Iliad'      => [ qw(trojans greeks) ],
+        'Homer::Odyssey'    => [ qw(travellers family suitors) ],
+    },
+    dl_func_list    => [ qw| delta epsilon | ],
+    dl_imports      => { zeta => 'eta', theta => 'iota' },
+    dl_name         => 'Tk::Canvas',
+    dl_base         => 'Tk::Canvas.ext',
+    dl_file         => $dlf,
+    dl_version      => '7.7',
+);
+($dl_file_out, $mksymlists_args) =
+    ExtUtils::CBuilder::Base::_prepare_mksymlists_args(\%args);
+is( $dl_file_out, $dlf, "_prepare_mksymlists_args(): Got expected name for dl_file" );
+is_deeply( $mksymlists_args,
+    {
+        DL_VARS         => [ qw| alpha beta gamma | ],
+        DL_FUNCS        => {
+            'Homer::Iliad'      => [ qw(trojans greeks) ],
+            'Homer::Odyssey'    => [ qw(travellers family suitors) ],
+        },
+        FUNCLIST        => [ qw| delta epsilon | ],
+        IMPORTS         => { zeta => 'eta', theta => 'iota' },
+        NAME            => 'Tk::Canvas',
+        DLBASE          => 'Tk::Canvas.ext',
+        FILE            => $dlf,
+        VERSION         => '7.7',
+    },
+    "_prepare_mksymlists_args(): got expected arguments for Mksymlists",
+);
+
+$dlf = 'Canvas';
+%args = (
+    dl_name         => 'Tk::Canvas',
+    dl_base         => 'Tk::Canvas.ext',
+);
+($dl_file_out, $mksymlists_args) =
+    ExtUtils::CBuilder::Base::_prepare_mksymlists_args(\%args);
+is( $dl_file_out, $dlf, "_prepare_mksymlists_args(): got expected name for dl_file" );
+is_deeply( $mksymlists_args,
+    {
+        DL_VARS         => [],
+        DL_FUNCS        => {},
+        FUNCLIST        => [],
+        IMPORTS         => {},
+        NAME            => 'Tk::Canvas',
+        DLBASE          => 'Tk::Canvas.ext',
+        FILE            => $dlf,
+        VERSION         => '0.0',
+    },
+    "_prepare_mksymlists_args(): got expected arguments for Mksymlists",
+);
+
+#####
+
+for ($source_file, $object_file, $lib_file) {
+  tr/"'//d; #"
+  1 while unlink;
+}
+
+pass("Completed all tests in $0");
+
+if ($^O eq 'VMS') {
+   1 while unlink 'COMPILET.LIS';
+   1 while unlink 'COMPILET.OPT';
+}
+
+sub create_c_source_file {
+    my $source_file = shift;
+    open my $FH, '>', $source_file or die "Can't create $source_file: $!";
+    print $FH "int boot_compilet(void) { return 1; }\n";
+    close $FH;
+}
+
+sub touch_file {
+    my $f = shift;
+    open my $FH, '>', $f or die "Can't create $f: $!";
+    print $FH "\n";
+    close $FH;
+    return $f;
+}
index 224a0d3..90393ec 100644 (file)
@@ -206,6 +206,10 @@ XXX
 
 =item *
 
+C<ExtUtils::CBuilder> has been upgraded from 0.2703 to 0.2800
+
+=item *
+
 C<if> has been upgraded from 0.06 to 0.0601.
 
 =item *