Blob Blame History Raw
ExtUtils-CBuilder-0.27

diff -urN perl-5.10.1.orig/MANIFEST perl-5.10.1/MANIFEST
--- perl-5.10.1.orig/MANIFEST	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/MANIFEST	2009-12-01 11:52:20.000000000 +0100
@@ -2166,6 +2166,7 @@
 lib/ExtUtils/CBuilder/t/00-have-compiler.t	ExtUtils::CBuilder tests
 lib/ExtUtils/CBuilder/t/01-basic.t	tests for ExtUtils::CBuilder
 lib/ExtUtils/CBuilder/t/02-link.t	tests for ExtUtils::CBuilder
+lib/ExtUtils/CBuilder/t/03-cplusplus.t	tests for ExtUtils::CBuilder
 lib/ExtUtils/Changes		MakeMaker change log
 lib/ExtUtils/Changes_EU-Install		ExtUtils-Install change log
 lib/ExtUtils/Command/MM.pm	Calling MM functions from the cmd line
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Base.pm perl-5.10.1/lib/ExtUtils/CBuilder/Base.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Base.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Base.pm	2009-12-01 10:38:49.000000000 +0100
@@ -9,7 +9,7 @@
 use IO::File;
 
 use vars qw($VERSION);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 
 sub new {
   my $class = shift;
@@ -21,6 +21,7 @@
   while (my ($k,$v) = each %Config) {
     $self->{config}{$k} = $v unless exists $self->{config}{$k};
   }
+  $self->{config}{cc} = $ENV{CC} if exists $ENV{CC};
   return $self;
 }
 
