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