line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package ExtUtils::CBuilder::Base; |
2
|
5
|
|
|
5
|
|
88193
|
use strict; |
|
5
|
|
|
|
|
18
|
|
|
5
|
|
|
|
|
136
|
|
3
|
5
|
|
|
5
|
|
25
|
use warnings; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
117
|
|
4
|
5
|
|
|
5
|
|
23
|
use File::Spec; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
95
|
|
5
|
5
|
|
|
5
|
|
22
|
use File::Basename; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
506
|
|
6
|
5
|
|
|
5
|
|
38
|
use Cwd (); |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
84
|
|
7
|
5
|
|
|
5
|
|
24
|
use Config; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
219
|
|
8
|
5
|
|
|
5
|
|
2287
|
use Text::ParseWords; |
|
5
|
|
|
|
|
6573
|
|
|
5
|
|
|
|
|
371
|
|
9
|
5
|
|
|
5
|
|
3669
|
use IPC::Cmd qw(can_run); |
|
5
|
|
|
|
|
282392
|
|
|
5
|
|
|
|
|
344
|
|
10
|
5
|
|
|
5
|
|
3030
|
use File::Temp qw(tempfile); |
|
5
|
|
|
|
|
49428
|
|
|
5
|
|
|
|
|
14358
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our $VERSION = '0.280234'; # VERSION |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# More details about C/C++ compilers: |
15
|
|
|
|
|
|
|
# http://developers.sun.com/sunstudio/documentation/product/compiler.jsp |
16
|
|
|
|
|
|
|
# http://gcc.gnu.org/ |
17
|
|
|
|
|
|
|
# http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp |
18
|
|
|
|
|
|
|
# http://msdn.microsoft.com/en-us/vstudio/default.aspx |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
my %cc2cxx = ( |
21
|
|
|
|
|
|
|
# first line order is important to support wrappers like in pkgsrc |
22
|
|
|
|
|
|
|
cc => [ 'c++', 'CC', 'aCC', 'cxx', ], # Sun Studio, HP ANSI C/C++ Compilers |
23
|
|
|
|
|
|
|
gcc => [ 'g++' ], # GNU Compiler Collection |
24
|
|
|
|
|
|
|
xlc => [ 'xlC' ], # IBM C/C++ Set, xlc without thread-safety |
25
|
|
|
|
|
|
|
xlc_r => [ 'xlC_r' ], # IBM C/C++ Set, xlc with thread-safety |
26
|
|
|
|
|
|
|
cl => [ 'cl' ], # Microsoft Visual Studio |
27
|
|
|
|
|
|
|
); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub new { |
30
|
20
|
|
|
20
|
0
|
19398
|
my $class = shift; |
31
|
20
|
|
|
|
|
105
|
my $self = bless {@_}, $class; |
32
|
|
|
|
|
|
|
|
33
|
20
|
50
|
|
|
|
135
|
$self->{properties}{perl} = $class->find_perl_interpreter |
34
|
|
|
|
|
|
|
or warn "Warning: Can't locate your perl binary"; |
35
|
|
|
|
|
|
|
|
36
|
20
|
|
|
|
|
865
|
while (my ($k,$v) = each %Config) { |
37
|
24520
|
100
|
|
|
|
378297
|
$self->{config}{$k} = $v unless exists $self->{config}{$k}; |
38
|
|
|
|
|
|
|
} |
39
|
20
|
100
|
|
|
|
97
|
$self->{config}{cc} = $ENV{CC} if defined $ENV{CC}; |
40
|
|
|
|
|
|
|
$self->{config}{ccflags} = join(" ", $self->{config}{ccflags}, $ENV{CFLAGS}) |
41
|
20
|
100
|
|
|
|
78
|
if defined $ENV{CFLAGS}; |
42
|
20
|
50
|
|
|
|
66
|
$self->{config}{cxx} = $ENV{CXX} if defined $ENV{CXX}; |
43
|
20
|
50
|
|
|
|
58
|
$self->{config}{cxxflags} = $ENV{CXXFLAGS} if defined $ENV{CXXFLAGS}; |
44
|
20
|
50
|
|
|
|
59
|
$self->{config}{ld} = $ENV{LD} if defined $ENV{LD}; |
45
|
|
|
|
|
|
|
$self->{config}{ldflags} = join(" ", $self->{config}{ldflags}, $ENV{LDFLAGS}) |
46
|
20
|
100
|
|
|
|
67
|
if defined $ENV{LDFLAGS}; |
47
|
|
|
|
|
|
|
|
48
|
20
|
50
|
|
|
|
66
|
unless ( exists $self->{config}{cxx} ) { |
49
|
|
|
|
|
|
|
|
50
|
20
|
|
|
|
|
1209
|
my ($ccbase, $ccpath, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
## If the path is just "cc", fileparse returns $ccpath as "./" |
53
|
20
|
100
|
|
|
|
373
|
$ccpath = "" if $self->{config}{cc} =~ /^\Q$ccbase$ccsfx\E$/; |
54
|
|
|
|
|
|
|
|
55
|
20
|
|
|
|
|
54
|
foreach my $cxx (@{$cc2cxx{$ccbase}}) { |
|
20
|
|
|
|
|
108
|
|
56
|
17
|
|
|
|
|
269
|
my $cxx1 = File::Spec->catfile( $ccpath, $cxx . $ccsfx); |
57
|
|
|
|
|
|
|
|
58
|
17
|
50
|
|
|
|
188
|
if( can_run( $cxx1 ) ) { |
59
|
0
|
|
|
|
|
0
|
$self->{config}{cxx} = $cxx1; |
60
|
0
|
|
|
|
|
0
|
last; |
61
|
|
|
|
|
|
|
} |
62
|
17
|
|
|
|
|
375729
|
my $cxx2 = $cxx . $ccsfx; |
63
|
|
|
|
|
|
|
|
64
|
17
|
50
|
|
|
|
64
|
if( can_run( $cxx2 ) ) { |
65
|
17
|
|
|
|
|
6251
|
$self->{config}{cxx} = $cxx2; |
66
|
17
|
|
|
|
|
48
|
last; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
0
|
0
|
|
|
|
0
|
if( can_run( $cxx ) ) { |
70
|
0
|
|
|
|
|
0
|
$self->{config}{cxx} = $cxx; |
71
|
0
|
|
|
|
|
0
|
last; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
} |
74
|
20
|
100
|
|
|
|
114
|
unless ( exists $self->{config}{cxx} ) { |
75
|
3
|
|
|
|
|
8
|
$self->{config}{cxx} = $self->{config}{cc}; |
76
|
3
|
|
|
|
|
7
|
my $cflags = $self->{config}{ccflags}; |
77
|
3
|
|
|
|
|
8
|
$self->{config}{cxxflags} = '-x c++'; |
78
|
3
|
50
|
|
|
|
29
|
$self->{config}{cxxflags} .= " $cflags" if defined $cflags; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
20
|
|
|
|
|
121
|
return $self; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub find_perl_interpreter { |
86
|
22
|
|
|
22
|
0
|
1856
|
my $perl; |
87
|
|
|
|
|
|
|
File::Spec->file_name_is_absolute($perl = $^X) |
88
|
|
|
|
|
|
|
or -f ($perl = $Config::Config{perlpath}) |
89
|
22
|
50
|
66
|
|
|
385
|
or ($perl = $^X); # XXX how about using IPC::Cmd::can_run here? |
90
|
22
|
|
|
|
|
192
|
return $perl; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub add_to_cleanup { |
94
|
1
|
|
|
1
|
0
|
2143
|
my $self = shift; |
95
|
1
|
|
|
|
|
10
|
foreach (@_) { |
96
|
1
|
|
|
|
|
16
|
$self->{files_to_clean}{$_} = 1; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub cleanup { |
101
|
21
|
|
|
21
|
0
|
663
|
my $self = shift; |
102
|
21
|
|
|
|
|
49
|
foreach my $file (keys %{$self->{files_to_clean}}) { |
|
21
|
|
|
|
|
9672
|
|
103
|
2
|
|
|
|
|
202
|
unlink $file; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub get_config { |
108
|
0
|
|
|
0
|
0
|
0
|
return %{ $_[0]->{config} }; |
|
0
|
|
|
|
|
0
|
|
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub object_file { |
112
|
15
|
|
|
15
|
0
|
1343
|
my ($self, $filename) = @_; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# File name, minus the suffix |
115
|
15
|
|
|
|
|
177
|
(my $file_base = $filename) =~ s/\.[^.]+$//; |
116
|
15
|
|
|
|
|
123
|
return "$file_base$self->{config}{obj_ext}"; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub arg_include_dirs { |
120
|
13
|
|
|
13
|
0
|
1445
|
my $self = shift; |
121
|
13
|
|
|
|
|
37
|
return map {"-I$_"} @_; |
|
18
|
|
|
|
|
105
|
|
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
13
|
|
|
13
|
0
|
652
|
sub arg_nolink { '-c' } |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub arg_object_file { |
127
|
13
|
|
|
13
|
0
|
63
|
my ($self, $file) = @_; |
128
|
13
|
|
|
|
|
101
|
return ('-o', $file); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub arg_share_object_file { |
132
|
9
|
|
|
9
|
0
|
579
|
my ($self, $file) = @_; |
133
|
9
|
|
|
|
|
69
|
return ($self->split_like_shell($self->{config}{lddlflags}), '-o', $file); |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub arg_exec_file { |
137
|
2
|
|
|
2
|
0
|
722
|
my ($self, $file) = @_; |
138
|
2
|
|
|
|
|
10
|
return ('-o', $file); |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub arg_defines { |
142
|
14
|
|
|
14
|
0
|
1682
|
my ($self, %args) = @_; |
143
|
14
|
|
|
|
|
107
|
return map "-D$_=$args{$_}", sort keys %args; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub compile { |
147
|
13
|
|
|
13
|
0
|
4585
|
my ($self, %args) = @_; |
148
|
13
|
100
|
|
|
|
83
|
die "Missing 'source' argument to compile()" unless defined $args{source}; |
149
|
|
|
|
|
|
|
|
150
|
12
|
|
|
|
|
34
|
my $cf = $self->{config}; # For convenience |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
my $object_file = $args{object_file} |
153
|
|
|
|
|
|
|
? $args{object_file} |
154
|
12
|
50
|
|
|
|
115
|
: $self->object_file($args{source}); |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
my $include_dirs_ref = |
157
|
|
|
|
|
|
|
(exists($args{include_dirs}) && ref($args{include_dirs}) ne "ARRAY") |
158
|
|
|
|
|
|
|
? [ $args{include_dirs} ] |
159
|
12
|
100
|
100
|
|
|
88
|
: $args{include_dirs}; |
160
|
|
|
|
|
|
|
my @include_dirs = $self->arg_include_dirs( |
161
|
12
|
100
|
|
|
|
28
|
@{ $include_dirs_ref || [] }, |
|
12
|
|
|
|
|
213
|
|
162
|
|
|
|
|
|
|
$self->perl_inc(), |
163
|
|
|
|
|
|
|
); |
164
|
|
|
|
|
|
|
|
165
|
12
|
50
|
|
|
|
39
|
my @defines = $self->arg_defines( %{$args{defines} || {}} ); |
|
12
|
|
|
|
|
153
|
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
my @extra_compiler_flags = |
168
|
12
|
|
|
|
|
147
|
$self->split_like_shell($args{extra_compiler_flags}); |
169
|
12
|
|
|
|
|
62
|
my @cccdlflags = $self->split_like_shell($cf->{cccdlflags}); |
170
|
12
|
100
|
|
|
|
1498
|
my @ccflags = $self->split_like_shell($args{'C++'} ? $cf->{cxxflags} : $cf->{ccflags}); |
171
|
12
|
|
|
|
|
1876
|
my @optimize = $self->split_like_shell($cf->{optimize}); |
172
|
12
|
|
|
|
|
629
|
my @flags = ( |
173
|
|
|
|
|
|
|
@include_dirs, |
174
|
|
|
|
|
|
|
@defines, |
175
|
|
|
|
|
|
|
@cccdlflags, |
176
|
|
|
|
|
|
|
@extra_compiler_flags, |
177
|
|
|
|
|
|
|
$self->arg_nolink, |
178
|
|
|
|
|
|
|
@ccflags, |
179
|
|
|
|
|
|
|
@optimize, |
180
|
|
|
|
|
|
|
$self->arg_object_file($object_file), |
181
|
|
|
|
|
|
|
); |
182
|
12
|
100
|
|
|
|
70
|
my @cc = $self->split_like_shell($args{'C++'} ? $cf->{cxx} : $cf->{cc}); |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
$self->do_system(@cc, @flags, $args{source}) |
185
|
12
|
100
|
|
|
|
755
|
or die "error building $object_file from '$args{source}'"; |
186
|
|
|
|
|
|
|
|
187
|
11
|
|
|
|
|
1035
|
return $object_file; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub have_compiler { |
191
|
9
|
|
|
9
|
0
|
2446
|
my ($self, $is_cplusplus) = @_; |
192
|
9
|
100
|
|
|
|
40
|
my $have_compiler_flag = $is_cplusplus ? "have_cxx" : "have_cc"; |
193
|
9
|
100
|
|
|
|
67
|
my $suffix = $is_cplusplus ? ".cc" : ".c"; |
194
|
9
|
100
|
|
|
|
69
|
return $self->{$have_compiler_flag} if defined $self->{$have_compiler_flag}; |
195
|
|
|
|
|
|
|
|
196
|
7
|
|
|
|
|
14
|
my $result; |
197
|
7
|
|
|
|
|
14
|
my $attempts = 3; |
198
|
|
|
|
|
|
|
# tmpdir has issues for some people so fall back to current dir |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
# don't clobber existing files (rare, but possible) |
201
|
7
|
|
|
|
|
82
|
my ( $FH, $tmpfile ) = tempfile( "compilet-XXXXX", SUFFIX => $suffix ); |
202
|
7
|
|
|
|
|
3323
|
binmode $FH; |
203
|
|
|
|
|
|
|
|
204
|
7
|
100
|
|
|
|
26
|
if ( $is_cplusplus ) { |
205
|
3
|
|
|
|
|
36
|
print $FH "class Bogus { public: int boot_compilet() { return 1; } };\n"; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
else { |
208
|
4
|
|
|
|
|
40
|
print $FH "int boot_compilet() { return 1; }\n"; |
209
|
|
|
|
|
|
|
} |
210
|
7
|
|
|
|
|
291
|
close $FH; |
211
|
|
|
|
|
|
|
|
212
|
7
|
|
|
|
|
30
|
my ($obj_file, @lib_files); |
213
|
7
|
|
|
|
|
18
|
eval { |
214
|
7
|
|
|
|
|
39
|
local $^W = 0; |
215
|
7
|
|
|
|
|
32
|
local $self->{quiet} = 1; |
216
|
7
|
|
|
|
|
65
|
$obj_file = $self->compile('C++' => $is_cplusplus, source => $tmpfile); |
217
|
6
|
|
|
|
|
495
|
@lib_files = $self->link(objects => $obj_file, module_name => 'compilet'); |
218
|
|
|
|
|
|
|
}; |
219
|
7
|
100
|
|
|
|
145
|
$result = $@ ? 0 : 1; |
220
|
|
|
|
|
|
|
|
221
|
7
|
|
|
|
|
171
|
foreach (grep defined, $tmpfile, $obj_file, @lib_files) { |
222
|
18
|
|
|
|
|
1127
|
1 while unlink; |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
7
|
|
|
|
|
480
|
return $self->{$have_compiler_flag} = $result; |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub have_cplusplus { |
229
|
4
|
|
|
4
|
0
|
2364
|
push @_, 1; |
230
|
4
|
|
|
|
|
96
|
goto &have_compiler; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub lib_file { |
234
|
10
|
|
|
10
|
0
|
97
|
my ($self, $dl_file, %args) = @_; |
235
|
10
|
|
|
|
|
226
|
$dl_file =~ s/\.[^.]+$//; |
236
|
10
|
|
|
|
|
55
|
$dl_file =~ tr/"//d; |
237
|
|
|
|
|
|
|
|
238
|
10
|
50
|
33
|
|
|
179
|
if (defined $args{module_name} and length $args{module_name}) { |
239
|
|
|
|
|
|
|
# Need to create with the same name as DynaLoader will load with. |
240
|
10
|
|
|
|
|
193
|
require DynaLoader; |
241
|
10
|
50
|
|
|
|
80
|
if (defined &DynaLoader::mod2fname) { |
242
|
0
|
|
|
|
|
0
|
my $lib = DynaLoader::mod2fname([split /::/, $args{module_name}]); |
243
|
0
|
|
|
|
|
0
|
my ($dev, $lib_dir, undef) = File::Spec->splitpath($dl_file); |
244
|
0
|
|
|
|
|
0
|
$dl_file = File::Spec->catpath($dev, $lib_dir, $lib); |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
10
|
|
|
|
|
59
|
$dl_file .= ".$self->{config}{dlext}"; |
249
|
|
|
|
|
|
|
|
250
|
10
|
|
|
|
|
66
|
return $dl_file; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub exe_file { |
255
|
1
|
|
|
1
|
0
|
8
|
my ($self, $dl_file) = @_; |
256
|
1
|
|
|
|
|
22
|
$dl_file =~ s/\.[^.]+$//; |
257
|
1
|
|
|
|
|
15
|
$dl_file =~ tr/"//d; |
258
|
1
|
|
|
|
|
12
|
return "$dl_file$self->{config}{_exe}"; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
8
|
|
|
8
|
0
|
56
|
sub need_prelink { 0 } |
262
|
|
|
|
|
|
|
|
263
|
9
|
|
|
9
|
0
|
46
|
sub extra_link_args_after_prelink { return } |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub prelink { |
266
|
0
|
|
|
0
|
0
|
0
|
my ($self, %args) = @_; |
267
|
|
|
|
|
|
|
|
268
|
0
|
|
|
|
|
0
|
my ($dl_file_out, $mksymlists_args) = _prepare_mksymlists_args(\%args); |
269
|
|
|
|
|
|
|
|
270
|
0
|
|
|
|
|
0
|
require ExtUtils::Mksymlists; |
271
|
|
|
|
|
|
|
# dl. abbrev for dynamic library |
272
|
0
|
|
|
|
|
0
|
ExtUtils::Mksymlists::Mksymlists( %{ $mksymlists_args } ); |
|
0
|
|
|
|
|
0
|
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
# Mksymlists will create one of these files |
275
|
0
|
|
|
|
|
0
|
return grep -e, map "$dl_file_out.$_", qw(ext def opt); |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub _prepare_mksymlists_args { |
279
|
2
|
|
|
2
|
|
4006
|
my $args = shift; |
280
|
2
|
100
|
|
|
|
29
|
($args->{dl_file} = $args->{dl_name}) =~ s/.*::// unless $args->{dl_file}; |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
my %mksymlists_args = ( |
283
|
|
|
|
|
|
|
DL_VARS => $args->{dl_vars} || [], |
284
|
|
|
|
|
|
|
DL_FUNCS => $args->{dl_funcs} || {}, |
285
|
|
|
|
|
|
|
FUNCLIST => $args->{dl_func_list} || [], |
286
|
|
|
|
|
|
|
IMPORTS => $args->{dl_imports} || {}, |
287
|
|
|
|
|
|
|
NAME => $args->{dl_name}, # Name of the Perl module |
288
|
|
|
|
|
|
|
DLBASE => $args->{dl_base}, # Basename of DLL file |
289
|
|
|
|
|
|
|
FILE => $args->{dl_file}, # Dir + Basename of symlist file |
290
|
2
|
100
|
100
|
|
|
89
|
VERSION => (defined $args->{dl_version} ? $args->{dl_version} : '0.0'), |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
291
|
|
|
|
|
|
|
); |
292
|
2
|
|
|
|
|
19
|
return ($args->{dl_file}, \%mksymlists_args); |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub link { |
296
|
8
|
|
|
8
|
0
|
134
|
my ($self, %args) = @_; |
297
|
8
|
|
|
|
|
153
|
return $self->_do_link('lib_file', lddl => 1, %args); |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
sub link_executable { |
301
|
1
|
|
|
1
|
0
|
11
|
my ($self, %args) = @_; |
302
|
1
|
|
|
|
|
10
|
return $self->_do_link('exe_file', lddl => 0, %args); |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub _do_link { |
306
|
9
|
|
|
9
|
|
124
|
my ($self, $type, %args) = @_; |
307
|
|
|
|
|
|
|
|
308
|
9
|
|
|
|
|
38
|
my $cf = $self->{config}; # For convenience |
309
|
|
|
|
|
|
|
|
310
|
9
|
|
|
|
|
45
|
my $objects = delete $args{objects}; |
311
|
9
|
50
|
|
|
|
79
|
$objects = [$objects] unless ref $objects; |
312
|
9
|
|
33
|
|
|
239
|
my $out = $args{$type} || $self->$type($objects->[0], %args); |
313
|
|
|
|
|
|
|
|
314
|
9
|
|
|
|
|
27
|
my @temp_files; |
315
|
|
|
|
|
|
|
@temp_files = |
316
|
|
|
|
|
|
|
$self->prelink(%args, dl_name => $args{module_name}) |
317
|
9
|
50
|
66
|
|
|
167
|
if $args{lddl} && $self->need_prelink; |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
my @linker_flags = ( |
320
|
|
|
|
|
|
|
$self->split_like_shell($args{extra_linker_flags}), |
321
|
|
|
|
|
|
|
$self->extra_link_args_after_prelink( |
322
|
9
|
|
|
|
|
123
|
%args, dl_name => $args{module_name}, prelink_res => \@temp_files |
323
|
|
|
|
|
|
|
) |
324
|
|
|
|
|
|
|
); |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
my @output = $args{lddl} |
327
|
9
|
100
|
|
|
|
187
|
? $self->arg_share_object_file($out) |
328
|
|
|
|
|
|
|
: $self->arg_exec_file($out); |
329
|
9
|
|
|
|
|
2095
|
my @shrp = $self->split_like_shell($cf->{shrpenv}); |
330
|
9
|
|
|
|
|
32
|
my @ld = $self->split_like_shell($cf->{ld}); |
331
|
|
|
|
|
|
|
|
332
|
9
|
100
|
|
|
|
867
|
$self->do_system(@shrp, @ld, @output, @$objects, @linker_flags) |
333
|
|
|
|
|
|
|
or die "error building $out from @$objects"; |
334
|
|
|
|
|
|
|
|
335
|
8
|
50
|
|
|
|
1041
|
return wantarray ? ($out, @temp_files) : $out; |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
sub do_system { |
340
|
19
|
|
|
19
|
0
|
115
|
my ($self, @cmd) = @_; |
341
|
19
|
100
|
|
|
|
310
|
print "@cmd\n" if !$self->{quiet}; |
342
|
19
|
|
|
|
|
392142
|
return !system(@cmd); |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
sub split_like_shell { |
346
|
100
|
|
|
100
|
0
|
3211
|
my ($self, $string) = @_; |
347
|
|
|
|
|
|
|
|
348
|
100
|
100
|
|
|
|
419
|
return () unless defined($string); |
349
|
74
|
100
|
|
|
|
414
|
return @$string if UNIVERSAL::isa($string, 'ARRAY'); |
350
|
73
|
|
|
|
|
503
|
$string =~ s/^\s+|\s+$//g; |
351
|
73
|
100
|
|
|
|
198
|
return () unless length($string); |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
# Text::ParseWords replaces all 'escaped' characters with themselves, which completely |
354
|
|
|
|
|
|
|
# breaks paths under windows. As such, we forcibly replace backwards slashes with forward |
355
|
|
|
|
|
|
|
# slashes on windows. |
356
|
64
|
50
|
|
|
|
287
|
$string =~ s@\\@/@g if $^O eq 'MSWin32'; |
357
|
|
|
|
|
|
|
|
358
|
64
|
|
|
|
|
376
|
return Text::ParseWords::shellwords($string); |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
# if building perl, perl's main source directory |
362
|
|
|
|
|
|
|
sub perl_src { |
363
|
|
|
|
|
|
|
# N.B. makemaker actually searches regardless of PERL_CORE, but |
364
|
|
|
|
|
|
|
# only squawks at not finding it if PERL_CORE is set |
365
|
|
|
|
|
|
|
|
366
|
17
|
100
|
|
17
|
0
|
11313
|
return unless $ENV{PERL_CORE}; |
367
|
|
|
|
|
|
|
|
368
|
4
|
|
|
|
|
55
|
my $Updir = File::Spec->updir; |
369
|
4
|
|
|
|
|
36
|
my $dir = File::Spec->curdir; |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# Try up to 5 levels upwards |
372
|
4
|
|
|
|
|
22
|
for (0..10) { |
373
|
34
|
100
|
100
|
|
|
633
|
if ( |
|
|
|
100
|
|
|
|
|
374
|
|
|
|
|
|
|
-f File::Spec->catfile($dir,"config_h.SH") |
375
|
|
|
|
|
|
|
&& |
376
|
|
|
|
|
|
|
-f File::Spec->catfile($dir,"perl.h") |
377
|
|
|
|
|
|
|
&& |
378
|
|
|
|
|
|
|
-f File::Spec->catfile($dir,"lib","Exporter.pm") |
379
|
|
|
|
|
|
|
) { |
380
|
1
|
|
|
|
|
21
|
return Cwd::realpath( $dir ); |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
|
383
|
33
|
|
|
|
|
244
|
$dir = File::Spec->catdir($dir, $Updir); |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
3
|
|
|
|
|
63
|
warn "PERL_CORE is set but I can't find your perl source!\n"; |
387
|
3
|
|
|
|
|
25
|
return ''; # return empty string if $ENV{PERL_CORE} but can't find dir ??? |
388
|
|
|
|
|
|
|
} |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# directory of perl's include files |
391
|
|
|
|
|
|
|
sub perl_inc { |
392
|
13
|
|
|
13
|
0
|
62
|
my $self = shift; |
393
|
|
|
|
|
|
|
|
394
|
13
|
50
|
|
|
|
107
|
$self->perl_src() || File::Spec->catdir($self->{config}{archlibexp},"CORE"); |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
sub DESTROY { |
398
|
20
|
|
|
20
|
|
17518
|
my $self = shift; |
399
|
20
|
|
|
|
|
405
|
local($., $@, $!, $^E, $?); |
400
|
20
|
|
|
|
|
245
|
$self->cleanup(); |
401
|
|
|
|
|
|
|
} |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
1; |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
# vim: ts=2 sw=2 et: |