ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ExtUtils-CXX/CXX.pm
Revision: 1.5
Committed: Sun Apr 11 07:21:36 2021 UTC (3 years, 7 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +12 -10 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.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<gcc> that
48 root 1.4 detects the language by the file extension will I<not> work.
49 root 1.1
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 root 1.5 gcc => g++
54     clang => clang++
55     xlc => xlC
56     cc => g++
57     c89 => g++
58     perlcc => perlc++
59 root 1.1
60     =back
61    
62     =over 4
63    
64     =cut
65    
66     package ExtUtils::CXX;
67    
68     use common::sense;
69    
70 root 1.3 our $VERSION = '1.0';
71 root 1.1
72 root 1.2 use Exporter 'import';
73 root 1.1
74     our @EXPORT = qw(extutils_cxx);
75    
76 root 1.2 use ExtUtils::MakeMaker::Config ();
77    
78 root 1.1 =item extutils_cxx BLOCK;
79    
80     This function temporarily does hideous things so you can call
81     C<WriteMakefile> or similar functions in the BLOCK normally. See the
82     description, above, for more details.
83    
84     =cut
85    
86     use Config;
87    
88     our %cc = (
89 root 1.5 gcc => "g++",
90     clang => "clang++",
91     xlc => "xlC",
92     cc => "g++",
93     c89 => "g++",
94     perlcc => "perlc++",
95 root 1.1 );
96    
97 root 1.3 our $PREFIX = qr{(?:\S+[\/\\])? (?:ccache|distcc)}x;
98    
99 root 1.1 sub _ccrepl {
100     my ($cfgvar, $env) = @_;
101    
102     my $tie = tied %Config;
103    
104     my $env = $ENV{"PERL_$env"} || $ENV{$env};
105    
106     my $val = $tie->{$cfgvar};
107    
108     if ($env) {
109     $val =~ s/^\S+/$env/;
110     } else {
111     keys %cc;
112     while (my ($k, $v) = each %cc) {
113 root 1.3 $val =~ s/^ ((?:$PREFIX\s+)? \S*[\/\\])? $k (-|\s|\d|$) /$1$v$2/x
114 root 1.1 and goto done;
115     }
116    
117 root 1.3 $val =~ s/^($PREFIX\s+)? \S+/$1g++/x;
118 root 1.1
119     done: ;
120     }
121    
122     $tie->{$cfgvar} = $val;
123     }
124    
125     sub extutils_cxx(&) {
126     my ($cb) = @_;
127    
128     # make sure these exist
129     @Config{qw(cc ld)};
130    
131     my $tie = tied %Config;
132    
133     # now dive into internals of Config and temporarily patch those values
134    
135     local $tie->{cc} = $Config{cc}; _ccrepl cc => "CXX";
136     local $tie->{ld} = $Config{ld}; _ccrepl ld => ($ENV{PERL_CXXLD} ? "CXXLD" : "CXX");
137    
138 root 1.2 local $ExtUtils::MakeMaker::Config::Config{cc} = $tie->{cc};
139     local $ExtUtils::MakeMaker::Config::Config{ld} = $tie->{ld};
140    
141 root 1.1 eval {
142     $cb->();
143     };
144     die if $@;
145     }
146    
147     =back
148    
149     =head2 WHAT YOU HAVE TO DO
150    
151     This module only makes your F<.xs> files compile as C++. It does not
152     provide magic C++ support for objects and typemaps, and does not help with
153     portability or writing your F<.xs> file. All of these you have to do -
154     google is your friend.
155    
156     =head2 LIMITATIONS
157    
158     Combining C++ and C is an art form in itself, and there is simply no
159     portable way to make it work - the platform might have a C compiler, but
160     no C++ compiler. The C++ compiler might be binary incompatible to the C
161     compiler, or might not run for other reasons, and in the end, C++ is more
162     of a moving target than C.
163    
164     =head2 SEE ALSO
165    
166     There is a module called C<ExtUtils::XSpp> that says it gives you C++ in
167     XS, by changing XS in some ways. I don't know what exactly it's purpose
168     is, but it might be a useful addition for C++ Xs development for you,
169     so you might want to look at it. It doesn't have C<ExtUtils::MakeMaker>
170     support, and there is a companion module that only supports the obsolete
171     (and very broken) C<Module::Build>, sour YMMV.
172    
173     =head1 AUTHOR/CONTACT
174    
175     Marc Lehmann <schmorp@schmorp.de>
176     http://software.schmorp.de/pkg/extutils-cxx.html
177    
178     =cut
179    
180     1
181