File Coverage

blib/lib/ExtUtils/Builder/Linker.pm
Criterion Covered Total %
statement 64 88 72.7
branch 4 8 50.0
condition 1 2 50.0
subroutine 16 21 76.1
pod 5 13 38.4
total 90 132 68.1


line stmt bran cond sub pod time code
1             package ExtUtils::Builder::Linker;
2             $ExtUtils::Builder::Linker::VERSION = '0.036';
3 3     3   1609 use strict;
  3         7  
  3         140  
4 3     3   15 use warnings;
  3         8  
  3         157  
5              
6 3     3   15 use parent qw/ExtUtils::Builder::ArgumentCollector ExtUtils::Builder::Binary/;
  3         6  
  3         32  
7              
8 3     3   770 use ExtUtils::Builder::Node;
  3         2611  
  3         107  
9 3     3   17 use ExtUtils::Builder::Util qw/command function require_module/;
  3         5  
  3         246  
10              
11 3     3   19 use Carp ();
  3         16  
  3         63  
12 3     3   14 use File::Basename 'dirname';
  3         5  
  3         3662  
13              
14             my %allowed_export = map { $_ => 1 } qw/none some all/;
15              
16             sub new {
17 5     5 1 243800 my ($class, %args) = @_;
18 5         15 my $self = bless {}, $class;
19 5         64 $self->_init(%args);
20 5         22 return $self;
21             }
22              
23             sub _init {
24 5     5   18 my ($self, %args) = @_;
25 5         48 $self->ExtUtils::Builder::ArgumentCollector::_init(%args);
26 5         30 $self->ExtUtils::Builder::Binary::_init(%args);
27              
28 5         13 my $export = $args{export};
29 5 50       18 Carp::croak("'$export' is not an allowed export value") if not $allowed_export{$export};
30 5         13 $self->{export} = $export;
31              
32 5         9 $self->{ld} = $args{ld};
33 5         12 $self->{library_dirs} = [];
34 5         13 $self->{libraries} = [];
35 5         14 $self->{option_filters} = [];
36              
37 5         15 return;
38             }
39              
40             sub export {
41 8     8 1 14 my $self = shift;
42 8         65 return $self->{export};
43             }
44              
45             sub ld {
46 5     5 0 8 my $self = shift;
47 5         10 return @{ $self->{ld} };
  5         58  
48             }
49              
50             sub collect_arguments {
51 5     5 0 42 my ($self, @args) = @_;
52 5         28 return ($self->SUPER::collect_arguments(@args), $self->linker_flags(@args));
53             }
54              
55             sub add_library_dirs {
56 0     0 1 0 my ($self, $dirs, %opts) = @_;
57 0         0 my $ranking = $self->fix_ranking($self->default_libdir_ranking, $opts{ranking});
58 0         0 push @{ $self->{library_dirs} }, map { { ranking => $ranking, value => $_ } } @{ $dirs };
  0         0  
  0         0  
  0         0  
59 0         0 return;
60             }
61              
62             sub default_libdir_ranking {
63 0     0 0 0 return 30;
64             }
65              
66             sub add_libraries {
67 0     0 1 0 my ($self, $dirs, %opts) = @_;
68 0         0 my $ranking = $self->fix_ranking($self->default_library_ranking, $opts{ranking});
69 0         0 push @{ $self->{libraries} }, map { { ranking => $ranking, value => $_ } } @{ $dirs };
  0         0  
  0         0  
  0         0  
70 0         0 return;
71             }
72              
73             sub default_library_ranking {
74 0     0 0 0 return 75;
75             }
76              
77             sub add_option_filter {
78 0     0 0 0 my ($self, $filter) = @_;
79 0         0 push @{ $self->{option_filters} }, $filter;
  0         0  
80 0         0 return;
81             }
82              
83             sub add_profile {
84 1     1 0 2 my ($self, $profile, %args) = @_;
85 1 50       9 if (not ref($profile)) {
86 1         5 $profile =~ s/ \A @ /ExtUtils::Builder::Profile::/xms;
87 1         2 require_module($profile);
88             }
89 1         14 return $profile->process_linker($self, \%args);
90             }
91              
92             my %key_for = (
93             dl_vars => 'DL_VARS',
94             dl_funcs => 'DL_FUNCS',
95             dl_func_list => 'FUNCLIST',
96             dl_imports => 'IMPORTS',
97             dl_name => 'NAME',
98             dl_base => 'DLBASE',
99             dl_file => 'FILE',
100             );
101             sub pre_action {
102 5     5 0 17 my ($self, $from, $to, %opts) = @_;
103 5         7 my @result;
104 5 50       20 push @result, $self->_mkdir_for($to) if $opts{mkdir};
105 5 50       17 if ($self->export eq 'some') {
106 0         0 my %args = map { $key_for{$_} => $opts{$_} } grep { exists $key_for{$_} } keys %opts;
  0         0  
  0         0  
107 0         0 push @result, function(
108             module => 'ExtUtils::Mksymlists',
109             function => 'Mksymlists',
110             message => join(' ', 'prelink', $to, %args),
111             arguments => [ %args ],
112             exports => 1,
113             );
114             }
115 5         25 return @result;
116             }
117       5 0   sub post_action { }
118              
119             sub link {
120 5     5 1 36 my ($self, @args) = @_;
121 5         10 @args = $self->$_(@args) for @{ $self->{option_filters} };
  5         16  
122 5         18 my ($from, $to, %opts) = @args;
123 5         49 my @argv = $self->arguments(@args);
124 5         28 my $main = command($self->ld, @argv);
125 5         2783 my @actions = ($self->pre_action(@args), $main, $self->post_action(@args));
126 5   50     8 my $deps = [ @{$from}, @{ $opts{dependencies} // [] } ];
  5         9  
  5         28  
127 5         30 return ExtUtils::Builder::Node->new(target => $to, dependencies => $deps, actions => \@actions);
128             }
129              
130             1;
131              
132             # ABSTRACT: An interface around different linkers.
133              
134             __END__