line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Module::Install::XSUtil; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
22295
|
use 5.005_03; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
42
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
$VERSION = '0.45'; |
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
631
|
use Module::Install::Base; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
35
|
|
8
|
|
|
|
|
|
|
@ISA = qw(Module::Install::Base); |
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
26
|
|
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
6
|
use Config; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
42
|
|
13
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
5
|
use File::Spec; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
21
|
|
15
|
1
|
|
|
1
|
|
7
|
use File::Find; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
116
|
|
16
|
|
|
|
|
|
|
|
17
|
1
|
50
|
|
1
|
|
6
|
use constant _VERBOSE => $ENV{MI_VERBOSE} ? 1 : 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1203
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my %ConfigureRequires = ( |
20
|
|
|
|
|
|
|
'ExtUtils::ParseXS' => 3.18, # shipped with Perl 5.18.0 |
21
|
|
|
|
|
|
|
); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my %BuildRequires = ( |
24
|
|
|
|
|
|
|
); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my %Requires = ( |
27
|
|
|
|
|
|
|
'XSLoader' => 0.02, |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
my %ToInstall; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $UseC99 = 0; |
33
|
|
|
|
|
|
|
my $UseCplusplus = 0; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub _verbose{ |
36
|
0
|
|
|
0
|
|
|
print STDERR q{# }, @_, "\n"; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub _xs_debugging{ |
40
|
0
|
|
0
|
0
|
|
|
return $ENV{XS_DEBUG} || scalar( grep{ $_ eq '-g' } @ARGV ); |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub _xs_initialize{ |
44
|
0
|
|
|
0
|
|
|
my($self) = @_; |
45
|
|
|
|
|
|
|
|
46
|
0
|
0
|
|
|
|
|
unless($self->{xsu_initialized}){ |
47
|
0
|
|
|
|
|
|
$self->{xsu_initialized} = 1; |
48
|
|
|
|
|
|
|
|
49
|
0
|
0
|
|
|
|
|
if(!$self->cc_available()){ |
50
|
0
|
|
|
|
|
|
warn "This distribution requires a C compiler, but it's not available, stopped.\n"; |
51
|
0
|
|
|
|
|
|
exit; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
0
|
|
|
|
|
|
$self->configure_requires(%ConfigureRequires); |
55
|
0
|
|
|
|
|
|
$self->build_requires(%BuildRequires); |
56
|
0
|
|
|
|
|
|
$self->requires(%Requires); |
57
|
|
|
|
|
|
|
|
58
|
0
|
|
|
|
|
|
$self->makemaker_args->{OBJECT} = '$(O_FILES)'; |
59
|
0
|
|
|
|
|
|
$self->clean_files('$(O_FILES)'); |
60
|
0
|
0
|
|
|
|
|
$self->clean_files('*.stackdump') if $^O eq 'cygwin'; |
61
|
|
|
|
|
|
|
|
62
|
0
|
0
|
|
|
|
|
if($self->_xs_debugging()){ |
63
|
|
|
|
|
|
|
# override $Config{optimize} |
64
|
0
|
0
|
|
|
|
|
if(_is_msvc()){ |
65
|
0
|
|
|
|
|
|
$self->makemaker_args->{OPTIMIZE} = '-Zi'; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
else{ |
68
|
0
|
|
|
|
|
|
$self->makemaker_args->{OPTIMIZE} = '-g -ggdb -g3'; |
69
|
|
|
|
|
|
|
} |
70
|
0
|
|
|
|
|
|
$self->cc_define('-DXS_ASSERT'); |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
} |
73
|
0
|
|
|
|
|
|
return; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# GNU C Compiler |
77
|
|
|
|
|
|
|
sub _is_gcc{ |
78
|
0
|
|
|
0
|
|
|
return $Config{gccversion}; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Microsoft Visual C++ Compiler (cl.exe) |
82
|
|
|
|
|
|
|
sub _is_msvc{ |
83
|
0
|
|
|
0
|
|
|
return $Config{cc} =~ /\A cl \b /xmsi; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
{ |
87
|
|
|
|
|
|
|
my $cc_available; |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub cc_available { |
90
|
0
|
0
|
|
0
|
1
|
|
return defined $cc_available ? |
91
|
|
|
|
|
|
|
$cc_available : |
92
|
|
|
|
|
|
|
($cc_available = shift->can_cc()) |
93
|
|
|
|
|
|
|
; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# cf. https://github.com/sjn/toolchain-site/blob/219db464af9b2f19b04fec05547ac10180a469f3/lancaster-consensus.md |
97
|
|
|
|
|
|
|
my $want_xs; |
98
|
|
|
|
|
|
|
sub want_xs { |
99
|
0
|
|
|
0
|
1
|
|
my($self, $default) = @_; |
100
|
0
|
0
|
|
|
|
|
return $want_xs if defined $want_xs; |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# you're using this module, you must want XS by default |
103
|
|
|
|
|
|
|
# unless PERL_ONLY is true. |
104
|
0
|
0
|
|
|
|
|
$default = !$ENV{PERL_ONLY} if not defined $default; |
105
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
foreach my $arg(@ARGV){ |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
|
my ($k, $v) = split '=', $arg; # MM-style named args |
109
|
0
|
0
|
0
|
|
|
|
if ($k eq 'PUREPERL_ONLY' && defined $v) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
110
|
0
|
|
|
|
|
|
return $want_xs = !$v; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
elsif($arg eq '--pp'){ # old-style |
113
|
0
|
|
|
|
|
|
return $want_xs = 0; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
elsif($arg eq '--xs'){ |
116
|
0
|
|
|
|
|
|
return $want_xs = 1; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
0
|
0
|
|
|
|
|
if ($ENV{PERL_MM_OPT}) { |
121
|
0
|
|
|
|
|
|
my($v) = $ENV{PERL_MM_OPT} =~ /\b PUREPERL_ONLY = (\S+) /xms; |
122
|
0
|
0
|
|
|
|
|
if (defined $v) { |
123
|
0
|
|
|
|
|
|
return $want_xs = !$v; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
return $want_xs = $default; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub use_ppport{ |
132
|
0
|
|
|
0
|
1
|
|
my($self, $dppp_version) = @_; |
133
|
0
|
0
|
|
|
|
|
return if $self->{_ppport_ok}++; |
134
|
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
136
|
|
|
|
|
|
|
|
137
|
0
|
|
|
|
|
|
my $filename = 'ppport.h'; |
138
|
|
|
|
|
|
|
|
139
|
0
|
|
0
|
|
|
|
$dppp_version ||= 3.19; # the more, the better |
140
|
0
|
|
|
|
|
|
$self->configure_requires('Devel::PPPort' => $dppp_version); |
141
|
0
|
|
|
|
|
|
$self->build_requires('Devel::PPPort' => $dppp_version); |
142
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
print "Writing $filename\n"; |
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
my $e = do{ |
146
|
0
|
|
|
|
|
|
local $@; |
147
|
0
|
|
|
|
|
|
eval qq{ |
148
|
|
|
|
|
|
|
use Devel::PPPort; |
149
|
|
|
|
|
|
|
Devel::PPPort::WriteFile(q{$filename}); |
150
|
|
|
|
|
|
|
}; |
151
|
0
|
|
|
|
|
|
$@; |
152
|
|
|
|
|
|
|
}; |
153
|
0
|
0
|
|
|
|
|
if($e){ |
154
|
0
|
|
|
|
|
|
print "Cannot create $filename because: $@\n"; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
0
|
0
|
|
|
|
|
if(-e $filename){ |
158
|
0
|
|
|
|
|
|
$self->clean_files($filename); |
159
|
0
|
|
|
|
|
|
$self->cc_define('-DUSE_PPPORT'); |
160
|
0
|
|
|
|
|
|
$self->cc_append_to_inc('.'); |
161
|
|
|
|
|
|
|
} |
162
|
0
|
|
|
|
|
|
return; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub use_xshelper { |
166
|
0
|
|
|
0
|
1
|
|
my($self, $opt) = @_; |
167
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
168
|
0
|
|
|
|
|
|
$self->use_ppport(); |
169
|
|
|
|
|
|
|
|
170
|
0
|
|
|
|
|
|
my $file = 'xshelper.h'; |
171
|
0
|
0
|
|
|
|
|
open my $fh, '>', $file or die "Cannot open $file for writing: $!"; |
172
|
0
|
|
|
|
|
|
print $fh $self->_xshelper_h(); |
173
|
0
|
0
|
|
|
|
|
close $fh or die "Cannot close $file: $!"; |
174
|
0
|
0
|
|
|
|
|
if(defined $opt) { |
175
|
0
|
0
|
|
|
|
|
if($opt eq '-clean') { |
176
|
0
|
|
|
|
|
|
$self->clean_files($file); |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
else { |
179
|
0
|
|
|
|
|
|
$self->realclean_files($file); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
} |
182
|
0
|
|
|
|
|
|
return; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub _gccversion { |
186
|
0
|
|
|
0
|
|
|
my $res = `$Config{cc} --version`; |
187
|
0
|
|
|
|
|
|
my ($version) = $res =~ /\(GCC\) ([0-9.]+)/; |
188
|
1
|
|
|
1
|
|
8
|
no warnings 'numeric', 'uninitialized'; |
|
1
|
|
|
|
|
13
|
|
|
1
|
|
|
|
|
4536
|
|
189
|
0
|
|
|
|
|
|
return sprintf '%g', $version; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub cc_warnings{ |
193
|
0
|
|
|
0
|
1
|
|
my($self) = @_; |
194
|
|
|
|
|
|
|
|
195
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
196
|
|
|
|
|
|
|
|
197
|
0
|
0
|
|
|
|
|
if(_is_gcc()){ |
|
|
0
|
|
|
|
|
|
198
|
0
|
|
|
|
|
|
$self->cc_append_to_ccflags(qw(-Wall)); |
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
|
my $gccversion = _gccversion(); |
201
|
0
|
0
|
|
|
|
|
if($gccversion >= 4.0){ |
202
|
0
|
|
|
|
|
|
$self->cc_append_to_ccflags(qw(-Wextra)); |
203
|
0
|
0
|
0
|
|
|
|
if(!($UseC99 or $UseCplusplus)) { |
204
|
|
|
|
|
|
|
# Note: MSVC++ doesn't support C99, |
205
|
|
|
|
|
|
|
# so -Wdeclaration-after-statement helps |
206
|
|
|
|
|
|
|
# ensure C89 specs. |
207
|
0
|
|
|
|
|
|
$self->cc_append_to_ccflags(qw(-Wdeclaration-after-statement)); |
208
|
|
|
|
|
|
|
} |
209
|
0
|
0
|
0
|
|
|
|
if($gccversion >= 4.1 && !$UseCplusplus) { |
210
|
0
|
|
|
|
|
|
$self->cc_append_to_ccflags(qw(-Wc++-compat)); |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
else{ |
214
|
0
|
|
|
|
|
|
$self->cc_append_to_ccflags(qw(-W -Wno-comment)); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
elsif(_is_msvc()){ |
218
|
0
|
|
|
|
|
|
$self->cc_append_to_ccflags(qw(-W3)); |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
else{ |
221
|
|
|
|
|
|
|
# TODO: support other compilers |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
0
|
|
|
|
|
|
return; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub c99_available { |
228
|
0
|
|
|
0
|
1
|
|
my($self) = @_; |
229
|
|
|
|
|
|
|
|
230
|
0
|
0
|
|
|
|
|
return 0 if not $self->cc_available(); |
231
|
|
|
|
|
|
|
|
232
|
0
|
|
|
|
|
|
require File::Temp; |
233
|
0
|
|
|
|
|
|
require File::Basename; |
234
|
|
|
|
|
|
|
|
235
|
0
|
|
|
|
|
|
my $tmpfile = File::Temp->new(SUFFIX => '.c'); |
236
|
|
|
|
|
|
|
|
237
|
0
|
|
|
|
|
|
$tmpfile->print(<<'C99'); |
238
|
|
|
|
|
|
|
// include a C99 header |
239
|
|
|
|
|
|
|
#include |
240
|
|
|
|
|
|
|
inline // a C99 keyword with C99 style comments |
241
|
|
|
|
|
|
|
int test_c99() { |
242
|
|
|
|
|
|
|
int i = 0; |
243
|
|
|
|
|
|
|
i++; |
244
|
|
|
|
|
|
|
int j = i - 1; // another C99 feature: declaration after statement |
245
|
|
|
|
|
|
|
return j; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
C99 |
248
|
|
|
|
|
|
|
|
249
|
0
|
|
|
|
|
|
$tmpfile->close(); |
250
|
|
|
|
|
|
|
|
251
|
0
|
|
|
|
|
|
system "$Config{cc} -c " . $tmpfile->filename; |
252
|
|
|
|
|
|
|
|
253
|
0
|
|
|
|
|
|
(my $objname = File::Basename::basename($tmpfile->filename)) =~ s/\Q.c\E$/$Config{_o}/; |
254
|
0
|
0
|
|
|
|
|
unlink $objname or warn "Cannot unlink $objname (ignored): $!"; |
255
|
|
|
|
|
|
|
|
256
|
0
|
|
|
|
|
|
return $? == 0; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub requires_c99 { |
260
|
0
|
|
|
0
|
1
|
|
my($self) = @_; |
261
|
0
|
0
|
|
|
|
|
if(!$self->c99_available) { |
262
|
0
|
|
|
|
|
|
warn "This distribution requires a C99 compiler, but $Config{cc} seems not to support C99, stopped.\n"; |
263
|
0
|
|
|
|
|
|
exit; |
264
|
|
|
|
|
|
|
} |
265
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
266
|
0
|
|
|
|
|
|
$UseC99 = 1; |
267
|
0
|
|
|
|
|
|
return; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
sub requires_cplusplus { |
271
|
0
|
|
|
0
|
1
|
|
my($self) = @_; |
272
|
0
|
0
|
|
|
|
|
if(!$self->cc_available) { |
273
|
0
|
|
|
|
|
|
warn "This distribution requires a C++ compiler, but $Config{cc} seems not to support C++, stopped.\n"; |
274
|
0
|
|
|
|
|
|
exit; |
275
|
|
|
|
|
|
|
} |
276
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
277
|
0
|
|
|
|
|
|
$UseCplusplus = 1; |
278
|
0
|
|
|
|
|
|
return; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
sub cc_append_to_inc{ |
282
|
0
|
|
|
0
|
1
|
|
my($self, @dirs) = @_; |
283
|
|
|
|
|
|
|
|
284
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
285
|
|
|
|
|
|
|
|
286
|
0
|
|
|
|
|
|
for my $dir(@dirs){ |
287
|
0
|
0
|
|
|
|
|
unless(-d $dir){ |
288
|
0
|
|
|
|
|
|
warn("'$dir' not found: $!\n"); |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
|
_verbose "inc: -I$dir" if _VERBOSE; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
295
|
0
|
|
|
|
|
|
my $paths = join q{ }, map{ s{\\}{\\\\}g; qq{"-I$_"} } @dirs; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
0
|
0
|
|
|
|
|
if($mm->{INC}){ |
298
|
0
|
|
|
|
|
|
$mm->{INC} .= q{ } . $paths; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
else{ |
301
|
0
|
|
|
|
|
|
$mm->{INC} = $paths; |
302
|
|
|
|
|
|
|
} |
303
|
0
|
|
|
|
|
|
return; |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
sub cc_libs { |
307
|
0
|
|
|
0
|
1
|
|
my ($self, @libs) = @_; |
308
|
|
|
|
|
|
|
|
309
|
0
|
|
|
|
|
|
@libs = map{ |
310
|
0
|
0
|
|
|
|
|
my($name, $dir) = ref($_) eq 'ARRAY' ? @{$_} : ($_, undef); |
|
0
|
|
|
|
|
|
|
311
|
0
|
|
|
|
|
|
my $lib; |
312
|
0
|
0
|
|
|
|
|
if(defined $dir) { |
313
|
0
|
0
|
|
|
|
|
$lib = ($dir =~ /^-/ ? qq{$dir } : qq{-L$dir }); |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
else { |
316
|
0
|
|
|
|
|
|
$lib = ''; |
317
|
|
|
|
|
|
|
} |
318
|
0
|
0
|
|
|
|
|
$lib .= ($name =~ /^-/ ? qq{$name} : qq{-l$name}); |
319
|
0
|
|
|
|
|
|
_verbose "libs: $lib" if _VERBOSE; |
320
|
0
|
|
|
|
|
|
$lib; |
321
|
|
|
|
|
|
|
} @libs; |
322
|
|
|
|
|
|
|
|
323
|
0
|
|
|
|
|
|
$self->cc_append_to_libs( @libs ); |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub cc_append_to_libs{ |
327
|
0
|
|
|
0
|
1
|
|
my($self, @libs) = @_; |
328
|
|
|
|
|
|
|
|
329
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
330
|
|
|
|
|
|
|
|
331
|
0
|
0
|
|
|
|
|
return unless @libs; |
332
|
|
|
|
|
|
|
|
333
|
0
|
|
|
|
|
|
my $libs = join q{ }, @libs; |
334
|
|
|
|
|
|
|
|
335
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
336
|
|
|
|
|
|
|
|
337
|
0
|
0
|
|
|
|
|
if ($mm->{LIBS}){ |
338
|
0
|
|
|
|
|
|
$mm->{LIBS} .= q{ } . $libs; |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
else{ |
341
|
0
|
|
|
|
|
|
$mm->{LIBS} = $libs; |
342
|
|
|
|
|
|
|
} |
343
|
0
|
|
|
|
|
|
return $libs; |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
sub cc_assert_lib { |
347
|
0
|
|
|
0
|
1
|
|
my ($self, @dcl_args) = @_; |
348
|
|
|
|
|
|
|
|
349
|
0
|
0
|
|
|
|
|
if ( ! $self->{xsu_loaded_checklib} ) { |
350
|
0
|
|
|
|
|
|
my $loaded_lib = 0; |
351
|
0
|
|
|
|
|
|
foreach my $checklib (qw(inc::Devel::CheckLib Devel::CheckLib)) { |
352
|
0
|
|
|
|
|
|
eval "use $checklib 0.4"; |
353
|
0
|
0
|
|
|
|
|
if (!$@) { |
354
|
0
|
|
|
|
|
|
$loaded_lib = 1; |
355
|
0
|
|
|
|
|
|
last; |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
0
|
0
|
|
|
|
|
if (! $loaded_lib) { |
360
|
0
|
|
|
|
|
|
warn "Devel::CheckLib not found in inc/ nor \@INC"; |
361
|
0
|
|
|
|
|
|
exit 0; |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
0
|
|
|
|
|
|
$self->{xsu_loaded_checklib}++; |
365
|
0
|
|
|
|
|
|
$self->configure_requires( "Devel::CheckLib" => "0.4" ); |
366
|
0
|
|
|
|
|
|
$self->build_requires( "Devel::CheckLib" => "0.4" ); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
0
|
|
|
|
|
|
Devel::CheckLib::check_lib_or_exit(@dcl_args); |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub cc_append_to_ccflags{ |
373
|
0
|
|
|
0
|
1
|
|
my($self, @ccflags) = @_; |
374
|
|
|
|
|
|
|
|
375
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
376
|
|
|
|
|
|
|
|
377
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
378
|
|
|
|
|
|
|
|
379
|
0
|
|
0
|
|
|
|
$mm->{CCFLAGS} ||= $Config{ccflags}; |
380
|
0
|
|
|
|
|
|
$mm->{CCFLAGS} .= q{ } . join q{ }, @ccflags; |
381
|
0
|
|
|
|
|
|
return; |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
sub cc_define{ |
385
|
0
|
|
|
0
|
1
|
|
my($self, @defines) = @_; |
386
|
|
|
|
|
|
|
|
387
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
388
|
|
|
|
|
|
|
|
389
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
390
|
0
|
0
|
|
|
|
|
if(exists $mm->{DEFINE}){ |
391
|
0
|
|
|
|
|
|
$mm->{DEFINE} .= q{ } . join q{ }, @defines; |
392
|
|
|
|
|
|
|
} |
393
|
|
|
|
|
|
|
else{ |
394
|
0
|
|
|
|
|
|
$mm->{DEFINE} = join q{ }, @defines; |
395
|
|
|
|
|
|
|
} |
396
|
0
|
|
|
|
|
|
return; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub requires_xs_module { |
400
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
401
|
|
|
|
|
|
|
|
402
|
0
|
0
|
|
|
|
|
return $self->requires() unless @_; |
403
|
|
|
|
|
|
|
|
404
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
405
|
|
|
|
|
|
|
|
406
|
0
|
|
|
|
|
|
my %added = $self->requires(@_); |
407
|
0
|
|
|
|
|
|
my(@inc, @libs); |
408
|
|
|
|
|
|
|
|
409
|
0
|
|
|
|
|
|
my $rx_lib = qr{ \. (?: lib | a) \z}xmsi; |
410
|
0
|
|
|
|
|
|
my $rx_dll = qr{ \. dll \z}xmsi; # for Cygwin |
411
|
|
|
|
|
|
|
|
412
|
0
|
|
|
|
|
|
while(my $module = each %added){ |
413
|
0
|
|
|
|
|
|
my $mod_basedir = File::Spec->join(split /::/, $module); |
414
|
0
|
|
|
|
|
|
my $rx_header = qr{\A ( .+ \Q$mod_basedir\E ) .+ \. h(?:pp)? \z}xmsi; |
415
|
|
|
|
|
|
|
|
416
|
0
|
|
|
|
|
|
SCAN_INC: foreach my $inc_dir(@INC){ |
417
|
0
|
|
|
|
|
|
my @dirs = grep{ -e } File::Spec->join($inc_dir, 'auto', $mod_basedir), File::Spec->join($inc_dir, $mod_basedir); |
|
0
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
|
419
|
0
|
0
|
|
|
|
|
next SCAN_INC unless @dirs; |
420
|
|
|
|
|
|
|
|
421
|
0
|
|
|
|
|
|
my $n_inc = scalar @inc; |
422
|
|
|
|
|
|
|
find(sub{ |
423
|
0
|
0
|
|
0
|
|
|
if(my($incdir) = $File::Find::name =~ $rx_header){ |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
424
|
0
|
|
|
|
|
|
push @inc, $incdir; |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
elsif($File::Find::name =~ $rx_lib){ |
427
|
0
|
|
|
|
|
|
my($libname) = $_ =~ /\A (?:lib)? (\w+) /xmsi; |
428
|
0
|
|
|
|
|
|
push @libs, [$libname, $File::Find::dir]; |
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
elsif($File::Find::name =~ $rx_dll){ |
431
|
|
|
|
|
|
|
# XXX: hack for Cygwin |
432
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
433
|
0
|
|
0
|
|
|
|
$mm->{macro}->{PERL_ARCHIVE_AFTER} ||= ''; |
434
|
0
|
|
|
|
|
|
$mm->{macro}->{PERL_ARCHIVE_AFTER} .= ' ' . $File::Find::name; |
435
|
|
|
|
|
|
|
} |
436
|
0
|
|
|
|
|
|
}, @dirs); |
437
|
|
|
|
|
|
|
|
438
|
0
|
0
|
|
|
|
|
if($n_inc != scalar @inc){ |
439
|
0
|
|
|
|
|
|
last SCAN_INC; |
440
|
|
|
|
|
|
|
} |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
} |
443
|
|
|
|
|
|
|
|
444
|
0
|
|
|
|
|
|
my %uniq = (); |
445
|
0
|
|
|
|
|
|
$self->cc_append_to_inc (grep{ !$uniq{ $_ }++ } @inc); |
|
0
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
|
447
|
0
|
|
|
|
|
|
%uniq = (); |
448
|
0
|
|
|
|
|
|
$self->cc_libs(grep{ !$uniq{ $_->[0] }++ } @libs); |
|
0
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
|
450
|
0
|
|
|
|
|
|
return %added; |
451
|
|
|
|
|
|
|
} |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
sub cc_src_paths{ |
454
|
0
|
|
|
0
|
1
|
|
my($self, @dirs) = @_; |
455
|
|
|
|
|
|
|
|
456
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
457
|
|
|
|
|
|
|
|
458
|
0
|
0
|
|
|
|
|
return unless @dirs; |
459
|
|
|
|
|
|
|
|
460
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
461
|
|
|
|
|
|
|
|
462
|
0
|
|
0
|
|
|
|
my $XS_ref = $mm->{XS} ||= {}; |
463
|
0
|
|
0
|
|
|
|
my $C_ref = $mm->{C} ||= []; |
464
|
|
|
|
|
|
|
|
465
|
0
|
|
|
|
|
|
my $_obj = $Config{_o}; |
466
|
|
|
|
|
|
|
|
467
|
0
|
|
|
|
|
|
my @src_files; |
468
|
|
|
|
|
|
|
find(sub{ |
469
|
0
|
0
|
|
0
|
|
|
if(/ \. (?: xs | c (?: c | pp | xx )? ) \z/xmsi){ # *.{xs, c, cc, cpp, cxx} |
470
|
0
|
|
|
|
|
|
push @src_files, $File::Find::name; |
471
|
|
|
|
|
|
|
} |
472
|
0
|
|
|
|
|
|
}, @dirs); |
473
|
|
|
|
|
|
|
|
474
|
0
|
0
|
|
|
|
|
my $xs_to = $UseCplusplus ? '.cpp' : '.c'; |
475
|
0
|
|
|
|
|
|
foreach my $src_file(@src_files){ |
476
|
0
|
|
|
|
|
|
my $c = $src_file; |
477
|
0
|
0
|
|
|
|
|
if($c =~ s/ \.xs \z/$xs_to/xms){ |
478
|
0
|
|
|
|
|
|
$XS_ref->{$src_file} = $c; |
479
|
|
|
|
|
|
|
|
480
|
0
|
|
|
|
|
|
_verbose "xs: $src_file" if _VERBOSE; |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
else{ |
483
|
0
|
|
|
|
|
|
_verbose "c: $c" if _VERBOSE; |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
|
486
|
0
|
0
|
|
|
|
|
push @{$C_ref}, $c unless grep{ $_ eq $c } @{$C_ref}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
} |
488
|
|
|
|
|
|
|
|
489
|
0
|
|
|
|
|
|
$self->clean_files(map{ |
490
|
0
|
|
|
|
|
|
File::Spec->catfile($_, '*.gcov'), |
491
|
|
|
|
|
|
|
File::Spec->catfile($_, '*.gcda'), |
492
|
|
|
|
|
|
|
File::Spec->catfile($_, '*.gcno'), |
493
|
|
|
|
|
|
|
} @dirs); |
494
|
0
|
|
|
|
|
|
$self->cc_append_to_inc('.'); |
495
|
|
|
|
|
|
|
|
496
|
0
|
|
|
|
|
|
return; |
497
|
|
|
|
|
|
|
} |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub cc_include_paths{ |
500
|
0
|
|
|
0
|
1
|
|
my($self, @dirs) = @_; |
501
|
|
|
|
|
|
|
|
502
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
503
|
|
|
|
|
|
|
|
504
|
0
|
|
0
|
|
|
|
push @{ $self->{xsu_include_paths} ||= []}, @dirs; |
|
0
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
|
506
|
0
|
|
0
|
|
|
|
my $h_map = $self->{xsu_header_map} ||= {}; |
507
|
|
|
|
|
|
|
|
508
|
0
|
|
|
|
|
|
foreach my $dir(@dirs){ |
509
|
0
|
|
|
|
|
|
my $prefix = quotemeta( File::Spec->catfile($dir, '') ); |
510
|
|
|
|
|
|
|
find(sub{ |
511
|
0
|
0
|
|
0
|
|
|
return unless / \.h(?:pp)? \z/xms; |
512
|
|
|
|
|
|
|
|
513
|
0
|
|
|
|
|
|
(my $h_file = $File::Find::name) =~ s/ \A $prefix //xms; |
514
|
0
|
|
|
|
|
|
$h_map->{$h_file} = $File::Find::name; |
515
|
0
|
|
|
|
|
|
}, $dir); |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
0
|
|
|
|
|
|
$self->cc_append_to_inc(@dirs); |
519
|
|
|
|
|
|
|
|
520
|
0
|
|
|
|
|
|
return; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub install_headers{ |
524
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
525
|
0
|
|
|
|
|
|
my $h_files; |
526
|
0
|
0
|
0
|
|
|
|
if(@_ == 0){ |
|
|
0
|
|
|
|
|
|
527
|
0
|
0
|
|
|
|
|
$h_files = $self->{xsu_header_map} or die "install_headers: cc_include_paths not specified.\n"; |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
elsif(@_ == 1 && ref($_[0]) eq 'HASH'){ |
530
|
0
|
|
|
|
|
|
$h_files = $_[0]; |
531
|
|
|
|
|
|
|
} |
532
|
|
|
|
|
|
|
else{ |
533
|
0
|
|
|
|
|
|
$h_files = +{ map{ $_ => undef } @_ }; |
|
0
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
|
536
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
537
|
|
|
|
|
|
|
|
538
|
0
|
|
|
|
|
|
my @not_found; |
539
|
0
|
|
0
|
|
|
|
my $h_map = $self->{xsu_header_map} || {}; |
540
|
|
|
|
|
|
|
|
541
|
0
|
|
|
|
|
|
while(my($ident, $path) = each %{$h_files}){ |
|
0
|
|
|
|
|
|
|
542
|
0
|
|
0
|
|
|
|
$path ||= $h_map->{$ident} || File::Spec->join('.', $ident); |
|
|
|
0
|
|
|
|
|
543
|
0
|
|
|
|
|
|
$path = File::Spec->canonpath($path); |
544
|
|
|
|
|
|
|
|
545
|
0
|
0
|
0
|
|
|
|
unless($path && -e $path){ |
546
|
0
|
|
|
|
|
|
push @not_found, $ident; |
547
|
0
|
|
|
|
|
|
next; |
548
|
|
|
|
|
|
|
} |
549
|
|
|
|
|
|
|
|
550
|
0
|
|
|
|
|
|
$ToInstall{$path} = File::Spec->join('$(INST_ARCHAUTODIR)', $ident); |
551
|
|
|
|
|
|
|
|
552
|
0
|
|
|
|
|
|
_verbose "install: $path as $ident" if _VERBOSE; |
553
|
0
|
|
|
|
|
|
my @funcs = $self->_extract_functions_from_header_file($path); |
554
|
0
|
0
|
|
|
|
|
if(@funcs){ |
555
|
0
|
|
|
|
|
|
$self->cc_append_to_funclist(@funcs); |
556
|
|
|
|
|
|
|
} |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
0
|
0
|
|
|
|
|
if(@not_found){ |
560
|
0
|
|
|
|
|
|
die "Header file(s) not found: @not_found\n"; |
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
|
563
|
0
|
|
|
|
|
|
return; |
564
|
|
|
|
|
|
|
} |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
my $home_directory; |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
sub _extract_functions_from_header_file{ |
569
|
0
|
|
|
0
|
|
|
my($self, $h_file) = @_; |
570
|
|
|
|
|
|
|
|
571
|
0
|
|
|
|
|
|
my @functions; |
572
|
|
|
|
|
|
|
|
573
|
0
|
0
|
|
|
|
|
($home_directory) = <~> unless defined $home_directory; |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
# get header file contents through cpp(1) |
576
|
0
|
|
|
|
|
|
my $contents = do { |
577
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
578
|
|
|
|
|
|
|
|
579
|
0
|
|
|
|
|
|
my $cppflags = q{"-I}. File::Spec->join($Config{archlib}, 'CORE') . q{"}; |
580
|
0
|
|
|
|
|
|
$cppflags =~ s/~/$home_directory/g; |
581
|
|
|
|
|
|
|
|
582
|
0
|
0
|
|
|
|
|
$cppflags .= ' ' . $mm->{INC} if $mm->{INC}; |
583
|
|
|
|
|
|
|
|
584
|
0
|
|
0
|
|
|
|
$cppflags .= ' ' . ($mm->{CCFLAGS} || $Config{ccflags}); |
585
|
0
|
0
|
|
|
|
|
$cppflags .= ' ' . $mm->{DEFINE} if $mm->{DEFINE}; |
586
|
|
|
|
|
|
|
|
587
|
0
|
0
|
|
|
|
|
my $add_include = _is_msvc() ? '-FI' : '-include'; |
588
|
0
|
|
|
|
|
|
$cppflags .= ' ' . join ' ', |
589
|
0
|
|
|
|
|
|
map{ qq{$add_include "$_"} } qw(EXTERN.h perl.h XSUB.h); |
590
|
|
|
|
|
|
|
|
591
|
0
|
|
|
|
|
|
my $cppcmd = qq{$Config{cpprun} $cppflags $h_file}; |
592
|
|
|
|
|
|
|
# remove all the -arch options to workaround gcc errors: |
593
|
|
|
|
|
|
|
# "-E, -S, -save-temps and -M options are not allowed |
594
|
|
|
|
|
|
|
# with multiple -arch flags" |
595
|
0
|
|
|
|
|
|
$cppcmd =~ s/ -arch \s* \S+ //xmsg; |
596
|
0
|
|
|
|
|
|
_verbose("extract functions from: $cppcmd") if _VERBOSE; |
597
|
0
|
|
|
|
|
|
`$cppcmd`; |
598
|
|
|
|
|
|
|
}; |
599
|
|
|
|
|
|
|
|
600
|
0
|
0
|
|
|
|
|
unless(defined $contents){ |
601
|
0
|
|
|
|
|
|
die "Cannot call C pre-processor ($Config{cpprun}): $! ($?)"; |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
# remove other include file contents |
605
|
0
|
|
|
|
|
|
my $chfile = q/\# (?:line)? \s+ \d+ /; |
606
|
0
|
|
|
|
|
|
$contents =~ s{ |
607
|
|
|
|
|
|
|
^$chfile \s+ (?!"\Q$h_file\E") |
608
|
|
|
|
|
|
|
.*? |
609
|
|
|
|
|
|
|
^(?= $chfile) |
610
|
|
|
|
|
|
|
}{}xmsig; |
611
|
|
|
|
|
|
|
|
612
|
0
|
|
|
|
|
|
if(_VERBOSE){ |
613
|
|
|
|
|
|
|
local *H; |
614
|
|
|
|
|
|
|
open H, "> $h_file.out" |
615
|
|
|
|
|
|
|
and print H $contents |
616
|
|
|
|
|
|
|
and close H; |
617
|
|
|
|
|
|
|
} |
618
|
|
|
|
|
|
|
|
619
|
0
|
|
|
|
|
|
while($contents =~ m{ |
620
|
|
|
|
|
|
|
([^\\;\s]+ # type |
621
|
|
|
|
|
|
|
\s+ |
622
|
|
|
|
|
|
|
([a-zA-Z_][a-zA-Z0-9_]*) # function name |
623
|
|
|
|
|
|
|
\s* |
624
|
|
|
|
|
|
|
\( [^;#]* \) # argument list |
625
|
|
|
|
|
|
|
[\w\s\(\)]* # attributes or something |
626
|
|
|
|
|
|
|
;) # end of declaration |
627
|
|
|
|
|
|
|
}xmsg){ |
628
|
0
|
|
|
|
|
|
my $decl = $1; |
629
|
0
|
|
|
|
|
|
my $name = $2; |
630
|
|
|
|
|
|
|
|
631
|
0
|
0
|
|
|
|
|
next if $decl =~ /\b typedef \b/xms; |
632
|
0
|
0
|
|
|
|
|
next if $name =~ /^_/xms; # skip something private |
633
|
|
|
|
|
|
|
|
634
|
0
|
|
|
|
|
|
push @functions, $name; |
635
|
|
|
|
|
|
|
|
636
|
0
|
|
|
|
|
|
if(_VERBOSE){ |
637
|
|
|
|
|
|
|
$decl =~ tr/\n\r\t / /s; |
638
|
|
|
|
|
|
|
$decl =~ s/ (\Q$name\E) /<$name>/xms; |
639
|
|
|
|
|
|
|
_verbose("decl: $decl"); |
640
|
|
|
|
|
|
|
} |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
0
|
|
|
|
|
|
return @functions; |
644
|
|
|
|
|
|
|
} |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
sub cc_append_to_funclist{ |
648
|
0
|
|
|
0
|
1
|
|
my($self, @functions) = @_; |
649
|
|
|
|
|
|
|
|
650
|
0
|
|
|
|
|
|
$self->_xs_initialize(); |
651
|
|
|
|
|
|
|
|
652
|
0
|
|
|
|
|
|
my $mm = $self->makemaker_args; |
653
|
|
|
|
|
|
|
|
654
|
0
|
|
0
|
|
|
|
push @{$mm->{FUNCLIST} ||= []}, @functions; |
|
0
|
|
|
|
|
|
|
655
|
0
|
|
0
|
|
|
|
$mm->{DL_FUNCS} ||= { '$(NAME)' => [] }; |
656
|
|
|
|
|
|
|
|
657
|
0
|
|
|
|
|
|
return; |
658
|
|
|
|
|
|
|
} |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
sub _xshelper_h { |
661
|
0
|
|
|
0
|
|
|
my $h = <<'XSHELPER_H'; |
662
|
|
|
|
|
|
|
:/* THIS FILE IS AUTOMATICALLY GENERATED BY Module::Install::XSUtil $VERSION. */ |
663
|
|
|
|
|
|
|
:/* |
664
|
|
|
|
|
|
|
:=head1 NAME |
665
|
|
|
|
|
|
|
: |
666
|
|
|
|
|
|
|
:xshelper.h - Helper C header file for XS modules |
667
|
|
|
|
|
|
|
: |
668
|
|
|
|
|
|
|
:=head1 DESCRIPTION |
669
|
|
|
|
|
|
|
: |
670
|
|
|
|
|
|
|
: // This includes all the perl header files and ppport.h |
671
|
|
|
|
|
|
|
: #include "xshelper.h" |
672
|
|
|
|
|
|
|
: |
673
|
|
|
|
|
|
|
:=head1 SEE ALSO |
674
|
|
|
|
|
|
|
: |
675
|
|
|
|
|
|
|
:L, where this file is distributed as a part of |
676
|
|
|
|
|
|
|
: |
677
|
|
|
|
|
|
|
:=head1 AUTHOR |
678
|
|
|
|
|
|
|
: |
679
|
|
|
|
|
|
|
:Fuji, Goro (gfx) Egfuji at cpan.orgE |
680
|
|
|
|
|
|
|
: |
681
|
|
|
|
|
|
|
:=head1 LISENCE |
682
|
|
|
|
|
|
|
: |
683
|
|
|
|
|
|
|
:Copyright (c) 2010, Fuji, Goro (gfx). All rights reserved. |
684
|
|
|
|
|
|
|
: |
685
|
|
|
|
|
|
|
:This library is free software; you can redistribute it and/or modify |
686
|
|
|
|
|
|
|
:it under the same terms as Perl itself. |
687
|
|
|
|
|
|
|
: |
688
|
|
|
|
|
|
|
:=cut |
689
|
|
|
|
|
|
|
:*/ |
690
|
|
|
|
|
|
|
: |
691
|
|
|
|
|
|
|
:#ifdef __cplusplus |
692
|
|
|
|
|
|
|
:extern "C" { |
693
|
|
|
|
|
|
|
:#endif |
694
|
|
|
|
|
|
|
: |
695
|
|
|
|
|
|
|
:#define PERL_NO_GET_CONTEXT /* we want efficiency */ |
696
|
|
|
|
|
|
|
:#include |
697
|
|
|
|
|
|
|
:#include |
698
|
|
|
|
|
|
|
:#define NO_XSLOCKS /* for exceptions */ |
699
|
|
|
|
|
|
|
:#include |
700
|
|
|
|
|
|
|
: |
701
|
|
|
|
|
|
|
:#ifdef __cplusplus |
702
|
|
|
|
|
|
|
:} /* extern "C" */ |
703
|
|
|
|
|
|
|
:#endif |
704
|
|
|
|
|
|
|
: |
705
|
|
|
|
|
|
|
:#include "ppport.h" |
706
|
|
|
|
|
|
|
: |
707
|
|
|
|
|
|
|
:/* portability stuff not supported by ppport.h yet */ |
708
|
|
|
|
|
|
|
: |
709
|
|
|
|
|
|
|
:#ifndef STATIC_INLINE /* from 5.13.4 */ |
710
|
|
|
|
|
|
|
:# if defined(__GNUC__) || defined(__cplusplus) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) |
711
|
|
|
|
|
|
|
:# define STATIC_INLINE static inline |
712
|
|
|
|
|
|
|
:# else |
713
|
|
|
|
|
|
|
:# define STATIC_INLINE static |
714
|
|
|
|
|
|
|
:# endif |
715
|
|
|
|
|
|
|
:#endif /* STATIC_INLINE */ |
716
|
|
|
|
|
|
|
: |
717
|
|
|
|
|
|
|
:#ifndef __attribute__format__ |
718
|
|
|
|
|
|
|
:#define __attribute__format__(a,b,c) /* nothing */ |
719
|
|
|
|
|
|
|
:#endif |
720
|
|
|
|
|
|
|
: |
721
|
|
|
|
|
|
|
:#ifndef LIKELY /* they are just a compiler's hint */ |
722
|
|
|
|
|
|
|
:#define LIKELY(x) (!!(x)) |
723
|
|
|
|
|
|
|
:#define UNLIKELY(x) (!!(x)) |
724
|
|
|
|
|
|
|
:#endif |
725
|
|
|
|
|
|
|
: |
726
|
|
|
|
|
|
|
:#ifndef newSVpvs_share |
727
|
|
|
|
|
|
|
:#define newSVpvs_share(s) Perl_newSVpvn_share(aTHX_ STR_WITH_LEN(s), 0U) |
728
|
|
|
|
|
|
|
:#endif |
729
|
|
|
|
|
|
|
: |
730
|
|
|
|
|
|
|
:#ifndef get_cvs |
731
|
|
|
|
|
|
|
:#define get_cvs(name, flags) get_cv(name, flags) |
732
|
|
|
|
|
|
|
:#endif |
733
|
|
|
|
|
|
|
: |
734
|
|
|
|
|
|
|
:#ifndef GvNAME_get |
735
|
|
|
|
|
|
|
:#define GvNAME_get GvNAME |
736
|
|
|
|
|
|
|
:#endif |
737
|
|
|
|
|
|
|
:#ifndef GvNAMELEN_get |
738
|
|
|
|
|
|
|
:#define GvNAMELEN_get GvNAMELEN |
739
|
|
|
|
|
|
|
:#endif |
740
|
|
|
|
|
|
|
: |
741
|
|
|
|
|
|
|
:#ifndef CvGV_set |
742
|
|
|
|
|
|
|
:#define CvGV_set(cv, gv) (CvGV(cv) = (gv)) |
743
|
|
|
|
|
|
|
:#endif |
744
|
|
|
|
|
|
|
: |
745
|
|
|
|
|
|
|
:/* general utility */ |
746
|
|
|
|
|
|
|
: |
747
|
|
|
|
|
|
|
:#if PERL_BCDVERSION >= 0x5008005 |
748
|
|
|
|
|
|
|
:#define LooksLikeNumber(x) looks_like_number(x) |
749
|
|
|
|
|
|
|
:#else |
750
|
|
|
|
|
|
|
:#define LooksLikeNumber(x) (SvPOKp(x) ? looks_like_number(x) : (I32)SvNIOKp(x)) |
751
|
|
|
|
|
|
|
:#endif |
752
|
|
|
|
|
|
|
: |
753
|
|
|
|
|
|
|
:#define newAV_mortal() (AV*)sv_2mortal((SV*)newAV()) |
754
|
|
|
|
|
|
|
:#define newHV_mortal() (HV*)sv_2mortal((SV*)newHV()) |
755
|
|
|
|
|
|
|
:#define newRV_inc_mortal(sv) sv_2mortal(newRV_inc(sv)) |
756
|
|
|
|
|
|
|
:#define newRV_noinc_mortal(sv) sv_2mortal(newRV_noinc(sv)) |
757
|
|
|
|
|
|
|
: |
758
|
|
|
|
|
|
|
:#define DECL_BOOT(name) EXTERN_C XS(CAT2(boot_, name)) |
759
|
|
|
|
|
|
|
:#define CALL_BOOT(name) STMT_START { \ |
760
|
|
|
|
|
|
|
: PUSHMARK(SP); \ |
761
|
|
|
|
|
|
|
: CALL_FPTR(CAT2(boot_, name))(aTHX_ cv); \ |
762
|
|
|
|
|
|
|
: } STMT_END |
763
|
|
|
|
|
|
|
XSHELPER_H |
764
|
0
|
|
|
|
|
|
$h =~ s/^://xmsg; |
765
|
0
|
|
|
|
|
|
$h =~ s/\$VERSION\b/$Module::Install::XSUtil::VERSION/xms; |
766
|
0
|
|
|
|
|
|
return $h; |
767
|
|
|
|
|
|
|
} |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
package |
770
|
|
|
|
|
|
|
MY; |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
# XXX: We must append to PM inside ExtUtils::MakeMaker->new(). |
773
|
|
|
|
|
|
|
sub init_PM { |
774
|
0
|
|
|
0
|
|
|
my $self = shift; |
775
|
|
|
|
|
|
|
|
776
|
0
|
|
|
|
|
|
$self->SUPER::init_PM(@_); |
777
|
|
|
|
|
|
|
|
778
|
0
|
|
|
|
|
|
while(my($k, $v) = each %ToInstall){ |
779
|
0
|
|
|
|
|
|
$self->{PM}{$k} = $v; |
780
|
|
|
|
|
|
|
} |
781
|
0
|
|
|
|
|
|
return; |
782
|
|
|
|
|
|
|
} |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
# append object file names to CCCMD |
785
|
|
|
|
|
|
|
sub const_cccmd { |
786
|
0
|
|
|
0
|
|
|
my $self = shift; |
787
|
|
|
|
|
|
|
|
788
|
0
|
|
|
|
|
|
my $cccmd = $self->SUPER::const_cccmd(@_); |
789
|
0
|
0
|
|
|
|
|
return q{} unless $cccmd; |
790
|
|
|
|
|
|
|
|
791
|
0
|
0
|
|
|
|
|
if (Module::Install::XSUtil::_is_msvc()){ |
792
|
0
|
|
|
|
|
|
$cccmd .= ' -Fo$@'; |
793
|
|
|
|
|
|
|
} |
794
|
|
|
|
|
|
|
else { |
795
|
0
|
|
|
|
|
|
$cccmd .= ' -o $@'; |
796
|
|
|
|
|
|
|
} |
797
|
|
|
|
|
|
|
|
798
|
0
|
|
|
|
|
|
return $cccmd |
799
|
|
|
|
|
|
|
} |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
sub xs_c { |
802
|
0
|
|
|
0
|
|
|
my($self) = @_; |
803
|
0
|
|
|
|
|
|
my $mm = $self->SUPER::xs_c(); |
804
|
0
|
0
|
|
|
|
|
$mm =~ s/ \.c /.cpp/xmsg if $UseCplusplus; |
805
|
0
|
|
|
|
|
|
return $mm; |
806
|
|
|
|
|
|
|
} |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
sub xs_o { |
809
|
0
|
|
|
0
|
|
|
my($self) = @_; |
810
|
0
|
|
|
|
|
|
my $mm = $self->SUPER::xs_o(); |
811
|
0
|
0
|
|
|
|
|
$mm =~ s/ \.c /.cpp/xmsg if $UseCplusplus; |
812
|
0
|
|
|
|
|
|
return $mm; |
813
|
|
|
|
|
|
|
} |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
1; |
816
|
|
|
|
|
|
|
__END__ |