@@ -98,6 +99,7 @@
   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 @optimize = $self->split_like_shell($cf->{optimize});
   my @flags = (@include_dirs, @defines, @cccdlflags, @extra_compiler_flags,
 	       $self->arg_nolink,
@@ -114,7 +116,7 @@
 }
 
 sub have_compiler {
-  my ($self) = @_;
+  my ($self, $is_cplusplus) = @_;
   return $self->{have_compiler} if defined $self->{have_compiler};
 
   my $result;
@@ -125,6 +127,7 @@
     # 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;
@@ -132,13 +135,19 @@
 
     {
       my $FH = IO::File->new("> $tmpfile") or die "Can't create $tmpfile: $!";
-      print $FH "int boot_compilet() { return 1; }\n";
+      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;
-      $obj_file = $self->compile(source => $tmpfile);
+      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;
@@ -152,6 +161,11 @@
   return $self->{have_compiler} = $result;
 }
 
+sub have_cplusplus {
+  push @_, 1;
+  goto &have_compiler;
+}
+
 sub lib_file {
   my ($self, $dl_file) = @_;
   $dl_file =~ s/\.[^.]+$//;
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Changes perl-5.10.1/lib/ExtUtils/CBuilder/Changes
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Changes	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Changes	2009-12-01 10:37:31.000000000 +0100
@@ -1,5 +1,48 @@
 Revision history for Perl extension ExtUtils::CBuilder.
 
+0.27 - Thu Oct 29 21:29:56 EDT 2009
+
+ Other:
+ - Removed Build.PL to avoid creating a circular dependency
+ - Added version numbers to Windows compiler driver modules
+
+0.26_05 - Sun Oct 25 17:29:02 EDT 2009
+
+ Bugs fixed:
+ - Fixed t/02link.t failures on cygwin with Perl 5.8 [David Golden]
+
+ Other:
+ - Made have_compiler (and have_cplusplus) quiet without echoing
+   the test command to STDOUT [David Golden]
+
+0.26_04 - Mon Oct 19 21:57:46 EDT 2009
+
+ Enhancements:
+ - Added 'have_cplusplus()' method to check for C++ support
+ - Added patches for building Perl with mingw64 [Sisyphus]
+ - Allow CC environment variable to override $Config{cc}
+
+ Bugs fixed:
+ - Fixed link executable command for Win32 MSVC (RT#40819) [Cosimo
+   Streppone]
+ - Removed MSVC version check when embedding a manifest file
+   (RT #43002) [Steve Hay]
+
+ Other:
+ - Split Windows compiler driver packages into individual *.pm files
+
+0.260301 - Sat Aug 29 11:04:41 EDT 2009
+
+ Bugs fixed:
+ - Fixed linking error on Win32 with gcc compiler (RT#49000)
+   [kmx]
+
+0.2603 - Sat Jul 18 06:56:06 EDT 2009
+
+ Bugs fixed:
+ - Makefile.PL had wrong INSTALLDIRS setting for older Perls
+   (RT#47985) [David Golden]
+
 0.2602 - Sat Jul  4 10:57:12 EDT 2009
 
  Bugs fixed:
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Unix.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Unix.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Unix.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Unix.pm	2009-12-01 10:38:49.000000000 +0100
@@ -4,7 +4,7 @@
 use ExtUtils::CBuilder::Base;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Base);
 
 sub link_executable {
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/VMS.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/VMS.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/VMS.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/VMS.pm	2009-12-01 10:38:49.000000000 +0100
@@ -4,7 +4,7 @@
 use ExtUtils::CBuilder::Base;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Base);
 
 use File::Spec::Functions qw(catfile catdir);
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows/BCC.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows/BCC.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows/BCC.pm	1970-01-01 01:00:00.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows/BCC.pm	2009-12-01 10:38:49.000000000 +0100
@@ -0,0 +1,130 @@
+package ExtUtils::CBuilder::Platform::Windows::BCC;
+
+use vars qw($VERSION);
+$VERSION = '0.27';
+
+sub format_compiler_cmd {
+  my ($self, %spec) = @_;
+
+  foreach my $path ( @{ $spec{includes} || [] },
+                     @{ $spec{perlinc}  || [] } ) {
+    $path = '-I' . $path;
+  }
+
+  %spec = $self->write_compiler_script(%spec)
+    if $spec{use_scripts};
+
+  return [ grep {defined && length} (
+    $spec{cc}, '-c'         ,
+    @{$spec{includes}}      ,
+    @{$spec{cflags}}        ,
+    @{$spec{optimize}}      ,
+    @{$spec{defines}}       ,
+    @{$spec{perlinc}}       ,
+    "-o$spec{output}"       ,
+    $spec{source}           ,
+  ) ];
+}
+
+sub write_compiler_script {
+  my ($self, %spec) = @_;
+
+  my $script = File::Spec->catfile( $spec{srcdir},
+                                    $spec{basename} . '.ccs' );
+
+  $self->add_to_cleanup($script);
+
+  print "Generating script '$script'\n" if !$self->{quiet};
+
+  my $SCRIPT = IO::File->new( ">$script" )
+    or die( "Could not create script '$script': $!" );
+
+  # XXX Borland "response files" seem to be unable to accept macro
+  # definitions containing quoted strings. Escaping strings with
+  # backslash doesn't work, and any level of quotes are stripped. The
+  # result is is a floating point number in the source file where a
+  # string is expected. So we leave the macros on the command line.
+  print $SCRIPT join( "\n",
+    map { ref $_ ? @{$_} : $_ }
+    grep defined,
+    delete(
+      @spec{ qw(includes cflags optimize perlinc) } )
+  );
+
+  push @{$spec{includes}}, '@"' . $script . '"';
+
+  return %spec;
+}
+
+sub format_linker_cmd {
+  my ($self, %spec) = @_;
+
+  foreach my $path ( @{$spec{libpath}} ) {
+    $path = "-L$path";
+  }
+
+  push( @{$spec{startup}}, 'c0d32.obj' )
+    unless ( $spec{starup} && @{$spec{startup}} );
+
+  %spec = $self->write_linker_script(%spec)
+    if $spec{use_scripts};
+
+  return [ grep {defined && length} (
+    $spec{ld}               ,
+    @{$spec{lddlflags}}     ,
+    @{$spec{libpath}}       ,
+    @{$spec{other_ldflags}} ,
+    @{$spec{startup}}       ,
+    @{$spec{objects}}       , ',',
+    $spec{output}           , ',',
+    $spec{map_file}         , ',',
+    $spec{libperl}          ,
+    @{$spec{perllibs}}      , ',',
+    $spec{def_file}
+  ) ];
+}
+
+sub write_linker_script {
+  my ($self, %spec) = @_;
+
+  # To work around Borlands "unique" commandline syntax,
+  # two scripts are used:
+
+  my $ld_script = File::Spec->catfile( $spec{srcdir},
+                                       $spec{basename} . '.lds' );
+  my $ld_libs   = File::Spec->catfile( $spec{srcdir},
+                                       $spec{basename} . '.lbs' );
+
+  $self->add_to_cleanup($ld_script, $ld_libs);
+
+  print "Generating scripts '$ld_script' and '$ld_libs'.\n" if !$self->{quiet};
+
+  # Script 1: contains options & names of object files.
+  my $LD_SCRIPT = IO::File->new( ">$ld_script" )
+    or die( "Could not create linker script '$ld_script': $!" );
+
+  print $LD_SCRIPT join( " +\n",
+    map { @{$_} }
+    grep defined,
+    delete(
+      @spec{ qw(lddlflags libpath other_ldflags startup objects) } )
+  );
+
+  # Script 2: contains name of libs to link against.
+  my $LD_LIBS = IO::File->new( ">$ld_libs" )
+    or die( "Could not create linker script '$ld_libs': $!" );
+
+  print $LD_LIBS join( " +\n",
+     (delete $spec{libperl}  || ''),
+    @{delete $spec{perllibs} || []},
+  );
+
+  push @{$spec{lddlflags}}, '@"' . $ld_script  . '"';
+  push @{$spec{perllibs}},  '@"' . $ld_libs    . '"';
+
+  return %spec;
+}
+
+1;
+
+
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows/GCC.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows/GCC.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows/GCC.pm	1970-01-01 01:00:00.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows/GCC.pm	2009-12-01 10:38:49.000000000 +0100
@@ -0,0 +1,151 @@
+package ExtUtils::CBuilder::Platform::Windows::GCC;
+
+use vars qw($VERSION);
+$VERSION = '0.27';
+
+sub format_compiler_cmd {
+  my ($self, %spec) = @_;
+
+  foreach my $path ( @{ $spec{includes} || [] },
+                     @{ $spec{perlinc}  || [] } ) {
+    $path = '-I' . $path;
+  }
+
+  # split off any -arguments included in cc
+  my @cc = split / (?=-)/, $spec{cc};
+
+  return [ grep {defined && length} (
+    @cc, '-c'               ,
+    @{$spec{includes}}      ,
+    @{$spec{cflags}}        ,
+    @{$spec{optimize}}      ,
+    @{$spec{defines}}       ,
+    @{$spec{perlinc}}       ,
+    '-o', $spec{output}     ,
+    $spec{source}           ,
+  ) ];
+}
+
+sub format_linker_cmd {
+  my ($self, %spec) = @_;
+  my $cf = $self->{config};
+
+  # The Config.pm variable 'libperl' is hardcoded to the full name
+  # of the perl import library (i.e. 'libperl56.a'). GCC will not
+  # find it unless the 'lib' prefix & the extension are stripped.
+  $spec{libperl} =~ s/^(?:lib)?([^.]+).*$/-l$1/;
+
+  unshift( @{$spec{other_ldflags}}, '-nostartfiles' )
+    if ( $spec{startup} && @{$spec{startup}} );
+
+  # From ExtUtils::MM_Win32:
+  #
+  ## one thing for GCC/Mingw32:
+  ## we try to overcome non-relocateable-DLL problems by generating
+  ##    a (hopefully unique) image-base from the dll's name
+  ## -- BKS, 10-19-1999
+  File::Basename::basename( $spec{output} ) =~ /(....)(.{0,4})/;
+  $spec{image_base} = sprintf( "0x%x0000", unpack('n', $1 ^ $2) );
+
+  %spec = $self->write_linker_script(%spec)
+    if $spec{use_scripts};
+
+  foreach my $path ( @{$spec{libpath}} ) {
+    $path = "-L$path";
+  }
+
+  my @cmds; # Stores the series of commands needed to build the module.
+
+  my $DLLTOOL = $cf->{dlltool} || 'dlltool';
+
+  push @cmds, [
+    $DLLTOOL, '--def'        , $spec{def_file},
+              '--output-exp' , $spec{explib}
+  ];
+
+  # split off any -arguments included in ld
+  my @ld = split / (?=-)/, $spec{ld};
+
+  push @cmds, [ grep {defined && length} (
+    @ld                       ,
+    '-o', $spec{output}       ,
+    "-Wl,--base-file,$spec{base_file}"   ,
+    "-Wl,--image-base,$spec{image_base}" ,
+    @{$spec{lddlflags}}       ,
+    @{$spec{libpath}}         ,
+    @{$spec{startup}}         ,
+    @{$spec{objects}}         ,
+    @{$spec{other_ldflags}}   ,
+    $spec{libperl}            ,
+    @{$spec{perllibs}}        ,
+    $spec{explib}             ,
+    $spec{map_file} ? ('-Map', $spec{map_file}) : ''
+  ) ];
+
+  push @cmds, [
+    $DLLTOOL, '--def'        , $spec{def_file},
+              '--output-exp' , $spec{explib},
+              '--base-file'  , $spec{base_file}
+  ];
+
+  push @cmds, [ grep {defined && length} (
+    @ld                       ,
+    '-o', $spec{output}       ,
+    "-Wl,--image-base,$spec{image_base}" ,
+    @{$spec{lddlflags}}       ,
+    @{$spec{libpath}}         ,
+    @{$spec{startup}}         ,
+    @{$spec{objects}}         ,
+    @{$spec{other_ldflags}}   ,
+    $spec{libperl}            ,
+    @{$spec{perllibs}}        ,
+    $spec{explib}             ,
+    $spec{map_file} ? ('-Map', $spec{map_file}) : ''
+  ) ];
+
+  return @cmds;
+}
+
+sub write_linker_script {
+  my ($self, %spec) = @_;
+
+  my $script = File::Spec->catfile( $spec{srcdir},
+                                    $spec{basename} . '.lds' );
+
+  $self->add_to_cleanup($script);
+
+  print "Generating script '$script'\n" if !$self->{quiet};
+
+  my $SCRIPT = IO::File->new( ">$script" )
+    or die( "Could not create script '$script': $!" );
+
+  print $SCRIPT ( 'SEARCH_DIR(' . $_ . ")\n" )
+    for @{delete $spec{libpath} || []};
+
+  # gcc takes only one startup file, so the first object in startup is
+  # specified as the startup file and any others are shifted into the
+  # beginning of the list of objects.
+  if ( $spec{startup} && @{$spec{startup}} ) {
+    print $SCRIPT 'STARTUP(' . shift( @{$spec{startup}} ) . ")\n";
+    unshift @{$spec{objects}},
+      @{delete $spec{startup} || []};
+  }
+
+  print $SCRIPT 'INPUT(' . join( ',',
+    @{delete $spec{objects}  || []}
+  ) . ")\n";
+
+  print $SCRIPT 'INPUT(' . join( ' ',
+     (delete $spec{libperl}  || ''),
+    @{delete $spec{perllibs} || []},
+  ) . ")\n";
+
+  #it is important to keep the order 1.linker_script - 2.other_ldflags
+  unshift @{$spec{other_ldflags}}, '"' . $script . '"';
+
+  return %spec;
+}
+
+1;
+
+
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows/MSVC.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows/MSVC.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows/MSVC.pm	1970-01-01 01:00:00.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows/MSVC.pm	2009-12-01 10:38:49.000000000 +0100
@@ -0,0 +1,131 @@
+package ExtUtils::CBuilder::Platform::Windows::MSVC;
+
+use vars qw($VERSION);
+$VERSION = '0.27';
+
+sub arg_exec_file {
+  my ($self, $file) = @_;
+  return "/OUT:$file";
+}
+
+sub format_compiler_cmd {
+  my ($self, %spec) = @_;
+
+  foreach my $path ( @{ $spec{includes} || [] },
+                     @{ $spec{perlinc}  || [] } ) {
+    $path = '-I' . $path;
+  }
+
+  %spec = $self->write_compiler_script(%spec)
+    if $spec{use_scripts};
+
+  return [ grep {defined && length} (
+    $spec{cc},'-nologo','-c',
+    @{$spec{includes}}      ,
+    @{$spec{cflags}}        ,
+    @{$spec{optimize}}      ,
+    @{$spec{defines}}       ,
+    @{$spec{perlinc}}       ,
+    "-Fo$spec{output}"      ,
+    $spec{source}           ,
+  ) ];
+}
+
+sub write_compiler_script {
+  my ($self, %spec) = @_;
+
+  my $script = File::Spec->catfile( $spec{srcdir},
+                                    $spec{basename} . '.ccs' );
+
+  $self->add_to_cleanup($script);
+  print "Generating script '$script'\n" if !$self->{quiet};
+
+  my $SCRIPT = IO::File->new( ">$script" )
+    or die( "Could not create script '$script': $!" );
+
+  print $SCRIPT join( "\n",
+    map { ref $_ ? @{$_} : $_ }
+    grep defined,
+    delete(
+      @spec{ qw(includes cflags optimize defines perlinc) } )
+  );
+
+  push @{$spec{includes}}, '@"' . $script . '"';
+
+  return %spec;
+}
+
+sub format_linker_cmd {
+  my ($self, %spec) = @_;
+  my $cf = $self->{config};
+
+  foreach my $path ( @{$spec{libpath}} ) {
+    $path = "-libpath:$path";
+  }
+
+  my $output = $spec{output};
+
+  $spec{def_file}  &&= '-def:'      . $spec{def_file};
+  $spec{output}    &&= '-out:'      . $spec{output};
+  $spec{manifest}  &&= '-manifest ' . $spec{manifest};
+  $spec{implib}    &&= '-implib:'   . $spec{implib};
+  $spec{map_file}  &&= '-map:'      . $spec{map_file};
+
+  %spec = $self->write_linker_script(%spec)
+    if $spec{use_scripts};
+
+  my @cmds; # Stores the series of commands needed to build the module.
+
+  push @cmds, [ grep {defined && length} (
+    $spec{ld}               ,
+    @{$spec{lddlflags}}     ,
+    @{$spec{libpath}}       ,
+    @{$spec{other_ldflags}} ,
+    @{$spec{startup}}       ,
+    @{$spec{objects}}       ,
+    $spec{map_file}         ,
+    $spec{libperl}          ,
+    @{$spec{perllibs}}      ,
+    $spec{def_file}         ,
+    $spec{implib}           ,
+    $spec{output}           ,
+  ) ];
+
+  # Embed the manifest file if it exists
+  push @cmds, [
+    'if', 'exist', $spec{manifest}, 'mt', '-nologo', $spec{manifest}, '-outputresource:' . "$output;2"
+  ];
+
+  return @cmds;
+}
+
+sub write_linker_script {
+  my ($self, %spec) = @_;
+
+  my $script = File::Spec->catfile( $spec{srcdir},
+                                    $spec{basename} . '.lds' );
+
+  $self->add_to_cleanup($script);
+
+  print "Generating script '$script'\n" if !$self->{quiet};
+
+  my $SCRIPT = IO::File->new( ">$script" )
+    or die( "Could not create script '$script': $!" );
+
+  print $SCRIPT join( "\n",
+    map { ref $_ ? @{$_} : $_ }
+    grep defined,
+    delete(
+      @spec{ qw(lddlflags libpath other_ldflags
+                startup objects libperl perllibs
+                def_file implib map_file)            } )
+  );
+
+  push @{$spec{lddlflags}}, '@"' . $script . '"';
+
+  return %spec;
+}
+
+1;
+
+
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/Windows.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/Windows.pm	2009-12-01 10:38:49.000000000 +0100
@@ -10,16 +10,36 @@
 use IO::File;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Base);
 
+=begin comment
+
+The compiler-specific packages implement functions for generating properly
+formatted commandlines for the compiler being used. Each package
+defines two primary functions 'format_linker_cmd()' &
+'format_compiler_cmd()' that accepts a list of named arguments (a
+hash) and returns a list of formatted options suitable for invoking the
+compiler. By default, if the compiler supports scripting of its
+operation then a script file is built containing the options while
+those options are removed from the commandline, and a reference to the
+script is pushed onto the commandline in their place. Scripting the
+compiler in this way helps to avoid the problems associated with long
+commandlines under some shells.
+
+=end comment
+
+=cut
+
 sub new {
   my $class = shift;
   my $self = $class->SUPER::new(@_);
   my $cf = $self->{config};
 
   # Inherit from an appropriate compiler driver class
-  unshift @ISA, "ExtUtils::CBuilder::Platform::Windows::" . $self->_compiler_type;
+  my $driver = "ExtUtils::CBuilder::Platform::Windows::" . $self->_compiler_type;
+  eval "require $driver" or die "Could not load compiler driver: $@";
+  unshift @ISA, $driver;
 
   return $self;
 }
@@ -238,422 +258,6 @@
 
 1;
 
-########################################################################
-
-=begin comment
-
-The packages below implement functions for generating properly
-formatted commandlines for the compiler being used. Each package
-defines two primary functions 'format_linker_cmd()' &
-'format_compiler_cmd()' that accepts a list of named arguments (a
-hash) and returns a list of formatted options suitable for invoking the
-compiler. By default, if the compiler supports scripting of its
-operation then a script file is built containing the options while
-those options are removed from the commandline, and a reference to the
-script is pushed onto the commandline in their place. Scripting the
-compiler in this way helps to avoid the problems associated with long
-commandlines under some shells.
-
-=end comment
-
-=cut
-
-########################################################################
-package ExtUtils::CBuilder::Platform::Windows::MSVC;
-
-sub format_compiler_cmd {
-  my ($self, %spec) = @_;
-
-  foreach my $path ( @{ $spec{includes} || [] },
-                     @{ $spec{perlinc}  || [] } ) {
-    $path = '-I' . $path;
-  }
-
-  %spec = $self->write_compiler_script(%spec)
-    if $spec{use_scripts};
-
-  return [ grep {defined && length} (
-    $spec{cc},'-nologo','-c',
-    @{$spec{includes}}      ,
-    @{$spec{cflags}}        ,
-    @{$spec{optimize}}      ,
-    @{$spec{defines}}       ,
-    @{$spec{perlinc}}       ,
-    "-Fo$spec{output}"      ,
-    $spec{source}           ,
-  ) ];
-}
-
-sub write_compiler_script {
-  my ($self, %spec) = @_;
-
-  my $script = File::Spec->catfile( $spec{srcdir},
-                                    $spec{basename} . '.ccs' );
-
-  $self->add_to_cleanup($script);
-  print "Generating script '$script'\n" if !$self->{quiet};
-
-  my $SCRIPT = IO::File->new( ">$script" )
-    or die( "Could not create script '$script': $!" );
-
-  print $SCRIPT join( "\n",
-    map { ref $_ ? @{$_} : $_ }
-    grep defined,
-    delete(
-      @spec{ qw(includes cflags optimize defines perlinc) } )
-  );
-
-  push @{$spec{includes}}, '@"' . $script . '"';
-
-  return %spec;
-}
-
-sub format_linker_cmd {
-  my ($self, %spec) = @_;
-  my $cf = $self->{config};
-
-  foreach my $path ( @{$spec{libpath}} ) {
-    $path = "-libpath:$path";
-  }
-
-  my $output = $spec{output};
-
-  $spec{def_file}  &&= '-def:'      . $spec{def_file};
-  $spec{output}    &&= '-out:'      . $spec{output};
-  $spec{manifest}  &&= '-manifest ' . $spec{manifest};
-  $spec{implib}    &&= '-implib:'   . $spec{implib};
-  $spec{map_file}  &&= '-map:'      . $spec{map_file};
-
-  %spec = $self->write_linker_script(%spec)
-    if $spec{use_scripts};
-
-  my @cmds; # Stores the series of commands needed to build the module.
-
-  push @cmds, [ grep {defined && length} (
-    $spec{ld}               ,
-    @{$spec{lddlflags}}     ,
-    @{$spec{libpath}}       ,
-    @{$spec{other_ldflags}} ,
-    @{$spec{startup}}       ,
-    @{$spec{objects}}       ,
-    $spec{map_file}         ,
-    $spec{libperl}          ,
-    @{$spec{perllibs}}      ,
-    $spec{def_file}         ,
-    $spec{implib}           ,
-    $spec{output}           ,
-  ) ];
-
-  # Embed the manifest file for VC 2005 (aka VC 8) or higher, but not for the 64-bit Platform SDK compiler
-  if ($cf->{ivsize} == 4 && $cf->{cc} eq 'cl' and $cf->{ccversion} =~ /^(\d+)/ and $1 >= 14) {
-    push @cmds, [
-      'if', 'exist', $spec{manifest}, 'mt', '-nologo', $spec{manifest}, '-outputresource:' . "$output;2"
-    ];
-  }
-
-  return @cmds;
-}
-
-sub write_linker_script {
-  my ($self, %spec) = @_;
-
-  my $script = File::Spec->catfile( $spec{srcdir},
-                                    $spec{basename} . '.lds' );
-
-  $self->add_to_cleanup($script);
-
-  print "Generating script '$script'\n" if !$self->{quiet};
-
-  my $SCRIPT = IO::File->new( ">$script" )
-    or die( "Could not create script '$script': $!" );
-
-  print $SCRIPT join( "\n",
-    map { ref $_ ? @{$_} : $_ }
-    grep defined,
-    delete(
-      @spec{ qw(lddlflags libpath other_ldflags
-                startup objects libperl perllibs
-                def_file implib map_file)            } )
-  );
-
-  push @{$spec{lddlflags}}, '@"' . $script . '"';
-
-  return %spec;
-}
-
-1;
-
-########################################################################
-package ExtUtils::CBuilder::Platform::Windows::BCC;
-
-sub format_compiler_cmd {
-  my ($self, %spec) = @_;
-
-  foreach my $path ( @{ $spec{includes} || [] },
-                     @{ $spec{perlinc}  || [] } ) {
-    $path = '-I' . $path;
-  }
-
-  %spec = $self->write_compiler_script(%spec)
-    if $spec{use_scripts};
-
-  return [ grep {defined && length} (
-    $spec{cc}, '-c'         ,
-    @{$spec{includes}}      ,
-    @{$spec{cflags}}        ,
-    @{$spec{optimize}}      ,
-    @{$spec{defines}}       ,
-    @{$spec{perlinc}}       ,
-    "-o$spec{output}"       ,
-    $spec{source}           ,
-  ) ];
-}
-
-sub write_compiler_script {
-  my ($self, %spec) = @_;
-
-  my $script = File::Spec->catfile( $spec{srcdir},
-                                    $spec{basename} . '.ccs' );
-
-  $self->add_to_cleanup($script);
-
-  print "Generating script '$script'\n" if !$self->{quiet};
-
-  my $SCRIPT = IO::File->new( ">$script" )
-    or die( "Could not create script '$script': $!" );
-
-  # XXX Borland "response files" seem to be unable to accept macro
-  # definitions containing quoted strings. Escaping strings with
-  # backslash doesn't work, and any level of quotes are stripped. The
-  # result is is a floating point number in the source file where a
-  # string is expected. So we leave the macros on the command line.
-  print $SCRIPT join( "\n",
-    map { ref $_ ? @{$_} : $_ }
-    grep defined,
-    delete(
-      @spec{ qw(includes cflags optimize perlinc) } )
-  );
-
-  push @{$spec{includes}}, '@"' . $script . '"';
-
-  return %spec;
-}
-
-sub format_linker_cmd {
-  my ($self, %spec) = @_;
-
-  foreach my $path ( @{$spec{libpath}} ) {
-    $path = "-L$path";
-  }
-
-  push( @{$spec{startup}}, 'c0d32.obj' )
-    unless ( $spec{starup} && @{$spec{startup}} );
-
-  %spec = $self->write_linker_script(%spec)
-    if $spec{use_scripts};
-
-  return [ grep {defined && length} (
-    $spec{ld}               ,
-    @{$spec{lddlflags}}     ,
-    @{$spec{libpath}}       ,
-    @{$spec{other_ldflags}} ,
-    @{$spec{startup}}       ,
-    @{$spec{objects}}       , ',',
-    $spec{output}           , ',',
-    $spec{map_file}         , ',',
-    $spec{libperl}          ,
-    @{$spec{perllibs}}      , ',',
-    $spec{def_file}
-  ) ];
-}
-
-sub write_linker_script {
-  my ($self, %spec) = @_;
-
-  # To work around Borlands "unique" commandline syntax,
-  # two scripts are used:
-
-  my $ld_script = File::Spec->catfile( $spec{srcdir},
-                                       $spec{basename} . '.lds' );
-  my $ld_libs   = File::Spec->catfile( $spec{srcdir},
-                                       $spec{basename} . '.lbs' );
-
-  $self->add_to_cleanup($ld_script, $ld_libs);
-
-  print "Generating scripts '$ld_script' and '$ld_libs'.\n" if !$self->{quiet};
-
-  # Script 1: contains options & names of object files.
-  my $LD_SCRIPT = IO::File->new( ">$ld_script" )
-    or die( "Could not create linker script '$ld_script': $!" );
-
-  print $LD_SCRIPT join( " +\n",
-    map { @{$_} }
-    grep defined,
-    delete(
-      @spec{ qw(lddlflags libpath other_ldflags startup objects) } )
-  );
-
-  # Script 2: contains name of libs to link against.
-  my $LD_LIBS = IO::File->new( ">$ld_libs" )
-    or die( "Could not create linker script '$ld_libs': $!" );
-
-  print $LD_LIBS join( " +\n",
-     (delete $spec{libperl}  || ''),
-    @{delete $spec{perllibs} || []},
-  );
-
-  push @{$spec{lddlflags}}, '@"' . $ld_script  . '"';
-  push @{$spec{perllibs}},  '@"' . $ld_libs    . '"';
-
-  return %spec;
-}
-
-1;
-
-########################################################################
-package ExtUtils::CBuilder::Platform::Windows::GCC;
-
-sub format_compiler_cmd {
-  my ($self, %spec) = @_;
-
-  foreach my $path ( @{ $spec{includes} || [] },
-                     @{ $spec{perlinc}  || [] } ) {
-    $path = '-I' . $path;
-  }
-
-  # split off any -arguments included in cc
-  my @cc = split / (?=-)/, $spec{cc};
-
-  return [ grep {defined && length} (
-    @cc, '-c'               ,
-    @{$spec{includes}}      ,
-    @{$spec{cflags}}        ,
-    @{$spec{optimize}}      ,
-    @{$spec{defines}}       ,
-    @{$spec{perlinc}}       ,
-    '-o', $spec{output}     ,
-    $spec{source}           ,
-  ) ];
-}
-
-sub format_linker_cmd {
-  my ($self, %spec) = @_;
-
-  # The Config.pm variable 'libperl' is hardcoded to the full name
-  # of the perl import library (i.e. 'libperl56.a'). GCC will not
-  # find it unless the 'lib' prefix & the extension are stripped.
-  $spec{libperl} =~ s/^(?:lib)?([^.]+).*$/-l$1/;
-
-  unshift( @{$spec{other_ldflags}}, '-nostartfiles' )
-    if ( $spec{startup} && @{$spec{startup}} );
-
-  # From ExtUtils::MM_Win32:
-  #
-  ## one thing for GCC/Mingw32:
-  ## we try to overcome non-relocateable-DLL problems by generating
-  ##    a (hopefully unique) image-base from the dll's name
-  ## -- BKS, 10-19-1999
-  File::Basename::basename( $spec{output} ) =~ /(....)(.{0,4})/;
-  $spec{image_base} = sprintf( "0x%x0000", unpack('n', $1 ^ $2) );
-
-  %spec = $self->write_linker_script(%spec)
-    if $spec{use_scripts};
-
-  foreach my $path ( @{$spec{libpath}} ) {
-    $path = "-L$path";
-  }
-
-  my @cmds; # Stores the series of commands needed to build the module.
-
-  push @cmds, [
-    'dlltool', '--def'        , $spec{def_file},
-               '--output-exp' , $spec{explib}
-  ];
-
-  # split off any -arguments included in ld
-  my @ld = split / (?=-)/, $spec{ld};
-
-  push @cmds, [ grep {defined && length} (
-    @ld                       ,
-    '-o', $spec{output}       ,
-    "-Wl,--base-file,$spec{base_file}"   ,
-    "-Wl,--image-base,$spec{image_base}" ,
-    @{$spec{lddlflags}}       ,
-    @{$spec{libpath}}         ,
-    @{$spec{startup}}         ,
-    @{$spec{objects}}         ,
-    @{$spec{other_ldflags}}   ,
-    $spec{libperl}            ,
-    @{$spec{perllibs}}        ,
-    $spec{explib}             ,
-    $spec{map_file} ? ('-Map', $spec{map_file}) : ''
-  ) ];
-
-  push @cmds, [
-    'dlltool', '--def'        , $spec{def_file},
-               '--output-exp' , $spec{explib},
-               '--base-file'  , $spec{base_file}
-  ];
-
-  push @cmds, [ grep {defined && length} (
-    @ld                       ,
-    '-o', $spec{output}       ,
-    "-Wl,--image-base,$spec{image_base}" ,
-    @{$spec{lddlflags}}       ,
-    @{$spec{libpath}}         ,
-    @{$spec{startup}}         ,
-    @{$spec{objects}}         ,
-    @{$spec{other_ldflags}}   ,
-    $spec{libperl}            ,
-    @{$spec{perllibs}}        ,
-    $spec{explib}             ,
-    $spec{map_file} ? ('-Map', $spec{map_file}) : ''
-  ) ];
-
-  return @cmds;
-}
-
-sub write_linker_script {
-  my ($self, %spec) = @_;
-
-  my $script = File::Spec->catfile( $spec{srcdir},
-                                    $spec{basename} . '.lds' );
-
-  $self->add_to_cleanup($script);
-
-  print "Generating script '$script'\n" if !$self->{quiet};
-
-  my $SCRIPT = IO::File->new( ">$script" )
-    or die( "Could not create script '$script': $!" );
-
-  print $SCRIPT ( 'SEARCH_DIR(' . $_ . ")\n" )
-    for @{delete $spec{libpath} || []};
-
-  # gcc takes only one startup file, so the first object in startup is
-  # specified as the startup file and any others are shifted into the
-  # beginning of the list of objects.
-  if ( $spec{startup} && @{$spec{startup}} ) {
-    print $SCRIPT 'STARTUP(' . shift( @{$spec{startup}} ) . ")\n";
-    unshift @{$spec{objects}},
-      @{delete $spec{startup} || []};
-  }
-
-  print $SCRIPT 'INPUT(' . join( ',',
-    @{delete $spec{objects}  || []}
-  ) . ")\n";
-
-  print $SCRIPT 'INPUT(' . join( ' ',
-     (delete $spec{libperl}  || ''),
-    @{delete $spec{perllibs} || []},
-  ) . ")\n";
-
-  push @{$spec{other_ldflags}}, '"' . $script . '"';
-
-  return %spec;
-}
-
-1;
-
 __END__
 
 =head1 NAME
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/aix.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/aix.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/aix.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/aix.pm	2009-12-01 10:38:49.000000000 +0100
@@ -5,7 +5,7 @@
 use File::Spec;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 sub need_prelink { 1 }
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/cygwin.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/cygwin.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/cygwin.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/cygwin.pm	2009-12-01 10:38:49.000000000 +0100
@@ -5,13 +5,16 @@
 use ExtUtils::CBuilder::Platform::Unix;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
+# TODO: If a specific exe_file name is requested, if the exe created
+# doesn't have that name, we might want to rename it.  Apparently asking
+# for an exe of "foo" might result in "foo.exe".  Alternatively, we should
+# make sure the return value is correctly "foo.exe".
+# C.f http://rt.cpan.org/Public/Bug/Display.html?id=41003
 sub link_executable {
   my $self = shift;
-  # $Config{ld} is okay. Circumvent the Unix ld=cc override in the superclass.
-  local $self->{config}{cc} = $self->{config}{ld};
   return $self->SUPER::link_executable(@_);
 }
 
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/darwin.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/darwin.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/darwin.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/darwin.pm	2009-12-01 10:38:49.000000000 +0100
@@ -4,7 +4,7 @@
 use ExtUtils::CBuilder::Platform::Unix;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 sub compile {
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/dec_osf.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/dec_osf.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/dec_osf.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/dec_osf.pm	2009-12-01 10:38:49.000000000 +0100
@@ -6,7 +6,7 @@
 
 use vars qw($VERSION @ISA);
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 
 sub link_executable {
   my $self = shift;
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/os2.pm perl-5.10.1/lib/ExtUtils/CBuilder/Platform/os2.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/Platform/os2.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/Platform/os2.pm	2009-12-01 10:38:49.000000000 +0100
@@ -4,7 +4,7 @@
 use ExtUtils::CBuilder::Platform::Unix;
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 @ISA = qw(ExtUtils::CBuilder::Platform::Unix);
 
 sub need_prelink { 1 }
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/t/00-have-compiler.t perl-5.10.1/lib/ExtUtils/CBuilder/t/00-have-compiler.t
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/t/00-have-compiler.t	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/t/00-have-compiler.t	2009-12-01 10:39:10.000000000 +0100
@@ -4,12 +4,6 @@
 my $perl;
 BEGIN {
   $perl = File::Spec->rel2abs($^X);
-  if ($ENV{PERL_CORE}) {
-    chdir 't' if -d 't';
-    chdir '../lib/ExtUtils/CBuilder'
-      or die "Can't chdir to lib/ExtUtils/CBuilder: $!";
-    @INC = qw(../..);
-  }
 }
 
 use strict;
@@ -22,22 +16,30 @@
   }
 }
 
-plan tests => 4;
+plan tests => 6;
 
 require_ok "ExtUtils::CBuilder";
 
 my $b = eval { ExtUtils::CBuilder->new(quiet => 1) };
 ok( $b, "got CBuilder object" ) or diag $@;
 
+my $bogus_path = 'djaadjfkadjkfajdf';
+my $run_perl = "$perl -e1 --";
 # test missing compiler
-$b->{config}{cc} = 'djaadjfkadjkfajdf';
-$b->{config}{ld} = 'djaadjfkadjkfajdf';
+$b->{config}{cc} = $bogus_path;
+$b->{config}{ld} = $bogus_path;
+
+$b->{have_compiler} = undef;
 is( $b->have_compiler, 0, "have_compiler: fake missing cc" );
+$b->{have_compiler} = 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}{cc} = "$perl -e1 --";
-$b->{config}{ld} = "$perl -e1 --";
 is( $b->have_compiler, 1, "have_compiler: fake present cc" );
+$b->{have_compiler} = undef;
+is( $b->have_cplusplus, 1, "have_cpp_compiler: fake present c++" );
 
-
+# test missing cpp compiler
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/t/02-link.t perl-5.10.1/lib/ExtUtils/CBuilder/t/02-link.t
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/t/02-link.t	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/t/02-link.t	2009-12-02 12:08:01.000000000 +0100
@@ -35,7 +35,7 @@
   plan skip_all => "no compiler available for testing";
 }
 else {
-  plan tests => 7;
+  plan tests => 8;
 }
 
 ok $b, "created EU::CB object";
@@ -56,13 +56,14 @@
 
 # Link
 SKIP: {
-  skip "error compiling source", 3
+  skip "error compiling source", 4
     unless -e $object_file;
 
   my @temps;
   eval { ($exe_file, @temps) = $b->link_executable(objects => $object_file) };
   is $@, q{}, "no exception from linking";
   ok -e $exe_file, "found executable file";
+  ok -x $exe_file, "executable file appears to be executable";
 
   if ($^O eq 'os2') {		# Analogue of LDLOADPATH...
           # Actually, not needed now, since we do not link with the generated DLL
@@ -74,9 +75,9 @@
 
   # Try the executable
   my $ec = my_system($exe_file);
-  is $ec, 11, "got expected exit code from executable"
-    or print( $? == -1 ? "# Could not run '$exe_file'\n" 
-                      : "# Unexpected exit code '$ec'\n");
+  is( $ec, 11, "got expected exit code from executable" )
+    or diag( $ec == -1 ? "Could not run '$exe_file': $!\n" 
+                       : "Unexpected exit code '$ec'\n");
 }
 
 # Clean up
@@ -92,8 +93,10 @@
 
 sub my_system {
   my $cmd = shift;
+  my $ec;
   if ($^O eq 'VMS') {
-    return system("mcr $cmd");
+    $ec = system("mcr $cmd");
   }
-  return system($cmd) >> 8;
+  $ec = system($cmd);
+  return $ec == -1 ? -1 : $ec >> 8;
 }
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder/t/03-cplusplus.t perl-5.10.1/lib/ExtUtils/CBuilder/t/03-cplusplus.t
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder/t/03-cplusplus.t	1970-01-01 01:00:00.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder/t/03-cplusplus.t	2009-12-02 12:08:01.000000000 +0100
@@ -0,0 +1,73 @@
+#! perl -w
+
+BEGIN {
+  if ($ENV{PERL_CORE}) {
+    chdir 't' if -d 't';
+    chdir '../lib/ExtUtils/CBuilder'
+      or die "Can't chdir to lib/ExtUtils/CBuilder: $!";
+    @INC = qw(../..);
+  }
+}
+
+use strict;
+use Test::More;
+BEGIN { 
+  if ($^O eq 'VMS') {
+    # So we can get the return value of system()
+    require vmsish;
+    import vmsish;
+  }
+}
+use ExtUtils::CBuilder;
+use File::Spec;
+
+# TEST doesn't like extraneous output
+my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
+my ($source_file, $object_file, $lib_file);
+
+my $b = ExtUtils::CBuilder->new(quiet => $quiet);
+
+# test plan
+if ( ! $b->have_cplusplus ) {
+  plan skip_all => "no compiler available for testing";
+}
+else {
+  plan tests => 7;
+}
+
+ok $b, "created EU::CB object";
+
+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;
+}
+ok -e $source_file, "source file '$source_file' created";
+
+$object_file = $b->object_file($source_file);
+ok 1;
+
+is $object_file, $b->compile(source => $source_file, 'C++' => 1);
+
+$lib_file = $b->lib_file($object_file);
+ok 1;
+
+my ($lib, @temps) = $b->link(objects => $object_file,
+                             module_name => 'compilet');
+$lib =~ tr/"'//d;
+is $lib_file, $lib;
+
+for ($source_file, $object_file, $lib_file) {
+  tr/"'//d;
+  1 while unlink;
+}
+
+if ($^O eq 'VMS') {
+   1 while unlink 'COMPILET.LIS';
+   1 while unlink 'COMPILET.OPT';
+}
+
diff -urN perl-5.10.1.orig/lib/ExtUtils/CBuilder.pm perl-5.10.1/lib/ExtUtils/CBuilder.pm
--- perl-5.10.1.orig/lib/ExtUtils/CBuilder.pm	2009-12-02 11:59:51.000000000 +0100
+++ perl-5.10.1/lib/ExtUtils/CBuilder.pm	2009-12-01 10:38:49.000000000 +0100
@@ -5,7 +5,7 @@
 use File::Basename ();
 
 use vars qw($VERSION @ISA);
-$VERSION = '0.2602';
+$VERSION = '0.27';
 $VERSION = eval $VERSION;
 
 # Okay, this is the brute-force method of finding out what kind of
@@ -133,6 +133,10 @@
 link a sample C library.  The sample will be compiled in the system
 tempdir or, if that fails for some reason, in the current directory.
 
+=item have_cplusplus
+
+Just like have_compiler but for C++ instead of C.
+
 =item compile
 
 Compiles a C source file and produces an object file.  The name of the
@@ -161,6 +165,11 @@
 this is not possible, as a string containing all the arguments
 together.
 
+=item C<C++>
+
+Specifies that the source file is a C++ source file and sets appropriate
+compiler flags
+
 =back
 
 The operation of this method is also affected by the