| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package ExtUtils::CBuilder::Base; | 
| 2 | 5 |  |  | 5 |  | 93423 | use strict; | 
|  | 5 |  |  |  |  | 19 |  | 
|  | 5 |  |  |  |  | 142 |  | 
| 3 | 5 |  |  | 5 |  | 25 | use warnings; | 
|  | 5 |  |  |  |  | 10 |  | 
|  | 5 |  |  |  |  | 140 |  | 
| 4 | 5 |  |  | 5 |  | 24 | use File::Spec; | 
|  | 5 |  |  |  |  | 12 |  | 
|  | 5 |  |  |  |  | 99 |  | 
| 5 | 5 |  |  | 5 |  | 22 | use File::Basename; | 
|  | 5 |  |  |  |  | 9 |  | 
|  | 5 |  |  |  |  | 568 |  | 
| 6 | 5 |  |  | 5 |  | 38 | use Cwd (); | 
|  | 5 |  |  |  |  | 7 |  | 
|  | 5 |  |  |  |  | 98 |  | 
| 7 | 5 |  |  | 5 |  | 26 | use Config; | 
|  | 5 |  |  |  |  | 9 |  | 
|  | 5 |  |  |  |  | 277 |  | 
| 8 | 5 |  |  | 5 |  | 2526 | use Text::ParseWords; | 
|  | 5 |  |  |  |  | 6932 |  | 
|  | 5 |  |  |  |  | 371 |  | 
| 9 | 5 |  |  | 5 |  | 3507 | use IPC::Cmd qw(can_run); | 
|  | 5 |  |  |  |  | 299308 |  | 
|  | 5 |  |  |  |  | 373 |  | 
| 10 | 5 |  |  | 5 |  | 3443 | use File::Temp qw(tempfile); | 
|  | 5 |  |  |  |  | 52923 |  | 
|  | 5 |  |  |  |  | 14844 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | our $VERSION = '0.280235'; # 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 | 23296 | my $class = shift; | 
| 31 | 20 |  |  |  |  | 121 | my $self = bless {@_}, $class; | 
| 32 |  |  |  |  |  |  |  | 
| 33 | 20 | 50 |  |  |  | 146 | $self->{properties}{perl} = $class->find_perl_interpreter | 
| 34 |  |  |  |  |  |  | or warn "Warning: Can't locate your perl binary"; | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 20 |  |  |  |  | 904 | while (my ($k,$v) = each %Config) { | 
| 37 | 24520 | 100 |  |  |  | 384114 | $self->{config}{$k} = $v unless exists $self->{config}{$k}; | 
| 38 |  |  |  |  |  |  | } | 
| 39 | 20 | 100 |  |  |  | 130 | $self->{config}{cc} = $ENV{CC} if defined $ENV{CC}; | 
| 40 |  |  |  |  |  |  | $self->{config}{ccflags} = join(" ", $self->{config}{ccflags}, $ENV{CFLAGS}) | 
| 41 | 20 | 100 |  |  |  | 94 | if defined $ENV{CFLAGS}; | 
| 42 | 20 | 50 |  |  |  | 86 | $self->{config}{cxx} = $ENV{CXX} if defined $ENV{CXX}; | 
| 43 | 20 | 50 |  |  |  | 67 | $self->{config}{cxxflags} = $ENV{CXXFLAGS} if defined $ENV{CXXFLAGS}; | 
| 44 | 20 | 50 |  |  |  | 83 | $self->{config}{ld} = $ENV{LD} if defined $ENV{LD}; | 
| 45 |  |  |  |  |  |  | $self->{config}{ldflags} = join(" ", $self->{config}{ldflags}, $ENV{LDFLAGS}) | 
| 46 | 20 | 100 |  |  |  | 82 | if defined $ENV{LDFLAGS}; | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 20 | 50 |  |  |  | 71 | unless ( exists $self->{config}{cxx} ) { | 
| 49 |  |  |  |  |  |  |  | 
| 50 | 20 |  |  |  |  | 1503 | my ($ccbase, $ccpath, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/); | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | ## If the path is just "cc", fileparse returns $ccpath as "./" | 
| 53 | 20 | 100 |  |  |  | 443 | $ccpath = "" if $self->{config}{cc} =~ /^\Q$ccbase$ccsfx\E$/; | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 20 |  |  |  |  | 66 | foreach my $cxx (@{$cc2cxx{$ccbase}}) { | 
|  | 20 |  |  |  |  | 133 |  | 
| 56 | 17 |  |  |  |  | 354 | my $cxx1 = File::Spec->catfile( $ccpath, $cxx . $ccsfx); | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 17 | 50 |  |  |  | 572 | if( can_run( $cxx1 ) ) { | 
| 59 | 0 |  |  |  |  | 0 | $self->{config}{cxx} = $cxx1; | 
| 60 | 0 |  |  |  |  | 0 | last; | 
| 61 |  |  |  |  |  |  | } | 
| 62 | 17 |  |  |  |  | 404660 | my $cxx2 = $cxx . $ccsfx; | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 17 | 50 |  |  |  | 71 | if( can_run( $cxx2 ) ) { | 
| 65 | 17 |  |  |  |  | 7189 | $self->{config}{cxx} = $cxx2; | 
| 66 | 17 |  |  |  |  | 68 | 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 |  |  |  | 133 | unless ( exists $self->{config}{cxx} ) { | 
| 75 | 3 |  |  |  |  | 15 | $self->{config}{cxx} = $self->{config}{cc}; | 
| 76 | 3 |  |  |  |  | 10 | my $cflags = $self->{config}{ccflags}; | 
| 77 | 3 |  |  |  |  | 8 | $self->{config}{cxxflags} = '-x c++'; | 
| 78 | 3 | 50 |  |  |  | 35 | $self->{config}{cxxflags} .= " $cflags" if defined $cflags; | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  | } | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 20 |  |  |  |  | 150 | return $self; | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | sub find_perl_interpreter { | 
| 86 | 22 |  |  | 22 | 0 | 2754 | my $perl; | 
| 87 |  |  |  |  |  |  | File::Spec->file_name_is_absolute($perl = $^X) | 
| 88 |  |  |  |  |  |  | or -f ($perl = $Config::Config{perlpath}) | 
| 89 | 22 | 50 | 66 |  |  | 453 | or ($perl = $^X); # XXX how about using IPC::Cmd::can_run here? | 
| 90 | 22 |  |  |  |  | 180 | return $perl; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | sub add_to_cleanup { | 
| 94 | 1 |  |  | 1 | 0 | 3035 | my $self = shift; | 
| 95 | 1 |  |  |  |  | 9 | foreach (@_) { | 
| 96 | 1 |  |  |  |  | 18 | $self->{files_to_clean}{$_} = 1; | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | sub cleanup { | 
| 101 | 21 |  |  | 21 | 0 | 793 | my $self = shift; | 
| 102 | 21 |  |  |  |  | 70 | foreach my $file (keys %{$self->{files_to_clean}}) { | 
|  | 21 |  |  |  |  | 11510 |  | 
| 103 | 2 |  |  |  |  | 329 | 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 | 1752 | my ($self, $filename) = @_; | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | # File name, minus the suffix | 
| 115 | 15 |  |  |  |  | 203 | (my $file_base = $filename) =~ s/\.[^.]+$//; | 
| 116 | 15 |  |  |  |  | 136 | return "$file_base$self->{config}{obj_ext}"; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | sub arg_include_dirs { | 
| 120 | 13 |  |  | 13 | 0 | 1770 | my $self = shift; | 
| 121 | 13 |  |  |  |  | 45 | return map {"-I$_"} @_; | 
|  | 18 |  |  |  |  | 107 |  | 
| 122 |  |  |  |  |  |  | } | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 13 |  |  | 13 | 0 | 855 | sub arg_nolink { '-c' } | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | sub arg_object_file { | 
| 127 | 13 |  |  | 13 | 0 | 44 | my ($self, $file) = @_; | 
| 128 | 13 |  |  |  |  | 95 | return ('-o', $file); | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  |  | 
| 131 |  |  |  |  |  |  | sub arg_share_object_file { | 
| 132 | 9 |  |  | 9 | 0 | 700 | my ($self, $file) = @_; | 
| 133 | 9 |  |  |  |  | 71 | return ($self->split_like_shell($self->{config}{lddlflags}), '-o', $file); | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  |  | 
| 136 |  |  |  |  |  |  | sub arg_exec_file { | 
| 137 | 2 |  |  | 2 | 0 | 885 | my ($self, $file) = @_; | 
| 138 | 2 |  |  |  |  | 16 | return ('-o', $file); | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | sub arg_defines { | 
| 142 | 14 |  |  | 14 | 0 | 2263 | my ($self, %args) = @_; | 
| 143 | 14 |  |  |  |  | 97 | return map "-D$_=$args{$_}", sort keys %args; | 
| 144 |  |  |  |  |  |  | } | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | sub compile { | 
| 147 | 13 |  |  | 13 | 0 | 5358 | my ($self, %args) = @_; | 
| 148 | 13 | 100 |  |  |  | 117 | die "Missing 'source' argument to compile()" unless defined $args{source}; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 12 |  |  |  |  | 38 | 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 |  |  | 95 | : $args{include_dirs}; | 
| 160 |  |  |  |  |  |  | my @include_dirs = $self->arg_include_dirs( | 
| 161 | 12 | 100 |  |  |  | 33 | @{ $include_dirs_ref || [] }, | 
|  | 12 |  |  |  |  | 224 |  | 
| 162 |  |  |  |  |  |  | $self->perl_inc(), | 
| 163 |  |  |  |  |  |  | ); | 
| 164 |  |  |  |  |  |  |  | 
| 165 | 12 | 50 |  |  |  | 69 | my @defines = $self->arg_defines( %{$args{defines} || {}} ); | 
|  | 12 |  |  |  |  | 185 |  | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | my @extra_compiler_flags = | 
| 168 | 12 |  |  |  |  | 117 | $self->split_like_shell($args{extra_compiler_flags}); | 
| 169 | 12 |  |  |  |  | 81 | my @cccdlflags = $self->split_like_shell($cf->{cccdlflags}); | 
| 170 | 12 | 100 |  |  |  | 1734 | my @ccflags = $self->split_like_shell($args{'C++'} ? $cf->{cxxflags} : $cf->{ccflags}); | 
| 171 | 12 |  |  |  |  | 1898 | my @optimize = $self->split_like_shell($cf->{optimize}); | 
| 172 | 12 |  |  |  |  | 693 | 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 |  |  |  | 74 | my @cc = $self->split_like_shell($args{'C++'} ? $cf->{cxx} : $cf->{cc}); | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | $self->do_system(@cc, @flags, $args{source}) | 
| 185 | 12 | 100 |  |  |  | 785 | or die "error building $object_file from '$args{source}'"; | 
| 186 |  |  |  |  |  |  |  | 
| 187 | 11 |  |  |  |  | 1206 | return $object_file; | 
| 188 |  |  |  |  |  |  | } | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | sub have_compiler { | 
| 191 | 9 |  |  | 9 | 0 | 2480 | my ($self, $is_cplusplus) = @_; | 
| 192 | 9 | 100 |  |  |  | 45 | my $have_compiler_flag = $is_cplusplus ? "have_cxx" : "have_cc"; | 
| 193 | 9 | 100 |  |  |  | 37 | my $suffix = $is_cplusplus ? ".cc" : ".c"; | 
| 194 | 9 | 100 |  |  |  | 59 | return $self->{$have_compiler_flag} if defined $self->{$have_compiler_flag}; | 
| 195 |  |  |  |  |  |  |  | 
| 196 | 7 |  |  |  |  | 17 | my $result; | 
| 197 | 7 |  |  |  |  | 25 | 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 |  |  |  |  | 84 | my ( $FH, $tmpfile ) = tempfile( "compilet-XXXXX", SUFFIX => $suffix ); | 
| 202 | 7 |  |  |  |  | 3909 | binmode $FH; | 
| 203 |  |  |  |  |  |  |  | 
| 204 | 7 | 100 |  |  |  | 31 | if ( $is_cplusplus ) { | 
| 205 | 3 |  |  |  |  | 54 | print $FH "class Bogus { public: int boot_compilet() { return 1; } };\n"; | 
| 206 |  |  |  |  |  |  | } | 
| 207 |  |  |  |  |  |  | else { | 
| 208 | 4 |  |  |  |  | 56 | print $FH "int boot_compilet() { return 1; }\n"; | 
| 209 |  |  |  |  |  |  | } | 
| 210 | 7 |  |  |  |  | 385 | close $FH; | 
| 211 |  |  |  |  |  |  |  | 
| 212 | 7 |  |  |  |  | 34 | my ($obj_file, @lib_files); | 
| 213 | 7 |  |  |  |  | 22 | eval { | 
| 214 | 7 |  |  |  |  | 43 | local $^W = 0; | 
| 215 | 7 |  |  |  |  | 40 | local $self->{quiet} = 1; | 
| 216 | 7 |  |  |  |  | 79 | $obj_file = $self->compile('C++' => $is_cplusplus, source => $tmpfile); | 
| 217 | 6 |  |  |  |  | 557 | @lib_files = $self->link(objects => $obj_file, module_name => 'compilet'); | 
| 218 |  |  |  |  |  |  | }; | 
| 219 | 7 | 100 |  |  |  | 137 | $result = $@ ? 0 : 1; | 
| 220 |  |  |  |  |  |  |  | 
| 221 | 7 |  |  |  |  | 205 | foreach (grep defined, $tmpfile, $obj_file, @lib_files) { | 
| 222 | 18 |  |  |  |  | 1333 | 1 while unlink; | 
| 223 |  |  |  |  |  |  | } | 
| 224 |  |  |  |  |  |  |  | 
| 225 | 7 |  |  |  |  | 528 | return $self->{$have_compiler_flag} = $result; | 
| 226 |  |  |  |  |  |  | } | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | sub have_cplusplus { | 
| 229 | 4 |  |  | 4 | 0 | 2854 | push @_, 1; | 
| 230 | 4 |  |  |  |  | 122 | goto &have_compiler; | 
| 231 |  |  |  |  |  |  | } | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | sub lib_file { | 
| 234 | 10 |  |  | 10 | 0 | 87 | my ($self, $dl_file, %args) = @_; | 
| 235 | 10 |  |  |  |  | 242 | $dl_file =~ s/\.[^.]+$//; | 
| 236 | 10 |  |  |  |  | 105 | $dl_file =~ tr/"//d; | 
| 237 |  |  |  |  |  |  |  | 
| 238 | 10 | 50 | 33 |  |  | 182 | 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 |  |  |  |  | 220 | require DynaLoader; | 
| 241 | 10 | 50 |  |  |  | 66 | 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 |  |  |  |  | 68 | $dl_file .= ".$self->{config}{dlext}"; | 
| 249 |  |  |  |  |  |  |  | 
| 250 | 10 |  |  |  |  | 72 | return $dl_file; | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | sub exe_file { | 
| 255 | 1 |  |  | 1 | 0 | 16 | my ($self, $dl_file) = @_; | 
| 256 | 1 |  |  |  |  | 21 | $dl_file =~ s/\.[^.]+$//; | 
| 257 | 1 |  |  |  |  | 20 | $dl_file =~ tr/"//d; | 
| 258 | 1 |  |  |  |  | 9 | return "$dl_file$self->{config}{_exe}"; | 
| 259 |  |  |  |  |  |  | } | 
| 260 |  |  |  |  |  |  |  | 
| 261 | 8 |  |  | 8 | 0 | 59 | sub need_prelink { 0 } | 
| 262 |  |  |  |  |  |  |  | 
| 263 | 9 |  |  | 9 | 0 | 43 | 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 |  | 4809 | my $args = shift; | 
| 280 | 2 | 100 |  |  |  | 35 | ($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 |  |  | 74 | 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 | 151 | my ($self, %args) = @_; | 
| 297 | 8 |  |  |  |  | 185 | 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 |  |  |  |  | 20 | return $self->_do_link('exe_file', lddl => 0, %args); | 
| 303 |  |  |  |  |  |  | } | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | sub _do_link { | 
| 306 | 9 |  |  | 9 |  | 135 | my ($self, $type, %args) = @_; | 
| 307 |  |  |  |  |  |  |  | 
| 308 | 9 |  |  |  |  | 36 | my $cf = $self->{config}; # For convenience | 
| 309 |  |  |  |  |  |  |  | 
| 310 | 9 |  |  |  |  | 50 | my $objects = delete $args{objects}; | 
| 311 | 9 | 50 |  |  |  | 103 | $objects = [$objects] unless ref $objects; | 
| 312 | 9 |  | 33 |  |  | 260 | my $out = $args{$type} || $self->$type($objects->[0], %args); | 
| 313 |  |  |  |  |  |  |  | 
| 314 | 9 |  |  |  |  | 46 | my @temp_files; | 
| 315 |  |  |  |  |  |  | @temp_files = | 
| 316 |  |  |  |  |  |  | $self->prelink(%args, dl_name => $args{module_name}) | 
| 317 | 9 | 50 | 66 |  |  | 170 | 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 |  |  |  |  | 166 | %args, dl_name => $args{module_name}, prelink_res => \@temp_files | 
| 323 |  |  |  |  |  |  | ) | 
| 324 |  |  |  |  |  |  | ); | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | my @output = $args{lddl} | 
| 327 | 9 | 100 |  |  |  | 196 | ? $self->arg_share_object_file($out) | 
| 328 |  |  |  |  |  |  | : $self->arg_exec_file($out); | 
| 329 | 9 |  |  |  |  | 2268 | my @shrp = $self->split_like_shell($cf->{shrpenv}); | 
| 330 | 9 |  |  |  |  | 54 | my @ld = $self->split_like_shell($cf->{ld}); | 
| 331 |  |  |  |  |  |  |  | 
| 332 | 9 | 100 |  |  |  | 875 | $self->do_system(@shrp, @ld, @output, @$objects, @linker_flags) | 
| 333 |  |  |  |  |  |  | or die "error building $out from @$objects"; | 
| 334 |  |  |  |  |  |  |  | 
| 335 | 8 | 50 |  |  |  | 1181 | return wantarray ? ($out, @temp_files) : $out; | 
| 336 |  |  |  |  |  |  | } | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  |  | 
| 339 |  |  |  |  |  |  | sub do_system { | 
| 340 | 19 |  |  | 19 | 0 | 121 | my ($self, @cmd) = @_; | 
| 341 | 19 | 100 |  |  |  | 332 | print "@cmd\n" if !$self->{quiet}; | 
| 342 | 19 |  |  |  |  | 434287 | return !system(@cmd); | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | sub split_like_shell { | 
| 346 | 100 |  |  | 100 | 0 | 3431 | my ($self, $string) = @_; | 
| 347 |  |  |  |  |  |  |  | 
| 348 | 100 | 100 |  |  |  | 488 | return () unless defined($string); | 
| 349 | 74 | 100 |  |  |  | 466 | return @$string if UNIVERSAL::isa($string, 'ARRAY'); | 
| 350 | 73 |  |  |  |  | 537 | $string =~ s/^\s+|\s+$//g; | 
| 351 | 73 | 100 |  |  |  | 222 | 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 |  |  |  | 317 | $string =~ s@\\@/@g if $^O eq 'MSWin32'; | 
| 357 |  |  |  |  |  |  |  | 
| 358 | 64 |  |  |  |  | 401 | 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 | 13038 | return unless $ENV{PERL_CORE}; | 
| 367 |  |  |  |  |  |  |  | 
| 368 | 4 |  |  |  |  | 64 | my $Updir = File::Spec->updir; | 
| 369 | 4 |  |  |  |  | 35 | my $dir   = File::Spec->curdir; | 
| 370 |  |  |  |  |  |  |  | 
| 371 |  |  |  |  |  |  | # Try up to 5 levels upwards | 
| 372 | 4 |  |  |  |  | 27 | for (0..10) { | 
| 373 | 34 | 100 | 100 |  |  | 675 | 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 |  |  |  |  | 265 | $dir = File::Spec->catdir($dir, $Updir); | 
| 384 |  |  |  |  |  |  | } | 
| 385 |  |  |  |  |  |  |  | 
| 386 | 3 |  |  |  |  | 59 | warn "PERL_CORE is set but I can't find your perl source!\n"; | 
| 387 | 3 |  |  |  |  | 29 | 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 | 58 | my $self = shift; | 
| 393 |  |  |  |  |  |  |  | 
| 394 | 13 | 50 |  |  |  | 96 | $self->perl_src() || File::Spec->catdir($self->{config}{archlibexp},"CORE"); | 
| 395 |  |  |  |  |  |  | } | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | sub DESTROY { | 
| 398 | 20 |  |  | 20 |  | 21342 | my $self = shift; | 
| 399 | 20 |  |  |  |  | 490 | local($., $@, $!, $^E, $?); | 
| 400 | 20 |  |  |  |  | 334 | $self->cleanup(); | 
| 401 |  |  |  |  |  |  | } | 
| 402 |  |  |  |  |  |  |  | 
| 403 |  |  |  |  |  |  | 1; | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | # vim: ts=2 sw=2 et: |