From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

$ExtUtils::Builder::Linker::VERSION = '0.026';
use strict;
use parent qw/ExtUtils::Builder::ArgumentCollector ExtUtils::Builder::Binary/;
use ExtUtils::Builder::Util qw/command function/;
use Carp ();
use File::Basename 'dirname';
my %allowed_export = map { $_ => 1 } qw/none some all/;
sub new {
my ($class, %args) = @_;
my $self = bless {}, $class;
$self->_init(%args);
return $self;
}
sub _init {
my ($self, %args) = @_;
$self->ExtUtils::Builder::ArgumentCollector::_init(%args);
$self->ExtUtils::Builder::Binary::_init(%args);
my $export = $args{export};
Carp::croak("'$export' is not an allowed export value") if not $allowed_export{$export};
$self->{export} = $export;
$self->{ld} = $args{ld};
$self->{library_dirs} = [];
$self->{libraries} = [];
$self->{option_filters} = [];
return;
}
sub export {
my $self = shift;
return $self->{export};
}
sub ld {
my $self = shift;
return @{ $self->{ld} };
}
sub collect_arguments {
my ($self, @args) = @_;
return ($self->SUPER::collect_arguments(@args), $self->linker_flags(@args));
}
sub add_library_dirs {
my ($self, $dirs, %opts) = @_;
my $ranking = $self->fix_ranking($self->default_libdir_ranking, $opts{ranking});
push @{ $self->{library_dirs} }, map { { ranking => $ranking, value => $_ } } @{ $dirs };
return;
}
sub default_libdir_ranking {
return 30;
}
sub add_libraries {
my ($self, $dirs, %opts) = @_;
my $ranking = $self->fix_ranking($self->default_library_ranking, $opts{ranking});
push @{ $self->{libraries} }, map { { ranking => $ranking, value => $_ } } @{ $dirs };
return;
}
sub default_library_ranking {
return 75;
}
sub add_option_filter {
my ($self, $filter) = @_;
push @{ $self->{option_filters} }, $filter;
return;
}
my %key_for = (
dl_vars => 'DL_VARS',
dl_funcs => 'DL_FUNCS',
dl_func_list => 'FUNCLIST',
dl_imports => 'IMPORTS',
dl_name => 'NAME',
dl_base => 'DLBASE',
dl_file => 'FILE',
);
sub pre_action {
my ($self, $from, $to, %opts) = @_;
my @result;
if ($self->export eq 'some') {
my %args = map { $key_for{$_} => $opts{$_} } grep { exists $key_for{$_} } keys %opts;
push @result, function(
module => 'ExtUtils::Mksymlists',
function => 'Mksymlists',
message => join(' ', 'prelink', $to, %args),
arguments => [ %args ],
exports => 1,
);
}
if ($opts{mkdir}) {
my $dirname = File::Basename::dirname($to);
push @result, function(
module => 'File::Path',
function => 'make_path',
exports => 'explicit',
arguments => [ $dirname ],
message => "mkdir $dirname",
);
}
return @result;
}
sub post_action { }
sub link {
my ($self, @args) = @_;
@args = $self->$_(@args) for @{ $self->{option_filters} };
my ($from, $to, %opts) = @args;
my @argv = $self->arguments(@args);
my $main = command($self->ld, @argv);
my @actions = ($self->pre_action(@args), $main, $self->post_action(@args));
my $deps = [ @{$from}, @{ $opts{dependencies} // [] } ];
return ExtUtils::Builder::Node->new(target => $to, dependencies => $deps, actions => \@actions);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
ExtUtils::Builder::Linker
=head1 VERSION
version 0.026
=head1 METHODS
=head2 new
=over 4
=item type
This must be either C<executable>, C<shared-library>, C<loadable-object> or C<static-library>.
=item libraries
=item library_dirs
=item export
=back
=head2 add_library_dirs
=head2 add_libraries
=head2 link($source, $target, %options)
=head1 AUTHOR
Leon Timmermans <fawaka@gmail.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Leon Timmermans.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut