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 + +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