@@ -10,6 +10,24 @@ use File::Basename qw(basename dirname);
1010use DirHandle;
1111
1212our %Config_Override ;
13+ our %XS_ext2src = qw(
14+ xs c
15+ ) ;
16+ my $xspat = join ' |' , keys %XS_ext2src ;
17+ our $XS_extRE = qr /\. ($xspat )\z / ;
18+
19+ sub _xs_list_basenames {
20+ my ($self ) = @_ ;
21+ map { (my $b = $_ ) =~ s / $XS_extRE// ; $b } sort keys %{ $self -> {XS } };
22+ }
23+
24+ sub _xs_basename2xs {
25+ my ($self , $ext ) = @_ ;
26+ for my $xs_ext (keys %XS_ext2src ) {
27+ return " $ext .$xs_ext " if exists $self -> {XS }{" $ext .$xs_ext " };
28+ }
29+ Carp::confess " PANIC: shouldn't get here" ;
30+ }
1331
1432use ExtUtils::MakeMaker qw( $Verbose neatvalue _sprintf562) ;
1533
@@ -1369,10 +1387,11 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc)
13691387 next if -l $name ; # We do not support symlinks at all
13701388 next if $self -> {NORECURS };
13711389 $dir {$name } = $name if (-f File::Spec-> catfile($name ," Makefile.PL" ));
1372- } elsif ($name =~ / \. xs\z / ){
1373- my ($c ); ($c = $name ) =~ s /\. xs\z / .c/ ;
1374- $xs {$name } = $c ;
1375- $c {$c } = 1;
1390+ } elsif ($name =~ $XS_extRE ){
1391+ my $xs_ext = $1 ;
1392+ my ($src ); ($src = $name ) =~ s /\. $xs_ext\z / .$XS_ext2src {$xs_ext }/ ;
1393+ $xs {$name } = $src ;
1394+ $c {$src } = 1;
13761395 } elsif ($name =~ / \. c(pp|xx|c)?\z /i ){ # .c .C .cpp .cxx .cc
13771396 $c {$name } = 1
13781397 unless $name =~ m / perlmain\. c/ ; # See MAP_TARGET
@@ -1617,11 +1636,13 @@ sub init_PM {
16171636 $inst = $self -> libscan($inst );
16181637 print " libscan($path ) => '$inst '\n " if ($Verbose >= 2);
16191638 return unless $inst ;
1620- if ($self -> {XSMULTI } and $inst =~ / \. xs\z / ) {
1621- my ($base ); ($base = $path ) =~ s /\. xs\z // ;
1622- $self -> {XS }{$path } = " $base .c" ;
1623- push @{$self -> {C }}, " $base .c" ;
1624- push @{$self -> {O_FILES }}, " $base$self ->{OBJ_EXT}" ;
1639+ if ($self -> {XSMULTI } and $inst =~ $XS_extRE ) {
1640+ my $xs_ext = $1 ;
1641+ my ($src ); ($src = $path ) =~ s /\. $xs_ext\z / .$XS_ext2src {$xs_ext }/ ;
1642+ my ($obj ); ($obj = $path ) =~ s /\. $xs_ext\z / $self ->{OBJ_EXT}/ ;
1643+ $self -> {XS }{$path } = $src ;
1644+ push @{$self -> {C }}, $src ;
1645+ push @{$self -> {O_FILES }}, $obj ;
16251646 } else {
16261647 $self -> {PM }{$path } = $inst ;
16271648 }
@@ -3873,28 +3894,18 @@ Defines the suffix rules to compile XS files to C.
38733894
38743895sub xs_c {
38753896 my ($self ) = shift ;
3876- return ' ' unless $self -> needs_linking();
3877- '
3878- .xs.c:
3879- $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(XSUBPP_EXTRA_ARGS) $*.xs > $*.xsc
3880- $(MV) $*.xsc $*.c
3881- ' ;
3882- }
3883-
3884- =item xs_cpp (o)
3885-
3886- Defines the suffix rules to compile XS files to C++.
3887-
3888- =cut
3897+ return ' ' unless $self -> needs_linking;
3898+ my @m ;
3899+ for my $xs_ext (keys %XS_ext2src ) {
3900+ # 1 2
3901+ push @m , sprintf <<'EOF' , $xs_ext , $XS_ext2src {$xs_ext };
38893902
3890- sub xs_cpp {
3891- my ($self ) = shift ;
3892- return ' ' unless $self -> needs_linking();
3893- '
3894- .xs.cpp:
3895- $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.xsc
3896- $(MV) $*.xsc $*.cpp
3897- ' ;
3903+ .%1$s.%2$s:
3904+ $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(XSUBPP_EXTRA_ARGS) $*.%1$s > $*.xsc
3905+ $(MV) $*.xsc $*.%2$s
3906+ EOF
3907+ }
3908+ join ' ' , @m ;
38983909}
38993910
39003911=item xs_o (o)
@@ -3908,16 +3919,21 @@ have an individual C<$(VERSION)>.
39083919
39093920sub xs_o {
39103921 my ($self ) = @_ ;
3911- return ' ' unless $self -> needs_linking() ;
3922+ return ' ' unless $self -> needs_linking;
39123923 my $minus_o = $self -> xs_obj_opt(' $*$(OBJ_EXT)' );
3913- my $frag = ' ' ;
3924+ my @m ;
39143925 # dmake makes noise about ambiguous rule
3915- $frag .= sprintf <<'EOF' , $minus_o unless $self -> is_make_type(' dmake' );
3916- .xs$(OBJ_EXT) :
3917- $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.xsc
3918- $(MV) $*.xsc $*.c
3919- $(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c %s
3926+ my @xs_keys = $self -> is_make_type(' dmake' ) ? () : keys %XS_ext2src ;
3927+ for my $xs_ext (@xs_keys ) {
3928+ # 1 2 3
3929+ push @m , sprintf <<'EOF' , $xs_ext , $XS_ext2src {$xs_ext }, $minus_o ;
3930+
3931+ .%1$s$(OBJ_EXT) :
3932+ $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $*.%1$s > $*.xsc
3933+ $(MV) $*.xsc $*.%2$s
3934+ $(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.%2$s %3$s
39203935EOF
3936+ }
39213937 if ($self -> {XSMULTI }) {
39223938 for my $ext ($self -> _xs_list_basenames) {
39233939 my $pmfile = " $ext .pm" ;
@@ -3927,17 +3943,19 @@ EOF
39273943 $cccmd =~ s / ^\s *CCCMD\s *=\s *// ;
39283944 $cccmd =~ s /\$\( DEFINE_VERSION\) / -DVERSION=\\ "$version \\ "/ ;
39293945 $cccmd =~ s /\$\( XS_DEFINE_VERSION\) / -DXS_VERSION=\\ "$version \\ "/ ;
3930- # 1 2 3
3931- $frag .= _sprintf562 <<'EOF' , $ext , $cccmd , $minus_o ;
3932-
3933- %1$s$(OBJ_EXT): %1$s.xs
3934- $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.xsc
3935- $(MV) $*.xsc $*.c
3936- %2$s $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c %3$s
3946+ my $xs = $self -> _xs_basename2xs($ext );
3947+ my $src = $self -> {XS }{$xs };
3948+ # 1 2 3 4 5
3949+ push @m , _sprintf562 <<'EOF' , $ext , $cccmd , $xs , $src , $minus_o ;
3950+
3951+ %1$s$(OBJ_EXT) : %3$s
3952+ $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) %3$s > $*.xsc
3953+ $(MV) $*.xsc %4$s
3954+ %2$s $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) %4$s %5$s
39373955EOF
39383956 }
39393957 }
3940- $frag ;
3958+ join ' ' , @m ;
39413959}
39423960
39433961
0 commit comments