From 2cb1225ea44ef9a12beb1163828e77282c22288e Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Feb 2013 22:56:10 +0400 Subject: [PATCH 01/17] Preliminary support for C++ (while for Unix systems) Add option XSTARGET_EXT to WriteMakefile (it is ".c" by default). Generated Makefile under ExtUtils::MM_Unix now contains variable XSTARGET_EXT and uses it as suffix in files produced by xsubpp. Also add right files in C_FILES list. --- lib/ExtUtils/MM_Unix.pm | 14 ++- t/lib/MakeMaker/Test/Setup/XSCPP.pm | 138 ++++++++++++++++++++++++++++ t/xscpp.t | 58 ++++++++++++ 3 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 t/lib/MakeMaker/Test/Setup/XSCPP.pm create mode 100644 t/xscpp.t diff --git a/lib/ExtUtils/MM_Unix.pm b/lib/ExtUtils/MM_Unix.pm index 7fc9f6484..03d7a0ba8 100644 --- a/lib/ExtUtils/MM_Unix.pm +++ b/lib/ExtUtils/MM_Unix.pm @@ -395,6 +395,7 @@ sub constants { PERLRUNINST FULLPERLRUNINST ABSPERLRUNINST PERL_CORE PERM_DIR PERM_RW PERM_RWX + XSTARGET_EXT ) ) { @@ -1283,7 +1284,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) next if $self->{NORECURS}; $dir{$name} = $name if (-f $self->catfile($name,"Makefile.PL")); } elsif ($name =~ /\.xs\z/){ - my($c); ($c = $name) =~ s/\.xs\z/.c/; + my($c); ($c = $name) =~ s/\.xs\z/$self->{XSTARGET_EXT}/; $xs{$name} = $c; $c{$c} = 1; } elsif ($name =~ /\.c(pp|xx|c)?\z/i){ # .c .C .cpp .cxx .cc @@ -1733,6 +1734,9 @@ EOP $self->{LIBPERL_A} ||= "libperl$self->{LIB_EXT}"; + # Default extension for target produced from xs file + $self->{XSTARGET_EXT} ||= '.c'; + # make a simple check if we find strict warn "Warning: PERL_LIB ($self->{PERL_LIB}) seems not to be a perl library directory (strict.pm not found)" @@ -3596,8 +3600,8 @@ sub xs_c { my($self) = shift; return '' unless $self->needs_linking(); ' -.xs.c: - $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(XSUBPP_EXTRA_ARGS) $*.xs > $*.xsc && $(MV) $*.xsc $*.c +.xs$(XSTARGET_EXT): + $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(XSUBPP_EXTRA_ARGS) $*.xs > $*.xsc && $(MV) $*.xsc $*$(XSTARGET_EXT) '; } @@ -3628,8 +3632,8 @@ sub xs_o { # many makes are too dumb to use xs_c then c_o return '' unless $self->needs_linking(); ' .xs$(OBJ_EXT): - $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.xsc && $(MV) $*.xsc $*.c - $(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c + $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(XSUBPP_EXTRA_ARGS) $*.xs > $*.xsc && $(MV) $*.xsc $*$(XSTARGET_EXT) + $(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*$(XSTARGET_EXT) '; } diff --git a/t/lib/MakeMaker/Test/Setup/XSCPP.pm b/t/lib/MakeMaker/Test/Setup/XSCPP.pm new file mode 100644 index 000000000..637b3e73f --- /dev/null +++ b/t/lib/MakeMaker/Test/Setup/XSCPP.pm @@ -0,0 +1,138 @@ +package MakeMaker::Test::Setup::XSCPP; + +@ISA = qw(Exporter); +require Exporter; +@EXPORT = qw(setup_xs teardown_xs); + +use strict; +use File::Path; +use File::Basename; +use MakeMaker::Test::Utils; + +my $Is_VMS = $^O eq 'VMS'; + +my %Files = ( + 'XSCPP-Test/lib/XSCPP/Test.pm' => <<'END', +package XSCPP::Test; + +require Exporter; +require DynaLoader; + +$VERSION = 1.01; +@ISA = qw(Exporter DynaLoader); +@EXPORT = qw(is_even); + +bootstrap XSCPP::Test $VERSION; + +1; +END + + 'XSCPP-Test/Makefile.PL' => <<'END', +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'XSCPP::Test', + VERSION_FROM => 'lib/XSCPP/Test.pm', + XSTARGET_EXT => '.cpp', +); +END + + 'XSCPP-Test/Test.xs' => <<'END', +#ifdef __cplusplus +extern "C" { +#endif + +#include "EXTERN.h" +#include "perl.h" + +#ifdef __cplusplus +} +#endif + +#include "XSUB.h" + +class CPPTest { + public: + CPPTest() { } + ~CPPTest() { } + int is_even(int num) { return (num % 2) == 0; } +}; + +MODULE = XSCPP::Test PACKAGE = XSCPP::Test + +PROTOTYPES: DISABLE + +CPPTest* +CPPTest::new(); + +int +CPPTest::is_even(int input); + +void +CPPTest::DESTROY(); + +END + + 'XSCPP-Test/typemap' => <<'END', +TYPEMAP +CPPTest * O_OBJECT + +OUTPUT + +O_OBJECT + sv_setref_pv( $arg, CLASS, (void*)$var ); + +INPUT + +O_OBJECT + if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) + $var = ($type)SvIV((SV*)SvRV( $arg )); + else{ + warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" ); + XSRETURN_UNDEF; + } + +END + + 'XSCPP-Test/t/is_even.t' => <<'END', +#!/usr/bin/perl -w + +use Test::More tests => 3; + +use_ok "XSCPP::Test"; +my $o = XSCPP::Test->new; +ok !$o->is_even(1); +ok $o->is_even(2); +END + ); + + +sub setup_xs { + setup_mm_test_root(); + chdir 'MM_TEST_ROOT:[t]' if $Is_VMS; + + while(my($file, $text) = each %Files) { + # Convert to a relative, native file path. + $file = File::Spec->catfile(File::Spec->curdir, split m{\/}, $file); + + my $dir = dirname($file); + mkpath $dir; + open(FILE, ">$file") || die "Can't create $file: $!"; + print FILE $text; + close FILE; + } + + return 1; +} + +sub teardown_xs { + foreach my $file (keys %Files) { + my $dir = dirname($file); + if( -e $dir ) { + rmtree($dir) || return; + } + } + return 1; +} + +1; diff --git a/t/xscpp.t b/t/xscpp.t new file mode 100644 index 000000000..b7fe228ee --- /dev/null +++ b/t/xscpp.t @@ -0,0 +1,58 @@ +#!/usr/bin/perl -w + +BEGIN { + unshift @INC, 't/lib/'; +} +chdir 't'; + +use strict; + +use Test::More; +use MakeMaker::Test::Utils; +use MakeMaker::Test::Setup::XSCPP; +use File::Find; +use File::Spec; +use File::Path; + +my $Skipped = 0; +if( have_compiler() ) { + plan tests => 5; +} +else { + $Skipped = 1; + plan skip_all => "ExtUtils::CBuilder not installed or couldn't find a compiler"; +} + +my $Is_VMS = $^O eq 'VMS'; +my $perl = which_perl(); + +chdir 't'; + +perl_lib; + +$| = 1; + +ok( setup_xs(), 'setup' ); +END { + unless( $Skipped ) { + chdir File::Spec->updir or die; + teardown_xs(), 'teardown' or die; + } +} + +ok( chdir('XSCPP-Test'), "chdir'd to XSCPP-Test" ) || + diag("chdir failed: $!"); + +my @mpl_out = run(qq{$perl Makefile.PL}); + +cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) || + diag(@mpl_out); + +my $make = make_run(); +my $make_out = run("$make"); +is( $?, 0, ' make exited normally' ) || + diag $make_out; + +my $test_out = run("$make"); +is( $?, 0, ' make test exited normally' ) || + diag $test_out; From 0f6ee3e23e83ca41b9e96a2484b19c6a521e31a4 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Feb 2013 23:26:17 +0400 Subject: [PATCH 02/17] Documentation for XSTARGET_EXT Plus try fix all other xs_c,xs_o methods (only in VMS really). --- lib/ExtUtils/MM_Unix.pm | 3 ++- lib/ExtUtils/MM_VMS.pm | 8 ++++---- lib/ExtUtils/MakeMaker.pm | 5 +++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/ExtUtils/MM_Unix.pm b/lib/ExtUtils/MM_Unix.pm index 03d7a0ba8..149830835 100644 --- a/lib/ExtUtils/MM_Unix.pm +++ b/lib/ExtUtils/MM_Unix.pm @@ -3592,7 +3592,8 @@ sub writedoc { =item xs_c (o) -Defines the suffix rules to compile XS files to C. +Defines the suffix rules to compile XS files to C (or to C++ +if XSTARGET_EXT set to ".cpp"). =cut diff --git a/lib/ExtUtils/MM_VMS.pm b/lib/ExtUtils/MM_VMS.pm index 254836738..47124d33d 100644 --- a/lib/ExtUtils/MM_VMS.pm +++ b/lib/ExtUtils/MM_VMS.pm @@ -905,8 +905,8 @@ sub xs_c { my($self) = @_; return '' unless $self->needs_linking(); ' -.xs.c : - $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET) +.xs$(XSTARGET_EXT) : + $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME)$(XSTARGET_EXT) '; } @@ -921,8 +921,8 @@ sub xs_o { # many makes are too dumb to use xs_c then c_o return '' unless $self->needs_linking(); ' .xs$(OBJ_EXT) : - $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c - $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c + $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME)$(XSTARGET_EXT) + $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME)$(XSTARGET_EXT) '; } diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index f7fdacba2..3cce5f8d8 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -2523,6 +2523,11 @@ May be set to an empty string, which is identical to C<-prototypes>, or C<-noprototypes>. See the xsubpp documentation for details. MakeMaker defaults to the empty string. +=item XSTARGET_EXT + +Suffix for files produced from .xs files. It is .c by default. But can be +set to .cpp if you xs code contains C++. + =item XS_VERSION Your version number for the .xs file of this package. This defaults From ff88943be8c1d1ea227159466b00a691c992a381 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Feb 2013 23:50:55 +0400 Subject: [PATCH 03/17] Now C++ support should be done. This commit skips t/xscpp.t tests if user has no C++ compiler. --- t/lib/MakeMaker/Test/Utils.pm | 32 +++++++++++++++++++++++++++++++- t/xscpp.t | 4 ++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/t/lib/MakeMaker/Test/Utils.pm b/t/lib/MakeMaker/Test/Utils.pm index 9a6ab60e3..02ecd04b1 100644 --- a/t/lib/MakeMaker/Test/Utils.pm +++ b/t/lib/MakeMaker/Test/Utils.pm @@ -14,7 +14,7 @@ our $Is_FreeBSD = $^O eq 'freebsd'; our @EXPORT = qw(which_perl perl_lib makefile_name makefile_backup make make_run run make_macro calibrate_mtime setup_mm_test_root - have_compiler slurp + have_compiler have_cplusplus slurp $Is_VMS $Is_MacOS run_ok ); @@ -390,6 +390,36 @@ sub have_compiler { return $have_compiler; } +=item have_cplusplus + + $have_compiler = have_cplusplus; + +Returns true if there is a C++ compiler available for XS builds. + +=cut + +sub have_cplusplus { + my $have_cplusplus = 0; + + # ExtUtils::CBuilder prints its compilation lines to the screen. + # Shut it up. + use TieOut; + local *STDOUT = *STDOUT; + local *STDERR = *STDERR; + + tie *STDOUT, 'TieOut'; + tie *STDERR, 'TieOut'; + + eval { + require ExtUtils::CBuilder; + my $cb = ExtUtils::CBuilder->new; + + $have_cplusplus = $cb->have_cplusplus; + }; + + return $have_cplusplus; +} + =item slurp $contents = slurp($filename); diff --git a/t/xscpp.t b/t/xscpp.t index b7fe228ee..8859c057d 100644 --- a/t/xscpp.t +++ b/t/xscpp.t @@ -15,12 +15,12 @@ use File::Spec; use File::Path; my $Skipped = 0; -if( have_compiler() ) { +if( have_cplusplus() ) { plan tests => 5; } else { $Skipped = 1; - plan skip_all => "ExtUtils::CBuilder not installed or couldn't find a compiler"; + plan skip_all => "ExtUtils::CBuilder not installed or couldn't find a C++ compiler"; } my $Is_VMS = $^O eq 'VMS'; From b40be0be5acaa147304cce1ee9aa82166bf20ae2 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Mar 2013 13:22:45 +0400 Subject: [PATCH 04/17] Fix warning: "XSTARGET_EXT" is not a known parameter --- lib/ExtUtils/MakeMaker.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index 3cce5f8d8..ce2fbb4a4 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -282,8 +282,8 @@ sub full_setup { PL_FILES PM PM_FILTER PMLIBDIRS PMLIBPARENTDIRS POLLUTE PPM_INSTALL_EXEC PPM_INSTALL_SCRIPT PREREQ_FATAL PREREQ_PM PREREQ_PRINT PRINT_PREREQ SIGN SKIP TEST_REQUIRES TYPEMAPS VERSION VERSION_FROM XS XSOPT XSPROTOARG - XS_VERSION clean depend dist dynamic_lib linkext macro realclean - tool_autosplit + XSTARGET_EXT XS_VERSION clean depend dist dynamic_lib linkext macro + realclean tool_autosplit MACPERL_SRC MACPERL_LIB MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED From 84d359015bf1830dacfd5ce441a95bce183d6dc3 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Mar 2013 13:29:37 +0400 Subject: [PATCH 05/17] Fix formatting (tabs -> spaces). --- t/lib/MakeMaker/Test/Utils.pm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/t/lib/MakeMaker/Test/Utils.pm b/t/lib/MakeMaker/Test/Utils.pm index 02ecd04b1..655f553c2 100644 --- a/t/lib/MakeMaker/Test/Utils.pm +++ b/t/lib/MakeMaker/Test/Utils.pm @@ -381,10 +381,10 @@ sub have_compiler { tie *STDERR, 'TieOut'; eval { - require ExtUtils::CBuilder; - my $cb = ExtUtils::CBuilder->new; + require ExtUtils::CBuilder; + my $cb = ExtUtils::CBuilder->new; - $have_compiler = $cb->have_compiler; + $have_compiler = $cb->have_compiler; }; return $have_compiler; @@ -411,10 +411,10 @@ sub have_cplusplus { tie *STDERR, 'TieOut'; eval { - require ExtUtils::CBuilder; - my $cb = ExtUtils::CBuilder->new; + require ExtUtils::CBuilder; + my $cb = ExtUtils::CBuilder->new; - $have_cplusplus = $cb->have_cplusplus; + $have_cplusplus = $cb->have_cplusplus; }; return $have_cplusplus; From 87931ea269b0cd5bd8261cc8cb0fdac3376dffe4 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sun, 17 Mar 2013 18:56:48 +0400 Subject: [PATCH 06/17] Add some documentation to FAQ about building XS with C++ compiler, also improve formatting for XSTARGET_EXT option description --- lib/ExtUtils/MakeMaker.pm | 4 ++-- lib/ExtUtils/MakeMaker/FAQ.pod | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index ce2fbb4a4..2cfe31ac0 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -2525,8 +2525,8 @@ defaults to the empty string. =item XSTARGET_EXT -Suffix for files produced from .xs files. It is .c by default. But can be -set to .cpp if you xs code contains C++. +Suffix for files produced from F<.xs> files. It is F<.c> by default. But can be +set to F<.cpp> if you xs code contains C++. =item XS_VERSION diff --git a/lib/ExtUtils/MakeMaker/FAQ.pod b/lib/ExtUtils/MakeMaker/FAQ.pod index c14acdf42..ad35382f5 100644 --- a/lib/ExtUtils/MakeMaker/FAQ.pod +++ b/lib/ExtUtils/MakeMaker/FAQ.pod @@ -443,6 +443,35 @@ And of course a very basic test: This tip has been brought to you by Nick Ing-Simmons and Stas Bekman. +=item How can I build my xs files as C++ + +Traditionally, language of source files determined by suffix (eg. F<.c> - C, +F<.cpp> or F<.cc> is C++), so you need to say to MakeMaker that it should make +files with appropriate suffix from you F<.xs> files. It can be done by using +C option. Something like: + + Makefile.PL: + -------- + use ExtUtils::MakeMaker; + + WriteMakefile( + NAME => 'Foo', + VERSION_FROM => 'Foo.pm', + OBJECT => q/$(O_FILES)/, + XSTARGET_EXT => '.cpp', + XSOPT => '-C++ -nolinenumbers', + # ... other attrs ... + ); + +B: If you already have F<.c> files generated before switch suffix, +you need to remove these files manually, or MakeMaker detects they and add +to build. That will lead to strange link errors. + +B: You probably want to disable file/line numbers info placed in +generated file because C knows nothing about generated file suffix +and uses F<.c> unconditionally. To do this, add C<-nolinenumbers> to +C option. + =back =head1 PATCHING From 9cb5b00c565caf49d6eb517cecb2e2c2997f801f Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Mon, 18 Mar 2013 08:34:21 +0400 Subject: [PATCH 07/17] Fix grammar as pointed by schwern --- lib/ExtUtils/MakeMaker.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index 2cfe31ac0..c396e8d65 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -2525,7 +2525,7 @@ defaults to the empty string. =item XSTARGET_EXT -Suffix for files produced from F<.xs> files. It is F<.c> by default. But can be +Suffix for files produced from F<.xs> files. It is F<.c> by default, but can be set to F<.cpp> if you xs code contains C++. =item XS_VERSION From 9755bf4d55f033b5d2663b82f40b6d778ad29818 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sun, 24 Mar 2013 11:55:50 +0400 Subject: [PATCH 08/17] Grammar check --- lib/ExtUtils/MakeMaker/FAQ.pod | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/ExtUtils/MakeMaker/FAQ.pod b/lib/ExtUtils/MakeMaker/FAQ.pod index ad35382f5..edeefc451 100644 --- a/lib/ExtUtils/MakeMaker/FAQ.pod +++ b/lib/ExtUtils/MakeMaker/FAQ.pod @@ -445,10 +445,11 @@ This tip has been brought to you by Nick Ing-Simmons and Stas Bekman. =item How can I build my xs files as C++ -Traditionally, language of source files determined by suffix (eg. F<.c> - C, -F<.cpp> or F<.cc> is C++), so you need to say to MakeMaker that it should make -files with appropriate suffix from you F<.xs> files. It can be done by using -C option. Something like: +Traditionally the language of source files is determined by suffix +(e.g. F<.c>- C, F<.cpp> or F<.cc> is C++), +so you need to tell MakeMaker that it should make files with an appropriate +suffix from your F<.xs> files. It can be done by using +C option. For example: Makefile.PL: -------- @@ -463,13 +464,13 @@ C option. Something like: # ... other attrs ... ); -B: If you already have F<.c> files generated before switch suffix, -you need to remove these files manually, or MakeMaker detects they and add -to build. That will lead to strange link errors. +B: If you have already generated F<.c> files before switching +the suffix, you need to remove these files manually, otherwise MakeMaker will +detect them and add to build. That will lead to strange errors from linker. -B: You probably want to disable file/line numbers info placed in -generated file because C knows nothing about generated file suffix -and uses F<.c> unconditionally. To do this, add C<-nolinenumbers> to +B: You will probably need to disable file/line numbers info placed in +the generated file because C knows nothing about the generated file +suffix and uses F<.c> unconditionally. To do this, add C<-nolinenumbers> to C option. =back From 41d56d755372c8a04230370bbc2cfb4950303478 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Mon, 8 Apr 2013 02:34:06 +0400 Subject: [PATCH 09/17] Improve tests Use quiet mode of the ExtUtils::CBuilder instead of magic with STDOUT/STDERR --- t/lib/MakeMaker/Test/Utils.pm | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/t/lib/MakeMaker/Test/Utils.pm b/t/lib/MakeMaker/Test/Utils.pm index 655f553c2..d99537e4c 100644 --- a/t/lib/MakeMaker/Test/Utils.pm +++ b/t/lib/MakeMaker/Test/Utils.pm @@ -371,18 +371,9 @@ Returns true if there is a compiler available for XS builds. sub have_compiler { my $have_compiler = 0; - # ExtUtils::CBuilder prints its compilation lines to the screen. - # Shut it up. - use TieOut; - local *STDOUT = *STDOUT; - local *STDERR = *STDERR; - - tie *STDOUT, 'TieOut'; - tie *STDERR, 'TieOut'; - eval { require ExtUtils::CBuilder; - my $cb = ExtUtils::CBuilder->new; + my $cb = ExtUtils::CBuilder->new(quiet=>1); $have_compiler = $cb->have_compiler; }; @@ -401,18 +392,9 @@ Returns true if there is a C++ compiler available for XS builds. sub have_cplusplus { my $have_cplusplus = 0; - # ExtUtils::CBuilder prints its compilation lines to the screen. - # Shut it up. - use TieOut; - local *STDOUT = *STDOUT; - local *STDERR = *STDERR; - - tie *STDOUT, 'TieOut'; - tie *STDERR, 'TieOut'; - eval { require ExtUtils::CBuilder; - my $cb = ExtUtils::CBuilder->new; + my $cb = ExtUtils::CBuilder->new(quiet=>1); $have_cplusplus = $cb->have_cplusplus; }; From c0aa37c065adc3b4933672a18bec957e336b0638 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Mon, 8 Apr 2013 02:40:44 +0400 Subject: [PATCH 10/17] Improve xscpp.t Remove preprocessor tests for __cplusplus, we already know that this is C++ --- t/lib/MakeMaker/Test/Setup/XSCPP.pm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/t/lib/MakeMaker/Test/Setup/XSCPP.pm b/t/lib/MakeMaker/Test/Setup/XSCPP.pm index 637b3e73f..4ef1175ea 100644 --- a/t/lib/MakeMaker/Test/Setup/XSCPP.pm +++ b/t/lib/MakeMaker/Test/Setup/XSCPP.pm @@ -38,16 +38,10 @@ WriteMakefile( END 'XSCPP-Test/Test.xs' => <<'END', -#ifdef __cplusplus extern "C" { -#endif - #include "EXTERN.h" #include "perl.h" - -#ifdef __cplusplus } -#endif #include "XSUB.h" From a2d15ba82ba6b243aa7382dcfef42bf9d9f9b1d5 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Mon, 8 Apr 2013 02:57:46 +0400 Subject: [PATCH 11/17] Fix xs.t and xscpp.t 1. Make xs.t and xscpp.t really run "make test" 2. Fix XSCPP module Makefile.PL to add libstdc++ to link --- t/lib/MakeMaker/Test/Setup/XSCPP.pm | 1 + t/xs.t | 2 +- t/xscpp.t | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/t/lib/MakeMaker/Test/Setup/XSCPP.pm b/t/lib/MakeMaker/Test/Setup/XSCPP.pm index 4ef1175ea..b40efe9f8 100644 --- a/t/lib/MakeMaker/Test/Setup/XSCPP.pm +++ b/t/lib/MakeMaker/Test/Setup/XSCPP.pm @@ -34,6 +34,7 @@ WriteMakefile( NAME => 'XSCPP::Test', VERSION_FROM => 'lib/XSCPP/Test.pm', XSTARGET_EXT => '.cpp', + LIBS => ['-lstdc++'], ); END diff --git a/t/xs.t b/t/xs.t index efd682edf..5cb17c2fe 100644 --- a/t/xs.t +++ b/t/xs.t @@ -53,6 +53,6 @@ my $make_out = run("$make"); is( $?, 0, ' make exited normally' ) || diag $make_out; -my $test_out = run("$make"); +my $test_out = run("$make test"); is( $?, 0, ' make test exited normally' ) || diag $test_out; diff --git a/t/xscpp.t b/t/xscpp.t index 8859c057d..6fe941a76 100644 --- a/t/xscpp.t +++ b/t/xscpp.t @@ -53,6 +53,6 @@ my $make_out = run("$make"); is( $?, 0, ' make exited normally' ) || diag $make_out; -my $test_out = run("$make"); +my $test_out = run("$make test"); is( $?, 0, ' make test exited normally' ) || diag $test_out; From b1728d3843e04837c21119c556628cf00b5af33d Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Tue, 12 Aug 2014 17:42:56 +0400 Subject: [PATCH 12/17] Fix tests after sync with upstream. --- t/lib/MakeMaker/Test/Setup/XSCPP.pm | 2 -- 1 file changed, 2 deletions(-) diff --git a/t/lib/MakeMaker/Test/Setup/XSCPP.pm b/t/lib/MakeMaker/Test/Setup/XSCPP.pm index b40efe9f8..914ad28de 100644 --- a/t/lib/MakeMaker/Test/Setup/XSCPP.pm +++ b/t/lib/MakeMaker/Test/Setup/XSCPP.pm @@ -103,8 +103,6 @@ END sub setup_xs { - setup_mm_test_root(); - chdir 'MM_TEST_ROOT:[t]' if $Is_VMS; while(my($file, $text) = each %Files) { # Convert to a relative, native file path. From 9f430d7ea0354ded575c5d626c985c8a9d1c8772 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Aug 2014 10:27:34 +0400 Subject: [PATCH 13/17] Modernize t/xscpp.t test, make it look more like t/xs.t --- t/xscpp.t | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/t/xscpp.t b/t/xscpp.t index 6fe941a76..6c5c8178e 100644 --- a/t/xscpp.t +++ b/t/xscpp.t @@ -7,22 +7,16 @@ chdir 't'; use strict; -use Test::More; use MakeMaker::Test::Utils; use MakeMaker::Test::Setup::XSCPP; +use Test::More + have_cplusplus() + ? (tests => 5) + : (skip_all => "ExtUtils::CBuilder not installed or couldn't find a C++ compiler"); use File::Find; use File::Spec; use File::Path; -my $Skipped = 0; -if( have_cplusplus() ) { - plan tests => 5; -} -else { - $Skipped = 1; - plan skip_all => "ExtUtils::CBuilder not installed or couldn't find a C++ compiler"; -} - my $Is_VMS = $^O eq 'VMS'; my $perl = which_perl(); @@ -34,10 +28,8 @@ $| = 1; ok( setup_xs(), 'setup' ); END { - unless( $Skipped ) { - chdir File::Spec->updir or die; - teardown_xs(), 'teardown' or die; - } + chdir File::Spec->updir or die; + teardown_xs(), 'teardown' or die; } ok( chdir('XSCPP-Test'), "chdir'd to XSCPP-Test" ) || From e1a363ef10a0b1abf085d50bfff045845a4fa81b Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Aug 2014 10:59:17 +0400 Subject: [PATCH 14/17] whitespace fixes --- lib/ExtUtils/MakeMaker/FAQ.pod | 6 +++--- t/lib/MakeMaker/Test/Setup/XSCPP.pm | 2 +- t/xscpp.t | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ExtUtils/MakeMaker/FAQ.pod b/lib/ExtUtils/MakeMaker/FAQ.pod index fc680f288..43d81cecb 100644 --- a/lib/ExtUtils/MakeMaker/FAQ.pod +++ b/lib/ExtUtils/MakeMaker/FAQ.pod @@ -448,7 +448,7 @@ This tip has been brought to you by Nick Ing-Simmons and Stas Bekman. =item How can I build my xs files as C++ -Traditionally the language of source files is determined by suffix +Traditionally the language of source files is determined by suffix (e.g. F<.c>- C, F<.cpp> or F<.cc> is C++), so you need to tell MakeMaker that it should make files with an appropriate suffix from your F<.xs> files. It can be done by using @@ -459,8 +459,8 @@ C option. For example: use ExtUtils::MakeMaker; WriteMakefile( - NAME => 'Foo', - VERSION_FROM => 'Foo.pm', + NAME => 'Foo', + VERSION_FROM => 'Foo.pm', OBJECT => q/$(O_FILES)/, XSTARGET_EXT => '.cpp', XSOPT => '-C++ -nolinenumbers', diff --git a/t/lib/MakeMaker/Test/Setup/XSCPP.pm b/t/lib/MakeMaker/Test/Setup/XSCPP.pm index 914ad28de..8b168dd83 100644 --- a/t/lib/MakeMaker/Test/Setup/XSCPP.pm +++ b/t/lib/MakeMaker/Test/Setup/XSCPP.pm @@ -118,7 +118,7 @@ sub setup_xs { return 1; } -sub teardown_xs { +sub teardown_xs { foreach my $file (keys %Files) { my $dir = dirname($file); if( -e $dir ) { diff --git a/t/xscpp.t b/t/xscpp.t index 6c5c8178e..af72ec17e 100644 --- a/t/xscpp.t +++ b/t/xscpp.t @@ -42,9 +42,9 @@ cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) || my $make = make_run(); my $make_out = run("$make"); -is( $?, 0, ' make exited normally' ) || +is( $?, 0, ' make exited normally' ) || diag $make_out; my $test_out = run("$make test"); -is( $?, 0, ' make test exited normally' ) || +is( $?, 0, ' make test exited normally' ) || diag $test_out; From 905ac570ec37adaaf40ab3e56892203bccaa4f45 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Aug 2014 11:25:00 +0400 Subject: [PATCH 15/17] Disable full compilation test of XS with C++. Only check that generated Makefile contains new XSTARGET_EXT variable, and that variable used in xsubpp call. --- t/xscpp.t | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/t/xscpp.t b/t/xscpp.t index af72ec17e..36250e620 100644 --- a/t/xscpp.t +++ b/t/xscpp.t @@ -9,10 +9,14 @@ use strict; use MakeMaker::Test::Utils; use MakeMaker::Test::Setup::XSCPP; -use Test::More - have_cplusplus() - ? (tests => 5) - : (skip_all => "ExtUtils::CBuilder not installed or couldn't find a C++ compiler"); + +# Disable full compilation test for now. +# TODO: Until some consensus in community will reached. +# use Test::More +# have_cplusplus() +# ? (tests => 5) +# : (skip_all => "ExtUtils::CBuilder not installed or couldn't find a C++ compiler"); +use Test::More tests => 5; use File::Find; use File::Spec; use File::Path; @@ -40,11 +44,17 @@ my @mpl_out = run(qq{$perl Makefile.PL}); cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) || diag(@mpl_out); -my $make = make_run(); -my $make_out = run("$make"); -is( $?, 0, ' make exited normally' ) || - diag $make_out; - -my $test_out = run("$make test"); -is( $?, 0, ' make test exited normally' ) || - diag $test_out; +my $mf_content = slurp(makefile_name()); +like( $mf_content, qr/\bXSTARGET_EXT\b\s*=\s*\.cpp\b/, 'Makefile: XSTARGET_EXT has right value' ); +like( $mf_content, qr/\bXSUBPPRUN\b.+\bXSTARGET_EXT\b/, 'Makefile: seems xsubpp generate file with .cpp suffix' ); + +# Disable full compilation test for now. +# TODO: Until some consensus in community will reached. +# my $make = make_run(); +# my $make_out = run("$make"); +# is( $?, 0, ' make exited normally' ) || +# diag $make_out; +# +# my $test_out = run("$make test"); +# is( $?, 0, ' make test exited normally' ) || +# diag $test_out; From 6d982a0510a57c657effb01e32ac746e9aff3463 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sat, 16 Aug 2014 11:34:39 +0400 Subject: [PATCH 16/17] Add note that this is not full solution to FAQ --- lib/ExtUtils/MakeMaker/FAQ.pod | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ExtUtils/MakeMaker/FAQ.pod b/lib/ExtUtils/MakeMaker/FAQ.pod index 43d81cecb..1eb1c60d3 100644 --- a/lib/ExtUtils/MakeMaker/FAQ.pod +++ b/lib/ExtUtils/MakeMaker/FAQ.pod @@ -467,6 +467,9 @@ C option. For example: # ... other attrs ... ); +B: This solution is not crossplatform. Should work with gcc and clang, +but probably will require more tuning (e.g. will need linking with libstdc++). + B: If you have already generated F<.c> files before switching the suffix, you need to remove these files manually, otherwise MakeMaker will detect them and add to build. That will lead to strange errors from linker. From 0e9bede959cc15965de8f80ed00c6c4b2a379fb6 Mon Sep 17 00:00:00 2001 From: Vladimir Timofeev Date: Sun, 17 Aug 2014 01:25:03 +0400 Subject: [PATCH 17/17] Add references to useful modules that can help configure project to use C++ --- lib/ExtUtils/MakeMaker/FAQ.pod | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ExtUtils/MakeMaker/FAQ.pod b/lib/ExtUtils/MakeMaker/FAQ.pod index 1eb1c60d3..edccecd4d 100644 --- a/lib/ExtUtils/MakeMaker/FAQ.pod +++ b/lib/ExtUtils/MakeMaker/FAQ.pod @@ -469,6 +469,9 @@ C option. For example: B: This solution is not crossplatform. Should work with gcc and clang, but probably will require more tuning (e.g. will need linking with libstdc++). +Other modules that you may find helpful to configure your project to work +across a range of C++ compilers and platforms include: L, +L and L. B: If you have already generated F<.c> files before switching the suffix, you need to remove these files manually, otherwise MakeMaker will