| 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__ |