File Coverage

blib/lib/ExtUtils/CXX.pm
Criterion Covered Total %
statement 34 36 94.4
branch 4 8 50.0
condition 1 3 33.3
subroutine 6 6 100.0
pod 1 1 100.0
total 46 54 85.1


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             ExtUtils::CXX - support C++ XS files
4              
5             =head1 SYNOPSIS
6              
7             use ExtUtils::CXX;
8             use ExtUtils::MakeMaker;
9              
10             # wrap calls to WriteMakefile or MakeMaker that are supposed to use
11             # C++ XS files into extutils_cxx blocks:
12              
13             extutils_cxx {
14             WriteMakefile (
15             ... put your normal args here
16             );
17             };
18              
19             =head1 DESCRIPTION
20              
21             This module enables XS extensions written in C++. It is meant to be useful
22             for the users and installers of c++ modules, rather than the authors, by
23             having a single central place where to patch things, rather than to have
24             to patch every single module that overrides CC manually. That is, in the
25             worst case, you need to patch this module for your environment before
26             being able to CPAN-install further C++ modules; commonly, only setting a
27             few ENV variables is enough; and in the best case, it just works out of
28             the box.
29              
30             (Comments on what to do and suggestions on how to achieve these things
31             better are welcome).
32              
33             At the moment, it works by changing the values in C<%Config::Config>
34             temporarily. It does the following things:
35              
36             =over 4
37              
38             =item 1. It tries to change C<$Config{cc}> and C<$Config{ld}> into a C++ compiler.
39              
40             If the environment variable C<$CXX> is set, then it's value will be used
41             to replace both (except if C<$PERL_CXXLD> is set, then that will be used for
42             C<$Config{ld}>.
43              
44             (There is also a C<$PERL_CXX> which takes precedence over C<$CXX>).
45              
46             The important thing is that the chosen C++ compiler compiles files with
47             a F<.c> ending as C++ - a generic compiler wrapper such as F that
48             detects the lafguage by the file extension will I work.
49              
50             In the absence of these variables, it will do the following
51             transformations on what it guesses will be the compiler name:
52              
53             gcc => g++
54             clang => clang++
55             xlc => xlC
56             cc => g++
57             c89 => g++
58              
59             =back
60              
61             =over 4
62              
63             =cut
64              
65             package ExtUtils::CXX;
66              
67 1     1   1191 use common::sense;
  1         14  
  1         6  
68              
69             our $VERSION = '1.0';
70              
71 1     1   87 use Exporter 'import';
  1         3  
  1         70  
72              
73             our @EXPORT = qw(extutils_cxx);
74              
75 1     1   500 use ExtUtils::MakeMaker::Config ();
  1         47979  
  1         115  
76              
77             =item extutils_cxx BLOCK;
78              
79             This function temporarily does hideous things so you can call
80             C or similar functions in the BLOCK normally. See the
81             description, above, for more details.
82              
83             =cut
84              
85 1     1   10 use Config;
  1         1  
  1         443  
86              
87             our %cc = (
88             gcc => "g++",
89             clang => "clang++",
90             xlc => "xlC",
91             cc => "g++",
92             c89 => "g++",
93             );
94              
95             our $PREFIX = qr{(?:\S+[\/\\])? (?:ccache|distcc)}x;
96              
97             sub _ccrepl {
98 2     2   5 my ($cfgvar, $env) = @_;
99              
100 2         3 my $tie = tied %Config;
101              
102 2   33     12 my $env = $ENV{"PERL_$env"} || $ENV{$env};
103              
104 2         3 my $val = $tie->{$cfgvar};
105              
106 2 50       5 if ($env) {
107 0         0 $val =~ s/^\S+/$env/;
108             } else {
109 2         3 keys %cc;
110 2         7 while (my ($k, $v) = each %cc) {
111 2 50       68 $val =~ s/^ ((?:$PREFIX\s+)? \S*[\/\\])? $k (-|\s|\d|$) /$1$v$2/x
112             and goto done;
113             }
114              
115 0         0 $val =~ s/^($PREFIX\s+)? \S+/$1g++/x;
116              
117 2         5 done: ;
118             }
119              
120 2         5 $tie->{$cfgvar} = $val;
121             }
122              
123             sub extutils_cxx(&) {
124 1     1 1 8 my ($cb) = @_;
125              
126             # make sure these exist
127 1         5 @Config{qw(cc ld)};
128              
129 1         2 my $tie = tied %Config;
130              
131             # now dive into internals of Config and temporarily patch those values
132              
133 1         12 local $tie->{cc} = $Config{cc}; _ccrepl cc => "CXX";
  1         5  
134 1 50       7 local $tie->{ld} = $Config{ld}; _ccrepl ld => ($ENV{PERL_CXXLD} ? "CXXLD" : "CXX");
  1         5  
135              
136 1         3 local $ExtUtils::MakeMaker::Config::Config{cc} = $tie->{cc};
137 1         3 local $ExtUtils::MakeMaker::Config::Config{ld} = $tie->{ld};
138              
139 1         2 eval {
140 1         3 $cb->();
141             };
142 1 50       5 die if $@;
143             }
144              
145             =back
146              
147             =head2 WHAT YOU HAVE TO DO
148              
149             This module only makes your F<.xs> files compile as C++. It does not
150             provide magic C++ support for objects and typemaps, and does not help with
151             portability or writing your F<.xs> file. All of these you have to do -
152             google is your friend.
153              
154             =head2 LIMITATIONS
155              
156             Combining C++ and C is an art form in itself, and there is simply no
157             portable way to make it work - the platform might have a C compiler, but
158             no C++ compiler. The C++ compiler might be binary incompatible to the C
159             compiler, or might not run for other reasons, and in the end, C++ is more
160             of a moving target than C.
161              
162             =head2 SEE ALSO
163              
164             There is a module called C that says it gives you C++ in
165             XS, by changing XS in some ways. I don't know what exactly it's purpose
166             is, but it might be a useful addition for C++ Xs development for you,
167             so you might want to look at it. It doesn't have C
168             support, and there is a companion module that only supports the obsolete
169             (and very broken) C, sour YMMV.
170              
171             =head1 AUTHOR/CONTACT
172              
173             Marc Lehmann
174             http://software.schmorp.de/pkg/extutils-cxx.html
175              
176             =cut
177              
178             1
179