File Coverage

blib/lib/ExtUtils/Builder/BuildTools/FromPerl.pm
Criterion Covered Total %
statement 61 85 71.7
branch 16 56 28.5
condition 5 28 17.8
subroutine 13 14 92.8
pod 1 3 33.3
total 96 186 51.6


line stmt bran cond sub pod time code
1             package ExtUtils::Builder::BuildTools::FromPerl;
2             $ExtUtils::Builder::BuildTools::FromPerl::VERSION = '0.036';
3 2     2   667202 use strict;
  2         4  
  2         92  
4 2     2   9 use warnings;
  2         3  
  2         143  
5              
6 2     2   17 use parent 'ExtUtils::Builder::BuildTools::Base';
  2         3  
  2         15  
7              
8 2     2   125 use Carp 'croak';
  2         3  
  2         116  
9 2     2   11 use ExtUtils::Config 0.007;
  2         46  
  2         66  
10 2     2   11 use ExtUtils::Builder::Util 0.018 qw/require_module split_like_shell/;
  2         30  
  2         157  
11 2     2   1052 use Perl::OSType 'is_os_type';
  2         975  
  2         2993  
12              
13             sub _is_gcc {
14 2     2   7 my ($config, $cc, $opts) = @_;
15 2   33     8 return $config->get('gccversion') || $cc =~ / ^ (?: gcc | g[+]{2} | clang (?: [+]{2} ) ) /ix;
16             }
17              
18             my %gpp_map = (
19             'cc' => 'c++',
20             'gcc' => 'g++',
21             'clang' => 'clang++',
22             );
23             my %is_gpp = reverse %gpp_map;
24              
25             sub make_compiler {
26 2     2 0 4 my ($self, $opts) = @_;
27 2         9 my $os = $opts->{config}->get('osname');
28 2         27 my $raw_cc = $opts->{config}->get('cc');
29 2 50       33 my ($cc, @cc_extra) = ref $raw_cc ? @{$raw_cc} : split_like_shell($raw_cc);
  0         0  
30 2 0 33     580 my ($module, %command) = is_os_type('Unix', $os) || _is_gcc($opts->{config}, $cc) ? 'Unixy' : is_os_type('Windows', $os) ? ('MSVC', language => 'C') : croak 'Your platform is not supported yet';
    50          
31 2         57 $command{$_} = $opts->{$_} for grep { exists $opts->{$_} } qw/language type/;
  4         16  
32 2         9 $command{cccdlflags} = [ split_like_shell($opts->{config}->get('cccdlflags')) ];
33 2         185 my $module_name = "ExtUtils::Builder::Compiler::$module";
34              
35 2   50     13 my $language = $opts->{language} // 'C';
36 2         8 require_module($module_name);
37 2 50       26 if (uc $language eq 'C++') {
    50          
38 0 0       0 if ($module_name->isa('ExtUtils::Builder::Compiler::Unixy')) {
    0          
39 0 0       0 push @{ $command{extra_flags} }, qw/-xc++/ if _is_gcc($opts->{config}, $cc);
  0         0  
40 0 0 0     0 $cc = $gpp_map{$cc} // croak "Don't know C++ compiler for $cc" unless $is_gpp{$cc};
41             } elsif (!$module_name->isa('ExtUtils::Builder::Compiler::MSVC')) {
42 0         0 croak "Can't find C++ compiler for your platform";
43             }
44             } elsif (uc $language ne 'C') {
45 0         0 croak "Unknown language $language";
46             }
47              
48 2         39 return $module_name->new(cc => [$cc, @cc_extra], %command);
49             }
50              
51             sub _unix_flags {
52 0     0   0 my ($self, $opts) = @_;
53 0 0       0 return $opts->{lddlflags} if defined $opts->{lddlflags};
54 0         0 my $lddlflags = $opts->{config}->get('lddlflags');
55 0         0 my $optimize = $opts->{config}->get('optimize');
56 0 0       0 $lddlflags =~ s/ ?\Q$optimize// if not $opts->{auto_optimize};
57 0         0 my %ldflags = map { ($_ => 1) } split_like_shell($opts->{config}->get('ldflags'));
  0         0  
58 0         0 my @lddlflags = grep { not $ldflags{$_} } split_like_shell($lddlflags);
  0         0  
59 0         0 return (lddlflags => \@lddlflags )
60             }
61              
62             sub make_linker {
63 2     2 0 5 my ($self, $opts) = @_;
64 2         10 my $os = $opts->{config}->get('osname');
65 2         31 my $raw_cc = $opts->{config}->get('cc');
66 2 50       26 my ($cc, @cc_extra) = ref $raw_cc ? @{$raw_cc} : split_like_shell($raw_cc);
  0         0  
67 2         140 my $raw_ld = $opts->{config}->get('ld');
68 2 50       168 my ($ld, @ld_extra) = ref $raw_ld ? @{$raw_ld} : split_like_shell($raw_ld);
  0         0  
69 2 100       162 my ($eff_ld, @eff_extra) = ($opts->{type} eq 'executable') ? ($cc, @cc_extra) : ($ld, @ld_extra);
70             my ($module, $link, $extra, %command) =
71             $opts->{type} eq 'static-library' ? ('Ar', $opts->{config}->get('ar')) :
72             $os eq 'darwin' ? ('Mach::GCC', $eff_ld, \@eff_extra) :
73 2 50       15 _is_gcc($opts->{config}, $ld) ?
    0          
    0          
    0          
    50          
    50          
    50          
74             $os eq 'MSWin32' ? ('PE::GCC', $cc, \@cc_extra) : ('ELF::GCC', $eff_ld, \@eff_extra) :
75             $os eq 'aix' ? ('XCOFF', $cc, \@cc_extra) :
76             is_os_type('Unix', $os) ? ('ELF::Any', $eff_ld, \@eff_extra, $self->_unix_flags($opts)) :
77             $os eq 'MSWin32' ? ('PE::MSVC', $ld, \@ld_extra) :
78             croak 'Linking is not supported yet on your platform';
79 2         160 $command{$_} = $opts->{$_} for grep { exists $opts->{$_} } qw/exports language type/;
  6         25  
80 2         6 my $module_name = "ExtUtils::Builder::Linker::$module";
81              
82 2   50     15 my $language = $opts->{language} // 'C';
83 2         9 require_module($module_name);
84 2 50       23 if (uc $language eq 'C++') {
    50          
85 0         0 my $prefix = 'ExtUtils::Builder::Linker:';
86 0 0 0     0 if ($module_name->isa("$prefix:ELF::GCC") || $module_name->isa("$prefix:Mach::GCC") || $module_name->isa("$prefix:PE::GCC")) {
    0 0        
      0        
87 0 0 0     0 $link = $gpp_map{$link} // croak "Don't know C++ compiler for $link" unless $is_gpp{$link};
88             } elsif (!$module->isa("$prefix:PE::MSVC") && !$module->isa("$prefix:Ar")) {
89 0         0 croak "Can't find C++ linker for your platform";
90             }
91             } elsif (uc $language ne 'C') {
92 0         0 croak "Unknown language $language";
93             }
94              
95 2         4 return $module_name->new(ld => [ $link, @{$extra} ], %command);
  2         28  
96             }
97              
98             sub add_methods {
99 2     2 1 39 my ($class, $planner, %opts) = @_;
100              
101 2 50 33     47 $opts{config} //= $planner->can('config') ? $planner->config : ExtUtils::Config->new;
102 2         32 my $os = $opts{config}->get('osname');
103 2 50       48 my $lib_prefix = is_os_type('Unix', $os) ? 'lib' : '';
104              
105             $class->SUPER::add_methods($planner,
106             object_file => '%s' . $opts{config}->get('_o'),
107             library_file => "$lib_prefix%s." . $opts{config}->get('so'),
108             static_library_file => "$lib_prefix%s" . $opts{config}->get('_a'),
109             loadable_file => '%s.' . $opts{config}->get('dlext'),
110 2         32 executable_file => '%s' . $opts{config}->get('_exe'),
111             %opts,
112             );
113              
114             # backwards compatability
115             $planner->add_delegate('obj_file', sub {
116 1     1   1096 my ($this, @args) = @_;
        1      
117 1         7 return $this->object_file(@args);
118 2         52 });
119              
120 2         30 return;
121             }
122              
123             1;
124              
125             #ABSTRACT: compiler configuration, derived from perl's configuration
126              
127             __END__