Initial Commit

This commit is contained in:
Riley Schneider
2025-12-03 16:38:10 +01:00
parent c5e26bf594
commit b732d8d4b5
17680 changed files with 5977495 additions and 2 deletions

1207
database/perl/vendor/lib/Alien/Base.pm vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
# ABSTRACT: Authoring an Alien distribution using Alien::Base
# PODNAME: Alien::Base::Authoring
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Base::Authoring - Authoring an Alien distribution using Alien::Base
=head1 VERSION
version 2.38
=head1 SYNOPSIS
% perldoc Alien::Build::Manual::AlienAuthor
% perldoc Alien::Base::ModuleBuild::Authoring
=head1 DESCRIPTION
This used to document the only way to author an L<Alien> distribution, which
was with L<Alien::Base::ModuleBuild>. You should now seriously consider using
the newer more reliable method which is via L<Alien::Build> and L<alienfile>. Read all about it in L<Alien::Build::Manual::AlienAuthor> and L<Alien::Base::ModuleBuild::Authoring>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,106 @@
# ABSTRACT: Frequently asked questions
# VERSION
# PODNAME: Alien::Base::FAQ
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Base::FAQ - Frequently asked questions
=head1 VERSION
version 2.38
=head1 SYNOPSIS
% perldoc Alien::Build::Manual::FAQ
% perldoc Alien::Base::ModuleBuild::FAQ
=head1 DESCRIPTION
This used to answer FAQs regarding the only way to author an L<Alien::Build>
distribution, which was with L<Aien::Base::ModuleBuild>. You should now
seriously consider using the newer more reliable method which is via
L<Alien::Build> and L<alienfile>.
=over 4
=item L<Alien::Build::Manual::FAQ>
=item L<Alien::Base::ModuleBuild::FAQ>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,254 @@
package Alien::Base::PkgConfig;
use strict;
use warnings;
use 5.008004;
use Carp;
use Config;
use Path::Tiny qw( path );
use Capture::Tiny qw( capture_stderr );
# ABSTRACT: Private legacy pkg-config class for Alien::Base
our $VERSION = '2.38'; # VERSION
sub new {
my $class = shift;
# allow creation of an object from a full spec.
if (ref $_[0] eq 'HASH') {
return bless $_[0], $class;
}
my ($path) = @_;
croak "Must specify a file" unless defined $path;
$path = path( $path )->absolute;
my($name) = $path->basename =~ /^(.*)\.pc$/;
my $self = {
package => $name,
vars => { pcfiledir => $path->parent->stringify },
keywords => {},
};
bless $self, $class;
$self->read($path);
return $self;
}
sub read {
my $self = shift;
my ($path) = @_;
open my $fh, '<', $path
or croak "Cannot open .pc file $path: $!";
while (my $line = <$fh>) {
if ($line =~ /^([^=:]+?)=([^\n\r]*)/) {
$self->{vars}{$1} = $2;
} elsif ($line =~ /^([^=:]+?):\s*([^\n\r]*)/) {
$self->{keywords}{$1} = $2;
}
}
}
# getter/setter for vars
sub var {
my $self = shift;
my ($var, $newval) = @_;
if (defined $newval) {
$self->{vars}{$var} = $newval;
}
return $self->{vars}{$var};
}
# abstract keywords and other vars in terms of "pure" vars
sub make_abstract {
my $self = shift;
die "make_abstract needs a key (and possibly a value)" unless @_;
my ($var, $value) = @_;
$value = defined $value ? $value : $self->{vars}{$var};
# convert other vars
foreach my $key (keys %{ $self->{vars} }) {
next if $key eq $var; # don't overwrite the current var
$self->{vars}{$key} =~ s/\Q$value\E/\$\{$var\}/g;
}
# convert keywords
foreach my $key (keys %{ $self->{keywords} }) {
$self->{keywords}{$key} =~ s/\Q$value\E/\$\{$var\}/g;
}
}
sub _interpolate_vars {
my $self = shift;
my ($string, $override) = @_;
$override ||= {};
foreach my $key (keys %$override) {
carp "Overriden pkg-config variable $key, contains no data"
unless $override->{$key};
}
if (defined $string) {
1 while $string =~ s/\$\{(.*?)\}/$override->{$1} || $self->{vars}{$1}/e;
}
return $string;
}
sub keyword {
my $self = shift;
my ($keyword, $override) = @_;
{
no warnings 'uninitialized';
croak "overrides passed to 'keyword' must be a hashref"
if defined $override and ref $override ne 'HASH';
}
return $self->_interpolate_vars( $self->{keywords}{$keyword}, $override );
}
my $pkg_config_command;
sub pkg_config_command {
unless (defined $pkg_config_command) {
capture_stderr {
# For now we prefer PkgConfig.pm over pkg-config on
# Solaris 64 bit Perls. We may need to do this on
# other platforms, in which case this logic should
# be abstracted so that it can be shared here and
# in Build.PL
if (`pkg-config --version` && $? == 0 && !($^O eq 'solaris' && $Config{ptrsize} == 8)) {
$pkg_config_command = 'pkg-config';
} else {
require PkgConfig;
$pkg_config_command = "$^X $INC{'PkgConfig.pm'}";
}
}
}
$pkg_config_command;
}
sub TO_JSON
{
my($self) = @_;
my %hash = %$self;
$hash{'__CLASS__'} = ref($self);
\%hash;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Base::PkgConfig - Private legacy pkg-config class for Alien::Base
=head1 VERSION
version 2.38
=head1 DESCRIPTION
This class is used internally by L<Alien::Base> and L<Alien::Base::ModuleBuild>
to store information from pkg-config about installed Aliens. It is not used
internally by the newer L<alienfile> and L<Alien::Build>. It should never
be used externally, should not be used for code new inside of C<Alien-Build>.
=head1 SEE ALSO
=over
=item L<Alien::Base>
=item L<alienfile>
=item L<Alien::Build>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,571 @@
package Alien::Base::Wrapper;
use strict;
use warnings;
use 5.006;
use Config;
use Text::ParseWords qw( shellwords );
# NOTE: Although this module is now distributed with Alien-Build,
# it should have NO non-perl-core dependencies for all Perls
# 5.6.0-5.30.1 (as of this writing, and any Perl more recent).
# You should be able to extract this module from the rest of
# Alien-Build and use it by itself. (There is a dzil plugin
# for this [AlienBase::Wrapper::Bundle]
# ABSTRACT: Compiler and linker wrapper for Alien
our $VERSION = '2.38'; # VERSION
sub _join
{
join ' ', map { s/(\s)/\\$1/g; $_ } map { "$_" } @_; ## no critic (ControlStructures::ProhibitMutatingListFunctions)
}
sub new
{
my($class, @aliens) = @_;
my $export = 1;
my $writemakefile = 0;
my @cflags_I;
my @cflags_other;
my @ldflags_L;
my @ldflags_l;
my @ldflags_other;
my %requires = (
'ExtUtils::MakeMaker' => '6.52',
'Alien::Base::Wrapper' => '1.97',
);
foreach my $alien (@aliens)
{
if($alien eq '!export')
{
$export = 0;
next;
}
if($alien eq 'WriteMakefile')
{
$writemakefile = 1;
next;
}
my $version = 0;
if($alien =~ s/=(.*)$//)
{
$version = $1;
}
$alien = "Alien::$alien" unless $alien =~ /::/;
$requires{$alien} = $version;
my $alien_pm = $alien . '.pm';
$alien_pm =~ s/::/\//g;
require $alien_pm unless eval { $alien->can('cflags') } && eval { $alien->can('libs') };
my $cflags;
my $libs;
if($alien->install_type eq 'share' && $alien->can('cflags_static'))
{
$cflags = $alien->cflags_static;
$libs = $alien->libs_static;
}
else
{
$cflags = $alien->cflags;
$libs = $alien->libs;
}
push @cflags_I, grep /^-I/, shellwords $cflags;
push @cflags_other, grep !/^-I/, shellwords $cflags;
push @ldflags_L, grep /^-L/, shellwords $libs;
push @ldflags_l, grep /^-l/, shellwords $libs;
push @ldflags_other, grep !/^-[Ll]/, shellwords $libs;
}
my @cflags_define = grep /^-D/, @cflags_other;
my @cflags_other2 = grep !/^-D/, @cflags_other;
my @mm;
push @mm, INC => _join @cflags_I if @cflags_I;
push @mm, CCFLAGS => _join(@cflags_other2) . " $Config{ccflags}" if @cflags_other2;
push @mm, DEFINE => _join(@cflags_define) if @cflags_define;
# TODO: handle spaces in -L paths
push @mm, LIBS => ["@ldflags_L @ldflags_l"];
my @ldflags = (@ldflags_L, @ldflags_other);
push @mm, LDDLFLAGS => _join(@ldflags) . " $Config{lddlflags}" if @ldflags;
push @mm, LDFLAGS => _join(@ldflags) . " $Config{ldflags}" if @ldflags;
my @mb;
push @mb, extra_compiler_flags => _join(@cflags_I, @cflags_other);
push @mb, extra_linker_flags => _join(@ldflags_l);
if(@ldflags)
{
push @mb, config => {
lddlflags => _join(@ldflags) . " $Config{lddlflags}",
ldflags => _join(@ldflags) . " $Config{ldflags}",
},
}
bless {
cflags_I => \@cflags_I,
cflags_other => \@cflags_other,
ldflags_L => \@ldflags_L,
ldflags_l => \@ldflags_l,
ldflags_other => \@ldflags_other,
mm => \@mm,
mb => \@mb,
_export => $export,
_writemakefile => $writemakefile,
requires => \%requires,
}, $class;
}
my $default_abw = __PACKAGE__->new;
# for testing only
sub _reset { __PACKAGE__->new }
sub _myexec
{
my @command = @_;
if($^O eq 'MSWin32')
{
# To handle weird quoting on MSWin32
# this logic needs to be improved.
my $command = "@command";
$command =~ s{"}{\\"}g;
system $command;
if($? == -1 )
{
die "failed to execute: $!\n";
}
elsif($? & 127)
{
die "child died with signal @{[ $? & 128 ]}";
}
else
{
exit($? >> 8);
}
}
else
{
exec @command;
}
}
sub cc
{
my @command = (
shellwords($Config{cc}),
@{ $default_abw->{cflags_I} },
@{ $default_abw->{cflags_other} },
@ARGV,
);
print "@command\n" unless $ENV{ALIEN_BASE_WRAPPER_QUIET};
_myexec @command;
}
sub ld
{
my @command = (
shellwords($Config{ld}),
@{ $default_abw->{ldflags_L} },
@{ $default_abw->{ldflags_other} },
@ARGV,
@{ $default_abw->{ldflags_l} },
);
print "@command\n" unless $ENV{ALIEN_BASE_WRAPPER_QUIET};
_myexec @command;
}
sub mm_args
{
my $self = ref $_[0] ? shift : $default_abw;
@{ $self->{mm} };
}
sub mm_args2
{
my $self = shift;
$self = $default_abw unless ref $self;
my %args = @_;
my @mm = @{ $self->{mm} };
while(@mm)
{
my $key = shift @mm;
my $value = shift @mm;
if(defined $args{$key})
{
if($args{$key} eq 'LIBS')
{
require Carp;
# Todo: support this maybe?
Carp::croak("please do not specify your own LIBS key with mm_args2");
}
else
{
$args{$key} = join ' ', $value, $args{$key};
}
}
else
{
$args{$key} = $value;
}
}
foreach my $module (keys %{ $self->{requires} })
{
$args{CONFIGURE_REQUIRES}->{$module} = $self->{requires}->{$module};
}
%args;
}
sub mb_args
{
my $self = ref $_[0] ? shift : $default_abw;
@{ $self->{mb} };
}
sub import
{
shift;
my $abw = $default_abw = __PACKAGE__->new(@_);
if($abw->_export)
{
my $caller = caller;
no strict 'refs';
*{"${caller}::cc"} = \&cc;
*{"${caller}::ld"} = \&ld;
}
if($abw->_writemakefile)
{
my $caller = caller;
no strict 'refs';
*{"${caller}::WriteMakefile"} = \&WriteMakefile;
}
}
sub WriteMakefile
{
my %args = @_;
require ExtUtils::MakeMaker;
ExtUtils::MakeMaker->VERSION('6.52');
my @aliens;
if(my $reqs = delete $args{alien_requires})
{
if(ref $reqs eq 'HASH')
{
@aliens = map {
my $module = $_;
my $version = $reqs->{$module};
$version ? "$module=$version" : "$module";
} sort keys %$reqs;
}
elsif(ref $reqs eq 'ARRAY')
{
@aliens = @$reqs;
}
else
{
require Carp;
Carp::croak("aliens_require must be either a hash or array reference");
}
}
else
{
require Carp;
Carp::croak("You are using Alien::Base::Wrapper::WriteMakefile, but didn't specify any alien requirements");
}
ExtUtils::MakeMaker::WriteMakefile(
Alien::Base::Wrapper->new(@aliens)->mm_args2(%args),
);
}
sub _export { shift->{_export} }
sub _writemakefile { shift->{_writemakefile} }
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Base::Wrapper - Compiler and linker wrapper for Alien
=head1 VERSION
version 2.38
=head1 SYNOPSIS
From the command line:
% perl -MAlien::Base::Wrapper=Alien::Foo,Alien::Bar -e cc -- -o foo.o -c foo.c
% perl -MAlien::Base::Wrapper=Alien::Foo,Alien::Bar -e ld -- -o foo foo.o
From Makefile.PL (static):
use ExtUtils::MakeMaker;
use Alien::Base::Wrapper ();
WriteMakefile(
Alien::Base::Wrapper->new( 'Alien::Foo', 'Alien::Bar')->mm_args2(
'NAME' => 'Foo::XS',
'VERSION_FROM' => 'lib/Foo/XS.pm',
),
);
From Makefile.PL (static with wrapper)
use Alien::Base::Wrapper qw( WriteMakefile);
WriteMakefile(
'NAME' => 'Foo::XS',
'VERSION_FROM' => 'lib/Foo/XS.pm',
'alien_requires' => {
'Alien::Foo' => 0,
'Alien::Bar' => 0,
},
);
From Makefile.PL (dynamic):
use Devel::CheckLib qw( check_lib );
use ExtUtils::MakeMaker 6.52;
my @mm_args;
my @libs;
if(check_lib( lib => [ 'foo' ] )
{
push @mm_args, LIBS => [ '-lfoo' ];
}
else
{
push @mm_args,
CC => '$(FULLPERL) -MAlien::Base::Wrapper=Alien::Foo -e cc --',
LD => '$(FULLPERL) -MAlien::Base::Wrapper=Alien::Foo -e ld --',
BUILD_REQUIRES => {
'Alien::Foo' => 0,
'Alien::Base::Wrapper' => 0,
}
;
}
WriteMakefile(
'NAME' => 'Foo::XS',
'VERSION_FROM' => 'lib/Foo/XS.pm',
'CONFIGURE_REQUIRES => {
'ExtUtils::MakeMaker' => 6.52,
},
@mm_args,
);
=head1 DESCRIPTION
This module acts as a wrapper around one or more L<Alien> modules. It is designed to work
with L<Alien::Base> based aliens, but it should work with any L<Alien> which uses the same
essential API.
In the first example (from the command line), this class acts as a wrapper around the
compiler and linker that Perl is configured to use. It takes the normal compiler and
linker flags and adds the flags provided by the Aliens specified, and then executes the
command. It will print the command to the console so that you can see exactly what is
happening.
In the second example (from Makefile.PL non-dynamic), this class is used to generate the
appropriate L<ExtUtils::MakeMaker> (EUMM) arguments needed to C<WriteMakefile>.
In the third example (from Makefile.PL dynamic), we do a quick check to see if the simple
linker flag C<-lfoo> will work, if so we use that. If not, we use a wrapper around the
compiler and linker that will use the alien flags that are known at build time. The
problem that this form attempts to solve is that compiler and linker flags typically
need to be determined at I<configure> time, when a distribution is installed, meaning
if you are going to use an L<Alien> module then it needs to be a configure prerequisite,
even if the library is already installed and easily detected on the operating system.
The author of this module believes that the third (from Makefile.PL dynamic) form is
somewhat unnecessary. L<Alien> modules based on L<Alien::Base> have a few prerequisites,
but they are well maintained and reliable, so while there is a small cost in terms of extra
dependencies, the overall reliability thanks to reduced overall complexity.
=head1 CONSTRUCTOR
=head2 new
my $abw = Alien::Base::Wrapper->new(@aliens);
Instead of passing the aliens you want to use into this modules import you can create
a non-global instance of C<Alien::Base::Wrapper> using the OO interface.
=head1 FUNCTIONS
=head2 cc
% perl -MAlien::Base::Wrapper=Alien::Foo -e cc -- cflags
Invoke the C compiler with the appropriate flags from C<Alien::Foo> and what
is provided on the command line.
=head2 ld
% perl -MAlien::Base::Wrapper=Alien::Foo -e ld -- ldflags
Invoke the linker with the appropriate flags from C<Alien::Foo> and what
is provided on the command line.
=head2 mm_args
my %args = $abw->mm_args;
my %args = Alien::Base::Wrapper->mm_args;
Returns arguments that you can pass into C<WriteMakefile> to compile/link against
the specified Aliens. Note that this does not set C<CONFIGURE_REQUIRES>. You
probably want to use C<mm_args2> below instead for that reason.
=head2 mm_args2
my %args = $abw->mm_args2(%args);
my %args = Alien::Base::Wrapper->mm_args2(%args);
Returns arguments that you can pass into C<WriteMakefile> to compile/link against. It works
a little differently from C<mm_args> above in that you can pass in arguments. It also adds
the appropriate C<CONFIGURE_REQUIRES> for you so you do not have to do that explicitly.
=head2 mb_args
my %args = $abw->mb_args;
my %args = Alien::Base::Wrapper->mb_args;
Returns arguments that you can pass into the constructor to L<Module::Build>.
=head2 WriteMakefile
use Alien::Base::Wrapper qw( WriteMakefile );
WriteMakefile(%args, alien_requires => %aliens);
WriteMakefile(%args, alien_requires => @aliens);
This is a thin wrapper around C<WriteMakefile> from L<ExtUtils::MakeMaker>, which adds the
given aliens to the configure requirements and sets the appropriate compiler and linker
flags.
If the aliens are specified as a hash reference, then the keys are the module names and the
values are the versions. For a list it is just the name of the aliens.
For the list form you can specify a version by appending C<=version> to the name of the
Aliens, that is:
WriteMakefile(
alien_requires => [ 'Alien::libfoo=1.23', 'Alien::libbar=4.56' ],
);
The list form is recommended if the ordering of the aliens matter. The aliens are sorted in
the hash form to make it consistent, but it may not be the order that you want.
=head1 ENVIRONMENT
Alien::Base::Wrapper responds to these environment variables:
=over 4
=item ALIEN_BASE_WRAPPER_QUIET
If set to true, do not print the command before executing
=back
=head1 SEE ALSO
L<Alien::Base>, L<Alien::Base>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

2206
database/perl/vendor/lib/Alien/Build.pm vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,290 @@
package Alien::Build::CommandSequence;
use strict;
use warnings;
use 5.008004;
use Text::ParseWords qw( shellwords );
use Capture::Tiny qw( capture );
# ABSTRACT: Alien::Build command sequence
our $VERSION = '2.38'; # VERSION
sub new
{
my($class, @commands) = @_;
my $self = bless {
commands => \@commands,
}, $class;
$self;
}
sub apply_requirements
{
my($self, $meta, $phase) = @_;
my $intr = $meta->interpolator;
foreach my $command (@{ $self->{commands} })
{
next if ref $command eq 'CODE';
if(ref $command eq 'ARRAY')
{
foreach my $arg (@$command)
{
next if ref $arg eq 'CODE';
$meta->add_requires($phase, $intr->requires($arg))
}
}
else
{
$meta->add_requires($phase, $intr->requires($command));
}
}
$self;
}
my %built_in = (
cd => sub {
my(undef, $dir) = @_;
if(!defined $dir)
{
die "undef passed to cd";
}
elsif(-d $dir)
{
chdir($dir) || die "unable to cd $dir $!";
}
else
{
die "unable to cd $dir, does not exist";
}
},
);
sub _run_list
{
my($build, @cmd) = @_;
$build->log("+ @cmd");
return $built_in{$cmd[0]}->(@cmd) if $built_in{$cmd[0]};
system @cmd;
die "external command failed" if $?;
}
sub _run_string
{
my($build, $cmd) = @_;
$build->log("+ $cmd");
{
my $cmd = $cmd;
$cmd =~ s{\\}{\\\\}g if $^O eq 'MSWin32';
my @cmd = shellwords($cmd);
return $built_in{$cmd[0]}->(@cmd) if $built_in{$cmd[0]};
}
system $cmd;
die "external command failed" if $?;
}
sub _run_with_code
{
my($build, @cmd) = @_;
my $code = pop @cmd;
$build->log("+ @cmd");
my %args = ( command => \@cmd );
if($built_in{$cmd[0]})
{
my $error;
($args{out}, $args{err}, $error) = capture {
eval { $built_in{$cmd[0]}->(@cmd) };
$@;
};
$args{exit} = $error eq '' ? 0 : 2;
$args{builtin} = 1;
}
else
{
($args{out}, $args{err}, $args{exit}) = capture {
system @cmd; $?
};
}
$build->log("[output consumed by Alien::Build recipe]");
$code->($build, \%args);
}
sub _apply
{
my($where, $prop, $value) = @_;
if($where =~ /^(.*?)\.(.*?)$/)
{
_apply($2, $prop->{$1}, $value);
}
else
{
$prop->{$where} = $value;
}
}
sub execute
{
my($self, $build) = @_;
my $intr = $build->meta->interpolator;
my $prop = $build->_command_prop;
foreach my $command (@{ $self->{commands} })
{
if(ref($command) eq 'CODE')
{
$command->($build);
}
elsif(ref($command) eq 'ARRAY')
{
my($command, @args) = @$command;
my $code;
$code = pop @args if $args[-1] && ref($args[-1]) eq 'CODE';
if($args[-1] && ref($args[-1]) eq 'SCALAR')
{
my $dest = ${ pop @args };
if($dest =~ /^\%\{((?:alien|)\.(?:install|runtime|hook)\.[a-z\.0-9_]+)\}$/)
{
$dest = $1;
$dest =~ s/^\./alien./;
$code = sub {
my($build, $args) = @_;
die "external command failed" if $args->{exit};
my $out = $args->{out};
chomp $out;
_apply($dest, $prop, $out);
};
}
else
{
die "illegal destination: $dest";
}
}
($command, @args) = map { $intr->interpolate($_, $prop) } ($command, @args);
if($code)
{
_run_with_code $build, $command, @args, $code;
}
else
{
_run_list $build, $command, @args;
}
}
else
{
my $command = $intr->interpolate($command,$prop);
_run_string $build, $command;
}
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::CommandSequence - Alien::Build command sequence
=head1 VERSION
version 2.38
=head1 CONSTRUCTOR
=head2 new
my $seq = Alien::Build::CommandSequence->new(@commands);
=head1 METHODS
=head2 apply_requirements
$seq->apply_requirements($meta, $phase);
=head2 execute
$seq->execute($build);
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,361 @@
package Alien::Build::Interpolate;
use strict;
use warnings;
use 5.008004;
# ABSTRACT: Advanced interpolation engine for Alien builds
our $VERSION = '2.38'; # VERSION
sub new
{
my($class) = @_;
my $self = bless {
helper => {},
classes => {},
}, $class;
$self;
}
sub add_helper
{
my $self = shift;
my $name = shift;
my $code = shift;
if(defined $self->{helper}->{$name})
{
require Carp;
Carp::croak("duplicate implementation for interpolated key $name");
}
my $require;
if(ref $_[0] eq 'CODE')
{
$require = shift;
}
else
{
$require = [];
while(@_)
{
my $module = shift;
my $version = shift;
$version ||= 0;
push @$require, $module => $version;
}
}
$self->{helper}->{$name} = Alien::Build::Helper->new(
$name,
$code,
$require,
);
}
sub replace_helper
{
my $self = shift;
my($name) = @_;
delete $self->{helper}->{$name};
$self->add_helper(@_);
}
sub has_helper
{
my($self, $name) = @_;
return unless defined $self->{helper}->{$name};
my @require = $self->{helper}->{$name}->require;
while(@require)
{
my $module = shift @require;
my $version = shift @require;
{
my $pm = "$module.pm";
$pm =~ s/::/\//g;
require $pm;
$module->VERSION($version) if $version;
}
unless($self->{classes}->{$module})
{
if($module->can('alien_helper'))
{
my $helpers = $module->alien_helper;
foreach my $k (keys %$helpers)
{
$self->{helper}->{$k}->code($helpers->{$k});
}
}
$self->{classes}->{$module} = 1;
}
}
my $code = $self->{helper}->{$name}->code;
return unless defined $code;
if(ref($code) ne 'CODE')
{
my $perl = $code;
package Alien::Build::Interpolate::Helper;
$code = sub {
## no critic
my $value = eval $perl;
## use critic
die $@ if $@;
$value;
};
}
$code;
}
sub execute_helper
{
my($self, $name) = @_;
my $code = $self->has_helper($name);
die "no helper defined for $name" unless defined $code;
$code->();
}
sub _get_prop
{
my($name, $prop, $orig) = @_;
$name =~ s/^\./alien./;
if($name =~ /^(.*?)\.(.*)$/)
{
my($key,$rest) = ($1,$2);
return _get_prop($rest, $prop->{$key}, $orig);
}
elsif(exists $prop->{$name})
{
return $prop->{$name};
}
else
{
require Carp;
Carp::croak("No property $orig is defined");
}
}
sub interpolate
{
my($self, $string, $prop) = @_;
$prop ||= {};
$string =~ s{(?<!\%)\%\{([a-zA-Z_][a-zA-Z_0-9]+)\}}{$self->execute_helper($1)}eg;
$string =~ s{(?<!\%)\%\{([a-zA-Z_\.][a-zA-Z_0-9\.]+)\}}{_get_prop($1,$prop,$1)}eg;
$string =~ s/\%(?=\%)//g;
$string;
}
sub requires
{
my($self, $string) = @_;
map {
my $helper = $self->{helper}->{$_};
$helper ? $helper->require : ();
} $string =~ m{(?<!\%)\%\{([a-zA-Z_][a-zA-Z_0-9]+)\}}g;
}
sub clone
{
my($self) = @_;
require Storable;
my %helper;
foreach my $name (keys %{ $self->{helper} })
{
$helper{$name} = $self->{helper}->{$name}->clone;
}
my $new = bless {
helper => \%helper,
classes => Storable::dclone($self->{classes}),
}, ref $self;
}
package Alien::Build::Helper;
sub new
{
my($class, $name, $code, $require) = @_;
bless {
name => $name,
code => $code,
require => $require,
}, $class;
}
sub name { shift->{name} }
sub code
{
my($self, $code) = @_;
$self->{code} = $code if $code;
$self->{code};
}
sub require
{
my($self) = @_;
if(ref $self->{require} eq 'CODE')
{
$self->{require} = [ $self->{require}->($self) ];
}
@{ $self->{require} };
}
sub clone
{
my($self) = @_;
my $class = ref $self;
$class->new(
$self->name,
$self->code,
[ $self->require ],
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Interpolate - Advanced interpolation engine for Alien builds
=head1 VERSION
version 2.38
=head1 CONSTRUCTOR
=head2 new
my $intr = Alien::Build::Interpolate->new;
=head2 add_helper
$intr->add_helper($name => $code);
$intr->add_helper($name => $code, %requirements);
=head2 replace_helper
$intr->replace_helper($name => $code);
$intr->replace_helper($name => $code, %requirements);
=head2 has_helper
my $coderef = $intr->has_helper($name);
Used to discover if a helper exists with the given name.
Returns the code reference.
=head2 execute_helper
my $value = $intr->execute_helper($name);
=head2 interpolate
my $string = $intr->interpolate($template);
=head2 requires
my %requires = $intr->requires($template);
=head2 clone
my $intr2 = $intr->clone;
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,474 @@
package Alien::Build::Interpolate::Default;
use strict;
use warnings;
use 5.008004;
use base qw( Alien::Build::Interpolate );
use File::chdir;
use File::Which qw( which );
use Capture::Tiny qw( capture );
# ABSTRACT: Default interpolator for Alien::Build
our $VERSION = '2.38'; # VERSION
sub _config
{
$Config::Config{$_[0]};
}
sub new
{
my($class) = @_;
my $self = $class->SUPER::new(@_);
$self->add_helper( ar => sub { _config 'ar' }, 'Config' );
$self->add_helper( bison => undef, sub {
my $helper = shift;
if(which 'bison')
{
$helper->code(sub { 'bison' });
return ();
}
else
{
return 'Alien::bison' => '0.17';
}
});
$self->add_helper( bzip2 => undef, sub {
my $helper = shift;
if(which 'bzip2')
{
$helper->code( sub { 'bzip2' });
return ();
}
else
{
return 'Alien::Libbz2' => '0.04';
}
});
$self->add_helper( cc => sub { _config 'cc' }, 'Config' );
$self->add_helper( cmake => sub { 'cmake' }, sub {
if(which 'cmake')
{
return ();
}
else
{
return 'Alien::CMake' => '0.07';
}
});
$self->add_helper( cp => sub { _config 'cp' }, 'Config' );
$self->add_helper( devnull => sub { $^O eq 'MSWin32' ? 'NUL' : '/dev/null' });
$self->add_helper( flex => undef, sub {
my $helper = shift;
if(which 'flex')
{
$helper->code(sub { 'flex' });
return ();
}
else
{
return 'Alien::flex' => '0.08';
}
});
$self->add_helper( gmake => undef, 'Alien::gmake' => '0.11' );
$self->add_helper( install => sub { 'install' });
$self->add_helper( ld => sub { _config 'ld' }, 'Config' );
$self->add_helper( m4 => undef, 'Alien::m4' => '0.08' );
if($^O eq 'MSWin32')
{
# TL;DR: dmake is bad, and shouldn't be used to build anything but older
# versions of Windows Perl that don't support gmake.
my $perl_make = _config 'make';
my $my_make;
$self->add_helper( make => sub {
return $my_make if defined $my_make;
if( $perl_make ne 'dmake' && which $perl_make )
{
# assume if it is called nmake or gmake that it really is what it
# says it is.
if( $perl_make eq 'nmake' || $perl_make eq 'gmake' )
{
return $my_make = $perl_make;
}
my $out = capture { system $perl_make, '--version' };
if( $out =~ /GNU make/i || $out =~ /Microsoft \(R\) Program Maintenance/ )
{
return $my_make = $perl_make;
}
}
# if we see something that looks like it might be gmake, use that.
foreach my $try (qw( gmake mingw32-make ))
{
return $my_make = $try if which $try;
}
if( which 'make' )
{
my $out = capture { system 'make', '--version' };
if( $out =~ /GNU make/i || $out =~ /Microsoft \(R\) Program Maintenance/ )
{
return $my_make = 'make';
}
}
# if we see something that looks like it might be nmake, use that.
foreach my $try (qw( nmake ))
{
return $my_make = $try if which $try;
}
$my_make = $perl_make;
});
}
else
{
$self->add_helper( make => sub { _config 'make' }, 'Config' );
}
$self->add_helper( mkdir_deep => sub { $^O eq 'MSWin32' ? 'md' : 'mkdir -p'}, 'Alien::Build' => '1.04' );
$self->add_helper( make_path => sub { $^O eq 'MSWin32' ? 'md' : 'mkdir -p'}, 'Alien::Build' => '1.05' );
$self->add_helper( nasm => undef, sub {
my $helper = shift;
if(which 'nasm')
{
$helper->code(sub { 'nasm' });
return ();
}
else
{
return 'Alien::nasm' => '0.11';
}
});
$self->add_helper( patch => undef, sub {
my $helper = shift;
if(which 'patch')
{
if($^O eq 'MSWin32')
{
$helper->code(sub { 'patch --binary' });
}
else
{
$helper->code(sub { 'patch' });
}
return ();
}
else
{
return 'Alien::patch' => '0.09';
}
});
$self->add_helper( perl => sub {
my $perl = Devel::FindPerl::find_perl_interpreter();
$perl =~ s{\\}{/}g if $^O eq 'MSWin32';
$perl;
}, 'Devel::FindPerl' );
$self->add_helper( pkgconf => undef, 'Alien::pkgconf' => 0.06 );
$self->add_helper( cwd => sub {
my $cwd = "$CWD";
$cwd =~ s{\\}{/}g if $^O eq 'MSWin32';
$cwd;
} );
$self->add_helper( sh => sub { 'sh' }, 'Alien::MSYS' => '0.07' );
$self->add_helper( rm => sub { _config 'rm' }, 'Config' );
$self->add_helper( xz => undef, sub {
my $helper = shift;
if(which 'xz')
{
$helper->code(sub { 'xz' });
return ();
}
else
{
return 'Alien::xz' => '0.02';
}
});
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Interpolate::Default - Default interpolator for Alien::Build
=head1 VERSION
version 2.38
=head1 CONSTRUCTOR
=head2 new
my $intr = Alien::Build::Interpolate::Default->new;
=head1 HELPERS
=head2 ar
%{ar}
The ar command.
=head2 bison
%{bison}
Requires: L<Alien::bison> 0.17 if not already in C<PATH>.
=head2 bzip2
%{bzip2}
Requires: L<Alien::Libbz2> 0.04 if not already in C<PATH>.
=head2 cc
%{cc}
The C Compiler used to build Perl
=head2 cmake
%{cmake}
Requires: L<Alien::CMake> 0.07 if cmake is not already in C<PATH>.
Deprecated: Use the L<Alien::Build::Plugin::Build::CMake> plugin instead (which will replace
this helper with one that works with L<Alien::cmake3> that works better).
=head2 cp
%{cp}
The copy command.
=head2 devnull
%{devnull}
The null device, if available. On Unix style operating systems this will be C</dev/null> on Windows it is C<NUL>.
=head2 flex
%{flex}
Requires: L<Alien::flex> 0.08 if not already in C<PATH>.
=head2 gmake
%{gmake}
Requires: L<Alien::gmake> 0.11
Deprecated: use L<Alien::Build::Plugin::Build::Make> instead.
=head2 install
%{install}
The Unix C<install> command. Not normally available on Windows.
=head2 ld
%{ld}
The linker used to build Perl
=head2 m4
%{m4}
Requires: L<Alien::m4> 0.08
L<Alien::m4> should pull in a version of C<m4> that will work with Autotools.
=head2 make
%{make}
Make. On Unix this will be the same make used by Perl. On Windows this will be
C<gmake> or C<nmake> if those are available, and only C<dmake> if the first two
are not available.
=head2 make_path
%{make_path}
Make directory, including all parent directories as needed. This is usually C<mkdir -p>
on Unix and simply C<md> on windows.
=head2 nasm
%{nasm}
Requires: L<Alien::nasm> 0.11 if not already in the C<PATH>.
=head2 patch
%{patch}
Requires: L<Alien::patch> 0.09 if not already in the C<PATH>.
On Windows this will normally render C<patch --binary>, which makes patch work like it does on Unix.
=head2 perl
%{perl}
Requires: L<Devel::FindPerl>
=head2 pkgconf
%{pkgconf}
Requires: L<Alien::pkgconf> 0.06.
=head2 cwd
%{cwd}
=head2 sh
%{sh}
Unix style command interpreter (/bin/sh).
Deprecated: use the L<Alien::Build::Plugin::Build::MSYS> plugin instead.
=head2 rm
%{rm}
The remove command
=head2 xz
%{xz}
Requires: L<Alien::xz> 0.02 if not already in the C<PATH>.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,211 @@
package Alien::Build::Log;
use strict;
use warnings;
use 5.008004;
use Carp ();
# ABSTRACT: Alien::Build logging
our $VERSION = '2.38'; # VERSION
my $log_class;
my $self;
sub new
{
my($class) = @_;
Carp::croak("Cannot instantiate base class") if $class eq 'Alien::Build::Log';
return bless {}, $class;
}
sub default
{
$self || do {
my $class = $log_class || $ENV{ALIEN_BUILD_LOG} || 'Alien::Build::Log::Default';
unless(eval { $class->can('new') })
{
my $pm = "$class.pm";
$pm =~ s/::/\//g;
require $pm;
}
$class->new;
}
}
sub set_log_class
{
my(undef, $class) = @_;
return if defined $class && ($class eq ($log_class || ''));
$log_class = $class;
undef $self;
}
sub log
{
Carp::croak("AB Log base class");
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Log - Alien::Build logging
=head1 VERSION
version 2.38
=head1 SYNOPSIS
Create your custom log class:
package Alien::Build::Log::MyLog;
use base qw( Alien::Build::Log );
sub log
{
my(undef, %opt) = @_;
my($package, $filename, $line) = @{ $opt{caller} };
my $message = $opt{message};
...;
}
override log class:
% env ALIEN_BUILD_LOG=Alien::Build::Log::MyLog cpanm Alien::libfoo
=head1 DESCRIPTION
=head1 CONSTRUCTORS
=head2 new
my $log = Alien::Build::Log->new;
Create an instance of the log class.
=head2 default
my $log = Alien::Build::Log->default;
Return singleton instance of log class used by L<Alien::Build>.
=head1 METHODS
=head2 set_log_class
Alien::Build::Log->set_log_class($class);
Set the default log class used by L<Alien::Build>. This method will also reset the
default instance used by L<Alien::Build>. If not specified, L<Alien::Build::Log::Default>
will be used.
=head2 log
$log->log(%options);
Overridable method which does the actual work of the log class. Options:
=over 4
=item caller
Array references containing the package, file and line number of where the
log was called.
=item message
The message to log.
=back
=head1 ENVIRONMENT
=over 4
=item ALIEN_BUILD_LOG
The default log class used by L<Alien::Build>.
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,149 @@
package Alien::Build::Log::Abbreviate;
use strict;
use warnings;
use 5.008004;
use Term::ANSIColor ();
use Path::Tiny qw( path );
use File::chdir;
use base qw( Alien::Build::Log );
# ABSTRACT: Log class for Alien::Build which is less verbose
our $VERSION = '2.38'; # VERSION
sub _colored
{
my($code, @out) = @_;
-t STDOUT ? Term::ANSIColor::_colored($code, @out) : @out;
}
my $root = path("$CWD");
sub log
{
my(undef, %args) = @_;
my($message) = $args{message};
my ($package, $filename, $line) = @{ $args{caller} };
my $source = $package;
$source =~ s/^Alien::Build::Auto::[^:]+::Alienfile/alienfile/;
my $expected = $package;
$expected .= '.pm' unless $package eq 'alienfile';
$expected =~ s/::/\//g;
if($filename !~ /\Q$expected\E$/)
{
$source = path($filename)->relative($root);
}
else
{
$source =~ s/^Alien::Build::Plugin/ABP/;
$source =~ s/^Alien::Build/AB/;
}
print _colored([ "bold on_black" ], '[');
print _colored([ "bright_green on_black" ], $source);
print _colored([ "on_black" ], ' ');
print _colored([ "bright_yellow on_black" ], $line);
print _colored([ "bold on_black" ], ']');
print _colored([ "white on_black" ], ' ', $message);
print "\n";
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Log::Abbreviate - Log class for Alien::Build which is less verbose
=head1 VERSION
version 2.38
=head1 SYNOPSIS
=head1 DESCRIPTION
=head1 METHODS
=head2 log
$log->log(%opts);
Send single log line to stdout.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,133 @@
package Alien::Build::Log::Default;
use strict;
use warnings;
use 5.008004;
use base qw( Alien::Build::Log );
# ABSTRACT: Default Alien::Build log class
our $VERSION = '2.38'; # VERSION
sub log
{
my(undef, %args) = @_;
my($message) = $args{message};
my ($package, $filename, $line) = @{ $args{caller} };
print "$package> $message\n";
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Log::Default - Default Alien::Build log class
=head1 VERSION
version 2.38
=head1 SYNOPSIS
Alien::Build->log("message1");
$build->log("message2");
=head1 DESCRIPTION
This is the default log class for L<Alien::Build>. It does
the sensible thing of sending the message to stdout, along
with the class that made the log call. For more details
about logging with L<Alien::Build>, see L<Alien::Build::Log>.
=head1 METHODS
=head2 log
$log->log(%opts);
Send single log line to stdout.
=head1 SEE ALSO
=over 4
=item L<Alien::Build>
=item L<Alien::Build::Log>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,651 @@
package Alien::Build::MM;
use strict;
use warnings;
use 5.008004;
use Alien::Build;
use Path::Tiny ();
use Capture::Tiny qw( capture );
use Carp ();
# ABSTRACT: Alien::Build installer code for ExtUtils::MakeMaker
our $VERSION = '2.38'; # VERSION
sub new
{
my($class, %prop) = @_;
my $self = bless {}, $class;
my %meta = map { $_ => $prop{$_} } grep /^my_/, keys %prop;
my $build = $self->{build} =
Alien::Build->load('alienfile',
root => "_alien",
(-d 'patch' ? (patch => 'patch') : ()),
meta_prop => \%meta,
)
;
if(%meta)
{
$build->meta->add_requires(configure => 'Alien::Build::MM' => '1.20');
$build->meta->add_requires(configure => 'Alien::Build' => '1.20');
}
if(defined $prop{alienfile_meta})
{
$self->{alienfile_meta} = $prop{alienfile_meta};
}
else
{
$self->{alienfile_meta} = 1;
}
$self->{clean_install} = $prop{clean_install};
$self->build->load_requires('configure');
$self->build->root;
$self->build->checkpoint;
$self;
}
sub build
{
shift->{build};
}
sub alienfile_meta
{
shift->{alienfile_meta};
}
sub clean_install
{
shift->{clean_install};
}
sub mm_args
{
my($self, %args) = @_;
if($args{DISTNAME})
{
$self->build->set_stage(Path::Tiny->new("blib/lib/auto/share/dist/$args{DISTNAME}")->absolute->stringify);
$self->build->install_prop->{mm}->{distname} = $args{DISTNAME};
my $module = $args{DISTNAME};
$module =~ s/-/::/g;
# See if there is an existing version installed, without pulling it into this process
my($old_prefix, $err, $ret) = capture { system $^X, "-M$module", -e => "print $module->dist_dir"; $? };
if($ret == 0)
{
chomp $old_prefix;
my $file = Path::Tiny->new($old_prefix, qw( _alien alien.json ));
if(-r $file)
{
my $old_runtime = eval {
require JSON::PP;
JSON::PP::decode_json($file->slurp);
};
unless($@)
{
$self->build->install_prop->{old}->{runtime} = $old_runtime;
$self->build->install_prop->{old}->{prefix} = $old_prefix;
}
}
}
}
else
{
Carp::croak "DISTNAME is required";
}
my $ab_version = '0.25';
if($self->clean_install)
{
$ab_version = '1.74';
}
$args{CONFIGURE_REQUIRES} = Alien::Build::_merge(
'Alien::Build::MM' => $ab_version,
%{ $args{CONFIGURE_REQUIRES} || {} },
%{ $self->build->requires('configure') || {} },
);
if($self->build->install_type eq 'system')
{
$args{BUILD_REQUIRES} = Alien::Build::_merge(
'Alien::Build::MM' => $ab_version,
%{ $args{BUILD_REQUIRES} || {} },
%{ $self->build->requires('system') || {} },
);
}
elsif($self->build->install_type eq 'share')
{
$args{BUILD_REQUIRES} = Alien::Build::_merge(
'Alien::Build::MM' => $ab_version,
%{ $args{BUILD_REQUIRES} || {} },
%{ $self->build->requires('share') || {} },
);
}
else
{
die "unknown install type: @{[ $self->build->install_type ]}"
}
$args{PREREQ_PM} = Alien::Build::_merge(
'Alien::Build' => $ab_version,
%{ $args{PREREQ_PM} || {} },
);
#$args{META_MERGE}->{'meta-spec'}->{version} = 2;
$args{META_MERGE}->{dynamic_config} = 1;
if($self->alienfile_meta)
{
$args{META_MERGE}->{x_alienfile} = {
generated_by => "@{[ __PACKAGE__ ]} version @{[ __PACKAGE__->VERSION || 'dev' ]}",
requires => {
map {
my %reqs = %{ $self->build->requires($_) };
$reqs{$_} = "$reqs{$_}" for keys %reqs;
$_ => \%reqs;
} qw( share system )
},
};
}
$self->build->checkpoint;
%args;
}
sub mm_postamble
{
# NOTE: older versions of the Alien::Build::MM documentation
# didn't include $mm and @rest args, so anything that this
# method uses them for has to be optional.
# (as of this writing they are unused, but are being added
# to match the way mm_install works).
my($self, $mm, @rest) = @_;
my $postamble = '';
# remove the _alien directory on a make realclean:
$postamble .= "realclean :: alien_realclean\n" .
"\n" .
"alien_realclean:\n" .
"\t\$(RM_RF) _alien\n\n";
# remove the _alien directory on a make clean:
$postamble .= "clean :: alien_clean\n" .
"\n" .
"alien_clean:\n" .
"\t\$(RM_RF) _alien\n\n";
my $dirs = $self->build->meta_prop->{arch}
? '$(INSTALLARCHLIB) $(INSTALLSITEARCH) $(INSTALLVENDORARCH)'
: '$(INSTALLPRIVLIB) $(INSTALLSITELIB) $(INSTALLVENDORLIB)'
;
# set prefix
$postamble .= "alien_prefix : _alien/mm/prefix\n\n" .
"_alien/mm/prefix :\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e prefix \$(INSTALLDIRS) $dirs\n\n";
# set verson
$postamble .= "alien_version : _alien/mm/version\n\n" .
"_alien/mm/version : _alien/mm/prefix\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e version \$(VERSION)\n\n";
# download
$postamble .= "alien_download : _alien/mm/download\n\n" .
"_alien/mm/download : _alien/mm/prefix _alien/mm/version\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e download\n\n";
# build
$postamble .= "alien_build : _alien/mm/build\n\n" .
"_alien/mm/build : _alien/mm/download\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e build\n\n";
# append to all
$postamble .= "pure_all :: _alien/mm/build\n\n";
$postamble .= "subdirs-test_dynamic subdirs-test_static subdirs-test :: alien_test\n\n";
$postamble .= "alien_test :\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e test\n\n";
# prop
$postamble .= "alien_prop :\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop\n\n";
$postamble .= "alien_prop_meta :\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop meta\n\n";
$postamble .= "alien_prop_install :\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop install\n\n";
$postamble .= "alien_prop_runtime :\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop runtime\n\n";
# install
$postamble .= "alien_clean_install : _alien/mm/prefix\n" .
"\t\$(FULLPERL) -MAlien::Build::MM=cmd -e clean_install\n\n";
$postamble;
}
sub mm_install
{
# NOTE: older versions of the Alien::Build::MM documentation
# didn't include this method, so anything that this method
# does has to be optional
my($self, $mm, @rest) = @_;
my $section = do {
package
MY;
$mm->SUPER::install(@rest);
};
return
".NOTPARALLEL : \n\n"
. ".NO_PARALLEL : \n\n"
. "install :: alien_clean_install\n\n"
. $section;
}
sub import
{
my(undef, @args) = @_;
foreach my $arg (@args)
{
if($arg eq 'cmd')
{
package main;
*_args = sub
{
my $build = Alien::Build->resume('alienfile', '_alien');
$build->load_requires('configure');
$build->load_requires($build->install_type);
($build, @ARGV)
};
*_touch = sub {
my($name) = @_;
my $path = Path::Tiny->new("_alien/mm/$name");
$path->parent->mkpath;
$path->touch;
};
*prefix = sub
{
my($build, $type, $perl, $site, $vendor) = _args();
my $distname = $build->install_prop->{mm}->{distname};
my $prefix = $type eq 'perl'
? $perl
: $type eq 'site'
? $site
: $type eq 'vendor'
? $vendor
: die "unknown INSTALLDIRS ($type)";
$prefix = Path::Tiny->new($prefix)->child("auto/share/dist/$distname")->absolute->stringify;
$build->log("prefix $prefix");
$build->set_prefix($prefix);
$build->checkpoint;
_touch('prefix');
};
*version = sub
{
my($build, $version) = _args();
$build->runtime_prop->{perl_module_version} = $version;
$build->checkpoint;
_touch('version');
};
*download = sub
{
my($build) = _args();
$build->download;
$build->checkpoint;
_touch('download');
};
*build = sub
{
my($build) = _args();
$build->build;
my $distname = $build->install_prop->{mm}->{distname};
if($build->meta_prop->{arch})
{
my $archdir = Path::Tiny->new("blib/arch/auto/@{[ join '/', split /-/, $distname ]}");
$archdir->mkpath;
my $archfile = $archdir->child($archdir->basename . '.txt');
$archfile->spew('Alien based distribution with architecture specific file in share');
}
my $cflags = $build->runtime_prop->{cflags};
my $libs = $build->runtime_prop->{libs};
if(($cflags && $cflags !~ /^\s*$/)
|| ($libs && $libs !~ /^\s*$/))
{
my $mod = join '::', split /-/, $distname;
my $install_files_pm = Path::Tiny->new("blib/lib/@{[ join '/', split /-/, $distname ]}/Install/Files.pm");
$install_files_pm->parent->mkpath;
$install_files_pm->spew(
"package ${mod}::Install::Files;\n",
"use strict;\n",
"use warnings;\n",
"require ${mod};\n",
"sub Inline { shift; ${mod}->Inline(\@_) }\n",
"1;\n",
"\n",
"=begin Pod::Coverage\n",
"\n",
" Inline\n",
"\n",
"=cut\n",
);
}
$build->checkpoint;
_touch('build');
};
*test = sub
{
my($build) = _args();
$build->test;
$build->checkpoint;
};
*clean_install = sub
{
my($build) = _args();
$build->clean_install;
$build->checkpoint;
};
*dumpprop = sub
{
my($build, $type) = _args();
my %h = (
meta => $build->meta_prop,
install => $build->install_prop,
runtime => $build->runtime_prop,
);
require Alien::Build::Util;
print Alien::Build::Util::_dump($type ? $h{$type} : \%h);
}
}
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::MM - Alien::Build installer code for ExtUtils::MakeMaker
=head1 VERSION
version 2.38
=head1 SYNOPSIS
In your C<Makefile.PL>:
use ExtUtils::MakeMaker;
use Alien::Build::MM;
my $abmm = Alien::Build::MM->new;
WriteMakefile($abmm->mm_args(
ABSTRACT => 'Discover or download and install libfoo',
DISTNAME => 'Alien-Libfoo',
NAME => 'Alien::Libfoo',
VERSION_FROM => 'lib/Alien/Libfoo.pm',
...
));
sub MY::postamble {
$abmm->mm_postamble(@_);
}
sub MY::install {
$abmm->mm_install(@_);
}
In your C<lib/Alien/Libfoo.pm>:
package Alien::Libfoo;
use base qw( Alien::Base );
1;
In your alienfile (needs to be named C<alienfile> and should be in the root of your dist):
use alienfile;
plugin 'PkgConfig' => 'libfoo';
share {
start_url 'http://libfoo.org';
...
};
=head1 DESCRIPTION
This class allows you to use Alien::Build and Alien::Base with L<ExtUtils::MakeMaker>.
It load the L<alienfile> recipe in the root of your L<Alien> dist, updates the prereqs
passed into C<WriteMakefile> if any are specified by your L<alienfile> or its plugins,
and adds a postamble to the C<Makefile> that will download/build/test the alienized
package as appropriate.
The L<alienfile> must be named C<alienfile>.
If you are using L<Dist::Zilla> to author your L<Alien> dist, you should consider using
the L<Dist::Zilla::Plugin::AlienBuild> plugin.
I personally don't recommend it, but if you want to use L<Module::Build> instead, you
can use L<Alien::Build::MB>.
=head1 CONSTRUCTOR
=head2 new
my $abmm = Alien::Build::MM->new;
Create a new instance of L<Alien::Build::MM>.
=head1 PROPERTIES
=head2 build
my $build = $abmm->build;
The L<Alien::Build> instance.
=head2 alienfile_meta
my $bool = $abmm->alienfile_meta
Set to a false value, in order to turn off the x_alienfile meta
=head2 clean_install
my $bool = $abmm->clean_install;
Set to a true value, in order to clean the share directory prior to
installing. If you use this you have to make sure that you install
the install handler in your C<Makefile.PL>:
$abmm = Alien::Build::MM->new(
clean_install => 1,
);
...
sub MY::install {
$abmm->mm_install(@_);
}
=head1 METHODS
=head2 mm_args
my %args = $abmm->mm_args(%args);
Adjust the arguments passed into C<WriteMakefile> as needed by L<Alien::Build>.
=head2 mm_postamble
my $postamble $abmm->mm_postamble;
my $postamble $abmm->mm_postamble($mm);
Returns the postamble for the C<Makefile> needed for L<Alien::Build>.
This adds the following C<make> targets which are normally called when
you run C<make all>, but can be run individually if needed for debugging.
=over 4
=item alien_prefix
Determines the final install prefix (C<%{.install.prefix}>).
=item alien_version
Determine the perl_module_version (C<%{.runtime.perl_module_version}>)
=item alien_download
Downloads the source from the internet. Does nothing for a system install.
=item alien_build
Build from source (if a share install). Gather configuration (for either
system or share install).
=item alien_prop, alien_prop_meta, alien_prop_install, alien_prop_runtime
Prints the meta, install and runtime properties for the Alien.
=item alien_realclean, alien_clean
Removes the alien specific files. These targets are executed when you call
the C<realclean> and C<clean> targets respectively.
=item alien_clean_install
Cleans out the Alien's share directory. Caution should be used in invoking
this target directly, as if you do not understand what you are doing you
are likely to break your already installed Alien.
=back
=head2 mm_install
sub MY::install {
$abmm->mm_install(@_);
}
B<EXPERIMENTAL>
Adds an install rule to clean the final install dist directory prior to installing.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base>, L<Alien>, L<Dist::Zilla::Plugin::AlienBuild>, L<Alien::Build::MB>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,133 @@
# PODNAME: Alien::Build::Manual::Alien
# ABSTRACT: General alien author documentation
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Manual::Alien - General alien author documentation
=head1 VERSION
version 2.38
=head1 SYNOPSIS
perldoc Alien::Build::Manual::Alien
=head1 DESCRIPTION
The goal of the L<Alien> namespace is to provide non-CPAN dependencies (so called "Alien" dependencies) for
CPAN modules. The history and intent of this idea is documented in the documentation-only L<Alien> module.
The C<Alien-Build> distribution provides a framework for building aliens. The intent is to fix bugs and
enhance the interface of a number of common tools so that all aliens may benefit. The distribution is broken
up into these parts:
=over 4
=item The Alien Installer (configure / build-time)
L<Alien::Build> and L<alienfile> are used to detect and install aliens. They are further documented in
L<Alien::Build::Manual::AlienAuthor>.
=item The Alien Runtime (runtime)
L<Alien::Base> is the base class for aliens in the C<Alien-Build> system. Its use by Alien consumers
is documented in L<Alien::Build::Manual::AlienUser>.
=item The Plugin system (configure / build-time)
Because many packages are implemented using different tools, the detection, build and install logic
for a particular L<Alien> can vary a lot. As such, much of L<Alien::Build> is implemented as a
series of plugins that inherit from L<Alien::Build::Plugin>. An overview of building your own
plugins is documented in L<Alien::Build::Manual::PluginAuthor>.
=back
Additional useful documentation may be found here:
=over 4
=item FAQ
L<Alien::Build::Manual::FAQ>
=item Contributing
L<Alien::Build::Manual::Contributing>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,736 @@
# PODNAME: Alien::Build::Manual::AlienAuthor
# ABSTRACT: Alien author documentation
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Manual::AlienAuthor - Alien author documentation
=head1 VERSION
version 2.38
=head1 SYNOPSIS
perldoc Alien::Build::Manual::AlienAuthor
=head1 DESCRIPTION
B<Note>: Please read the entire document before you get started in
writing your own L<alienfile>. The section on dynamic vs. static
libraries will likely save you a lot of grief if you read it now!
This document is intended to teach L<Alien> authors how to build their
own L<Alien> distribution using L<Alien::Build> and L<Alien::Base>.
Such an L<Alien> distribution consists of three essential parts:
=over 4
=item An L<alienfile>
This is a recipe for how to 1) detect an already installed version of
the library or tool you are alienizing 2) download and build the library
or tool that you are alienizing and 3) gather the configuration settings
necessary for the use of that library or tool.
=item An installer C<Makefile.PL> or C<Build.PL> or a C<dist.ini> if you are using L<Dist::Zilla>
This is a thin layer between your L<alienfile> recipe, and the Perl
installer (either L<ExtUtils::MakeMaker> or L<Module::Build>.
=item A Perl class (.pm file) that inherits from L<Alien::Base>
For most L<Alien>s this does not need to be customized at all, since
L<Alien::Base> usually does what you need.
=back
For example if you were alienizing a library called libfoo, you might
have these files:
Alien-Libfoo-1.00/Makefile.PL
Alien-Libfoo-1.00/alienfile
Alien-Libfoo-1.00/lib/Alien/Libfoo.pm
This document will focus mainly on instructing you how to construct an
L<alienfile>, but we will also briefly cover making a simple
C<Makefile.PL> or C<dist.ini> to go along with it. We will also touch
on when you might want to extend your subclass to add non-standard
functionality.
=head2 Using commands
Most software libraries and tools will come with instructions for how to
install them in the form of commands that you are intended to type into
a shell manually. The easiest way to automate those instructions is to
just put the commands in your L<alienfile>. For example, lets suppose
that libfoo is built using autoconf and provides a C<pkg-config> C<.pc>
file.
We will also later discuss plugins. For common build systems like
autoconf or CMake, it is usually better to use the appropriate plugin
because they will handle corner cases better than a simple set of
commands. We're going to take a look at commands first because it's
easier to understand the different phases with commands.
(Aside, autoconf is a series of tools and macros used to configure
(usually) a C or C++ library or tool by generating any number of
Makefiles. It is the C equivalent to L<ExtUtils::MakeMaker>, if you
will. Basically, if your library or tool instructions start with
'./configure' it is most likely an autoconf based library or tool).
(Aside2, C<pkg-config> is a standard-ish way to provide the compiler and
linker flags needed for compiling and linking against the library. If
your tool installs a C<.pc> file, usually in C<$PREFIX/lib/pkgconfig>
then, your tool uses C<pkg-config>).
Here is the L<alienfile> that you might have:
use alienfile;
probe [ 'pkg-config --exists libfoo' ];
share {
start_url 'http://www.libfoo.org/src/libfoo-1.00.tar.gz';
download [ 'wget %{.meta.start_url}' ];
extract [ 'tar zxf %{.install.download}' ];
build [
[ './configure --prefix=%{.install.prefix} --disable-shared' ],
[ '%{make}' ],
[ '%{make} install' ],
];
};
gather [
[ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
[ 'pkg-config --cflags libfoo', \'%{.runtime.cflags}' ],
[ 'pkg-config --libs libfoo', \'%{.runtime.libs}' ],
];
There is a lot going on here, so lets decode it a little bit. An
L<alienfile> is just some Perl with some alien specific sugar. The
first line
use alienfile;
imports the sugar into the L<alienfile>. It also is a flag for the
reader to see that this is an L<alienfile> and not some other kind of
Perl script.
The second line is the probe directive:
probe [ 'pkg-config --exists libfoo' ];
is used to see if the library is already installed on the target system.
If C<pkg-config> is in the path, and if libfoo is installed, this should
exit with a success (0) and tell L<Alien::Build> to use the system
library. If either C<pkg-config> in the PATH, or if libfoo is not
installed, then it will exist with non-success (!= 0) and tells
L<Alien::Build> to download and build from source.
You can provide as many probe directives as you want. This is useful if
there are different ways to probe for the system. L<Alien::Build> will
stop on the first successfully found system library found. Say our
library libfoo comes with a C<.pc> file for use with C<pkg-config> and
also provides a C<foo-config> program to find the same values. You
could then specify this in your L<alienfile>
probe [ 'pkg-config --exists libfoo' ];
probe [ 'foo-config --version' ];
Other directives can be specified multiple times if there are different
methods that can be tried for the various steps.
Sometimes it is easier to probe for a library from Perl rather than with
a command. For that you can use a code reference. For example, another
way to call C<pkg-config> would be from Perl:
probe sub {
my($build) = @_; # $build is the Alien::Build instance.
system 'pkg-config --exists libfoo';
$? == 0 ? 'system' : 'share';
};
The Perl code should return 'system' if the library is installed, and
'share' if not. (Other directives should return a true value on
success, and a false value). You can also throw an exception with
C<die> to indicate a failure.
The next part of the L<alienfile> is the C<share> block, which is used
to group the directives which are used to download and install the
library or tool in the event that it is not already installed.
share {
start_url 'http://www.libfoo.org/src/libfoo-1.00.tar.gz';
download [ 'wget %{.meta.start_url}' ];
extract [ 'tar zxf %{.install.download}' ];
build [
[ './configure --prefix=%{.install.prefix} --disable-shared' ],
[ '%{make}' ],
[ '%{make} install' ],
];
};
The start_url specifies where to find the package that you are alienizing.
It should be either a tarball (or zip file, or what have you) or an
HTML index. The download directive as you might imagine specifies how
to download the library or tool. The extract directive specifies how
to extract the archive once it is downloaded. In the extract step, you
can use the variable C<%{.install.download}> as a placeholder for the archive
that was downloaded in the download step. This is also accessible if
you use a code reference from the L<Alien::Build> instance:
share {
...
requires 'Archive::Extract';
extract sub {
my($build) = @_;
my $tarball = $build->install_prop->{download};
my $ae = Archive::Extract->new( archive => $tarball );
$ae->extract;
1;
}
...
};
The build directive specifies how to build the library or tool once it
has been downloaded and extracted. Note the special variable
C<%{.install.prefix}> is the location where the library should be
installed. C<%{make}> is a helper which will be replaced by the
appropriate C<make>, which may be called something different on some
platforms (on Windows for example, it frequently may be called C<nmake>
or C<dmake>).
The final part of the L<alienfile> has a gather directive which
specifies how to get the details on how to compile and link against the
library. For this, once again we use the C<pkg-config> command:
gather [
[ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
[ 'pkg-config --cflags libfoo', \'%{.runtime.cflags}' ],
[ 'pkg-config --libs libfoo', \'%{.runtime.libs}' ],
];
The scalar reference as the final item in the command list tells
L<Alien::Build> that the output from the command should be stored in the
given variable. The runtime variables are the ones that will be
available to C<Alien::Libfoo> once it is installed. (Install
properties, which are the ones that we have seen up till now are thrown
away once the L<Alien> distribution is installed.
You can also provide a C<sys> block for directives that should be used
when a system install is detected. Normally you only need to do this if
the gather step is different between share and system installs. For
example, the above is equivalent to:
build {
...
gather [
[ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
[ 'pkg-config --cflags libfoo', \'%{.runtime.cflags}' ],
[ 'pkg-config --libs libfoo', \'%{.runtime.libs}' ],
];
};
sys {
gather [
[ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
[ 'pkg-config --cflags libfoo', \'%{.runtime.cflags}' ],
[ 'pkg-config --libs libfoo', \'%{.runtime.libs}' ],
];
};
(Aside3, the reason it is called C<sys> and not C<system> is so that it
does not conflict with the built in C<system> function)!
=head2 Using plugins
The first example is a good way of showing the full manual path that you
can choose, but there is a lot of repetition, if you are doing many
L<Alien>s that use autoconf and C<pkg-config> (which are quite common.
L<alienfile> allows you to use plugins. See L<Alien::Build::Plugin> for
a list of some of the plugin categories.
For now, I will just show you how to write the L<alienfile> for libfoo
above using L<Alien::Build::Plugin::Build::Autoconf>,
L<Alien::Build::Plugin::PkgConfig::Negotiate>,
L<Alien::Build::Plugin::Download::Negotiate>, and
L<Alien::Build::Plugin::Extract::Negotiate>
use alienfile;
plugin 'PkgConfig' => (
pkg_name => 'libfoo',
);
share {
start_url 'http://www.libfoo.org/src';
plugin 'Download' => (
filter => qr/^libfoo-[0-9\.]+\.tar\.gz$/,
version => qr/^libfoo-([0-9\.]+)\.tar\.gz$/,
);
plugin 'Extract' => 'tar.gz';
plugin 'Build::Autoconf';
build [
'%{configure} --disable-shared',
'%{make}',
'%{make} install',
];
};
The first plugin that we use is the C<pkg-config> negotiation plugin. A
negotiation plugin is one which doesn't do the actual work but selects
the best one from a set of plugins depending on your platform and
environment. (In the case of
L<Alien::Build::Plugin::PkgConfig::Negotiate>, it may choose to use
command line tools, a pure Perl implementation (L<PkgConfig>), or
libpkgconf, depending on what is available). When using negotiation
plugins you may omit the C<::Negotiate> suffix. So as you can see using
the plugin here is an advantage because it is more reliable than just
specifying a command which may not be installed!
Next we use the download negotiation plugin. This is also better than
the version above, because again, C<wget> my not be installed on the
target system. Also you can specify a URL which will be scanned for
links, and use the most recent version.
We use the Extract negotiation plugin to use either command line tools,
or Perl libraries to extract from the archive once it is downloaded.
Finally we use the Autoconf plugin
(L<Alien::Build::Plugin::Build::Autoconf>). This is a lot more
sophisticated and reliable than in the previous example, for a number of
reasons. This version will even work on Windows assuming the library or
tool you are alienizing supports that platform!
Strictly speaking the build directive is not necessary, because the
autoconf plugin provides a default which is reasonable. The only reason
that you would want to include it is if you need to provide additional
flags to the configure step.
share {
...
build [
'%{configure} --enable-bar --enable-baz --disable-shared',
'%{make}',
'%{make} install',
];
};
=head2 A note about dynamic vs. static libraries
If you are using your L<Alien> to build an XS module, it is important
that you use static libraries if possible. If you have a package that
refuses to build a static library, then you can use L<Alien::Role::Dino>.
Actually let me back up a minute. For a C<share> install it is best
to use static libraries to build your XS extension. This is because
if your L<Alien> is ever upgraded to a new version it can break your
existing XS modules. For a C<system> install shared libraries are
usually best because you can often get security patches without having
to re-build anything in perl land.
If you looked closely at the "Using commands" and "Using plugins"
sections above, you may notice that we went out of our way where
possible to tell Autotools to build only static libraries using the
C<--disable-shared> command. The Autoconf plugin also does this by
default.
Sometimes though you will have a package that builds both, or maybe
you I<want> both static and dynamic libraries to work with XS and FFI.
For that case, there is the L<Alien::Build::Plugin::Gather::IsolateDynamic>
plugin.
use alienfile;
...
plugin 'Gather::IsolateDynamic';
What it does, is that it moves the dynamic libraries (usually .so on
Unix and .DLL on Windows) to a place where they can be found by FFI,
and where they won't be used by the compiler for building XS. It usually
doesn't do any harm to include this plugin, so if you are just starting
out you might want to add it anyway. Arguably it should have been the
default behavior from the beginning.
If you have already published an Alien that does not isolate its
dynamic libraries, then you might get some fails from old upgraded
aliens because the share directory isn't cleaned up by default (this is
perhaps a design bug in the way that share directories work, but it
is a long standing characteristic). One work around for this is to
use the C<clean_install> property on L<Alien::Build::MM>, which will
clean out the share directory on upgrade, and possibly save you a lot
of grief.
=head2 Verifying and debugging your alienfile
You could feed your alienfile directly into L<Alien::Build>, or
L<Alien::Build::MM>, but it is sometimes useful to test your alienfile
using the C<af> command (it does not come with L<Alien::Build>, you need
to install L<App::af>). By default C<af> will use the C<alienfile> in
the current directory (just as C<make> uses the C<Makefile> in the
current directory; just like C<make> you can use the C<-f> option to
specify a different L<alienfile>).
You can test your L<alienfile> in dry run mode:
% af install --dry-run
Alien::Build::Plugin::Core::Legacy> adding legacy hash to config
Alien::Build::Plugin::Core::Gather> mkdir -p /tmp/I2YXRyxb0r/_alien
---
cflags: ''
cflags_static: ''
install_type: system
legacy:
finished_installing: 1
install_type: system
name: libfoo
original_prefix: /tmp/7RtAusykNN
version: 1.2.3
libs: '-lfoo '
libs_static: '-lfoo '
prefix: /tmp/7RtAusykNN
version: 1.2.3
You can use the C<--type> option to force a share install (download and
build from source):
% af install --type=share --dry-run
Alien::Build::Plugin::Core::Download> decoding html
Alien::Build::Plugin::Core::Download> candidate *https://www.libfoo.org/download/libfoo-1.2.4.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.3.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.2.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.1.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.0.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.1.9.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.1.8.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.1.7.tar.gz
Alien::Build::Plugin::Core::Download> candidate ...
Alien::Build::Plugin::Core::Download> setting version based on archive to 1.2.4
Alien::Build::Plugin::Core::Download> downloaded libfoo-1.2.4.tar.gz
Alien::Build::CommandSequence> + ./configure --prefix=/tmp/P22WEXj80r --with-pic --disable-shared
... snip ...
Alien::Build::Plugin::Core::Gather> mkdir -p /tmp/WsoLAQ889w/_alien
---
cflags: ''
cflags_static: ''
install_type: share
legacy:
finished_installing: 1
install_type: share
original_prefix: /tmp/P22WEXj80r
version: 1.2.4
libs: '-L/tmp/P22WEXj80r/lib -lfoo '
libs_static: '-L/tmp/P22WEXj80r/lib -lfoo '
prefix: /tmp/P22WEXj80r
version: 1.2.4
You can also use the C<--before> and C<--after> options to take a peek
at what the build environment looks like at different stages as well,
which can sometimes be useful:
% af install --dry-run --type=share --before build bash
Alien::Build::Plugin::Core::Download> decoding html
Alien::Build::Plugin::Core::Download> candidate *https://www.libfoo.org/download/libfoo-1.2.4.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.3.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.2.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.1.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.2.0.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.1.9.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.1.8.tar.gz
Alien::Build::Plugin::Core::Download> candidate https://www.libfoo.org/download/libfoo-1.1.7.tar.gz
Alien::Build::Plugin::Core::Download> candidate ...
Alien::Build::Plugin::Core::Download> setting version based on archive to 1.2.4
Alien::Build::Plugin::Core::Download> downloaded libfoo-1.2.4.tar.gz
App::af::install> [ before build ] + bash
/tmp/fbVPu4LRTs/build_5AVn/libfoo-1.2.4$ ls
CHANGES Makefile autoconf.ac lib
/tmp/fbVPu4LRTs/build_5AVn/libfoo-1.2.4$
There are a lot of other useful things that you can do with the C<af>
command. See L<af> for details.
=head2 Integrating with MakeMaker
Once you have a working L<alienfile> you can write your C<Makefile.PL>.
use ExtUtils::MakeMaker;
use Alien::Build::MM;
my $abmm = Alien::Build::MM->new;
WriteMakefile($abmm->mm_args(
ABSTRACT => 'Discover or download and install libfoo',
DISTNAME => 'Alien-Libfoo',
NAME => 'Alien::Libfoo',
VERSION_FROM => 'lib/Alien/Libfoo.pm',
CONFIGURE_REQUIRES => {
'Alien::Build::MM' => 0,
},
BUILD_REQUIRES => {
'Alien::Build::MM' => 0,
},
PREREQ_PM => {
'Alien::Base' => 0,
},
# If you are going to write the recommended
# tests you will will want these:
TEST_REQUIRES => {
'Test::Alien' => 0,
'Test2::V0' => 0,
},
));
sub MY::postamble {
$abmm->mm_postamble;
}
The C<lib/Alien/Libfoo.pm> that goes along with it is very simple:
package Alien::Libfoo;
use strict;
use warnings;
use base qw( Alien::Base );
1;
You are done and can install it normally:
% perl Makefile.PL
% make
% make test
% make install
=head2 Integrating with Module::Build
Please don't! Okay if you have to there is L<Alien::Build::MB>.
=head2 Non standard configuration
L<Alien::Base> support most of the things that your L<Alien> will need,
like compiler flags (cflags), linker flags (libs) and binary directory
(bin_dir). Your library or tool may have other configuration items
which are not supported by default. You can store the values in the
L<alienfile> into the runtime properties:
gather [
# standard:
[ 'foo-config --version libfoo', \'%{.runtime.version}' ],
[ 'foo-config --cflags libfoo', \'%{.runtime.cflags}' ],
[ 'foo-config --libs libfoo', \'%{.runtime.libs}' ],
# non-standard
[ 'foo-config --bar-baz libfoo', \'%{.runtime.bar_baz}' ],
];
then you can expose them in your L<Alien::Base> subclass:
package Alien::Libfoo;
use strict;
use warnings;
use base qw( Alien::Base );
sub bar_baz {
my($self) = @_;
$self->runtime_prop->{bar_baz},
};
1;
=head2 Testing
(optional, but highly recommended)
You should write a test using L<Test::Alien> to make sure that your
alien will work with any XS modules that are going to use it:
use Test2::V0;
use Test::Alien;
use Alien::Libfoo;
alien_ok 'Alien::Libfoo';
xs_ok do { local $/; <DATA> }, with_subtest {
is Foo::something(), 1, 'Foo::something() returns 1';
};
done_testing;
__DATA__
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <foo.h>
MODULE = Foo PACKAGE = Foo
int something()
You can also use L<Test::Alien> to test tools instead of libraries:
use Test2::V0;
use Test::Alien;
use Alien::Libfoo;
alien_ok 'Alien::Libfoo';
run_ok(['foo', '--version'])
->exit_is(0);
done_testing;
You can also write tests specifically for L<FFI::Platypus>, if your
alien is going to be used to write FFI bindings. (the test below
is the FFI equivalent to the XS example above).
use Test2::V0;
use Test::Alien;
use Alien::Libfoo;
alien_ok 'Alien::Libfoo';
ffi_ok { symbols => [ 'something' ] }, with_subtest {
# $ffi is an instance of FFI::Platypus with the lib
# set appropriately.
my($ffi) = @_;
my $something = $ffi->function( something => [] => 'int' );
is $something->call(), 1, 'Foo::something() returns 1';
};
If you do use C<ffi_ok> you want to make sure that your alien reliably
produces dynamic libraries. If it isn't consistent (if for example
some platforms tend not to provide or build dynamic libraries), you can
check that C<dynamic_libs> doesn't return an empty list.
...
alien_ok 'Alien::Libfoo';
SKIP: {
skip "This test requires a dynamic library"
unless Alien::Libfoo->dynamic_libs;
ffi_ok { symbols [ 'something' ] }, with_subtest {
...
};
}
More details on testing L<Alien> modules can be found in the
L<Test::Alien> documentation.
You can also run the tests that come with the package that you are alienizing,
by using a C<test> block in your L<alienfile>. Keep in mind that some packages
use testing tools or have other prerequisites that will not be available on your
users machines when they attempt to install your alien. So you do not want to
blindly add a test block without checking what the prereqs are. For Autoconf
style packages you typically test a package using the C<make check> command:
use alienfile;
plugin 'PkgConfig' => 'libfoo';
share {
... # standard build steps.
test [ '%{make} check' ];
};
=head2 Dist::Zilla
(optional, mildly recommended)
You can also use the L<Alien::Build> L<Dist::Zilla> plugin
L<Dist::Zilla::Plugin::AlienBuild>:
name = Alien-Libfoo
author = E. Xavier Ample <example@cpan.org>
license = Perl_5
copyright_holder = E. Xavier Ample <example@cpan.org>
copyright_year = 2017
version = 0.01
[@Basic]
[AlienBuild]
The plugin takes care of a lot of details like making sure that the
correct minimum versions of L<Alien::Build> and L<Alien::Base> are used.
See the plugin documentation for additional details.
=head2 Using your Alien
Once you have installed you can use your Alien. See
L<Alien::Build::Manual::AlienUser> for guidance on that.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,263 @@
# PODNAME: Alien::Build::Manual::AlienUser
# ABSTRACT: Alien user documentation
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Manual::AlienUser - Alien user documentation
=head1 VERSION
version 2.38
=head1 SYNOPSIS
perldoc Alien::Build::Manual::AlienUser
=head1 DESCRIPTION
This document is intended for a user of an L<Alien::Base> based L<Alien>
module's user. Although specifically geared for L<Alien::Base>
subclasses, it may have some useful hints for L<Alien> in general.
Full working examples of how to use an L<Alien> module are also bundled
with L<Alien::Build> in the distribution's C<example/user> directory.
Those examples use L<Alien::xz>, which uses L<alienfile> + L<Alien::Build>
+ L<Alien::Base>.
The following documentation will assume you are trying to use an L<Alien>
called C<Alien::Foo> which provides the library C<libfoo> and the command
line tool C<foo>. Many L<Alien>s will only provide one or the other.
The best interface to use for using L<Alien::Base> based aliens is
L<Alien::Base::Wrapper>. This allows you to combine multiple aliens together
and handles a number of corner obscure corner cases that using L<Alien>s
directly does not. Also as of 0.64, L<Alien::Base::Wrapper> comes bundled
with L<Alien::Build> and L<Alien::Base> anyway, so it is not an extra
dependency.
What follows are the main use cases.
=head2 ExtUtils::MakeMaker
use ExtUtils::MakeMaker;
use Alien::Base::Wrapper ();
WriteMakefile(
Alien::Base::Wrapper->new('Alien::Foo')->mm_args2(
NAME => 'FOO::XS',
...
),
);
L<Alien::Base::Wrapper> will take a hash of C<WriteMakefile> arguments
and insert the appropriate compiler and linker flags for you. This
is recommended over doing this yourself as the exact incantation to
get EUMM to work is tricky to get right.
The C<mm_args2> method will also set your C<CONFIGURE_REQUIRES> for
L<Alien::Base::Wrapper>, L<ExtUtils::MakeMaker> and any aliens that
you specify.
=head2 Module::Build
use Module::Build;
use Alien::Base::Wrapper qw( Alien::Foo !export );
use Alien::Foo;
my $build = Module::Build->new(
...
configure_requires => {
'Alien::Base::Wrapper' => '0',
'Alien::Foo' => '0',
...
},
Alien::Base::Wrapper->mb_args,
...
);
$build->create_build_script;
For L<Module::Build> you can also use L<Alien::Base::Wrapper>, but
you will have to specify the C<configure_requires> yourself.
=head2 Inline::C / Inline::CPP
use Inline 0.56 with => 'Alien::Foo';
L<Inline::C> and L<Inline::CPP> can be configured
to use an L<Alien::Base> based L<Alien> with the C<with> keyword.
=head2 ExtUtils::Depends
use ExtUtils::MakeMaker;
use ExtUtils::Depends;
my $pkg = ExtUtils::Depends->new("Alien::Foo");
WriteMakefile(
...
$pkg->get_makefile_vars,
...
);
L<ExtUtils::Depends> works similar to L<Alien::Base::Wrapper>, but uses
the L<Inline> interface under the covers.
=head2 Dist::Zilla
[@Filter]
-bundle = @Basic
-remove = MakeMaker
[Prereqs / ConfigureRequires]
Alien::Foo = 0
[MakeMaker::Awesome]
header = use Alien::Base::Wrapper qw( Alien::Foo !export );
WriteMakefile_arg = Alien::Base::Wrapper->mm_args
=head2 FFI::Platypus
use FFI::Platypus;
use Alien::Foo;
my $ffi = FFI::Platypus->new(
lib => [ Alien::Foo->dynamic_libs ],
);
Not all L<Alien>s provide dynamic libraries, but those that do can be
used by L<FFI::Platypus>. Unlike an XS module, these
need to be a regular run time prerequisite.
=head2 Inline::C
use Inline with => 'Alien::Foo';
use Inline C => <<~'END';
#include <foo.h>
const char *my_foo_wrapper()
{
foo();
}
END
sub exported_foo()
{
my_foo_wrapper();
}
=head2 tool
use Alien::Foo;
use Env qw( @PATH );
unshift @PATH, Alien::Foo->bin_dir;
system 'foo', '--bar', '--baz';
Some L<Alien>s provide tools instead of or in addition to a library.
You need to add them to the C<PATH> environment variable though.
(Unless the tool is already provided by the system, in which case
it is already in the path and the C<bin_dir> method will return an
empty list).
=head1 ENVIRONMENT
=over 4
=item ALIEN_INSTALL_TYPE
Although the recommended way for a consumer to use an L<Alien::Base> based L<Alien>
is to declare it as a static configure and build-time dependency, some consumers
may prefer to fallback on using an L<Alien> only when the consumer itself cannot
detect the necessary package. In some cases the consumer may want the user to opt-in
to using an L<Alien> before requiring it.
To keep the interface consistent among Aliens, the consumer of the fallback opt-in
L<Alien> may fallback on the L<Alien> if the environment variable C<ALIEN_INSTALL_TYPE>
is set to any value. The rationale is that by setting this environment variable the
user is aware that L<Alien> modules may be installed and have indicated consent.
The actual implementation of this, by its nature would have to be in the consuming
CPAN module.
This behavior should be documented in the consumer's POD.
See L<Alien::Build/ENVIRONMENT> for more details on the usage of this environment
variable.
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,263 @@
# PODNAME: Alien::Build::Manual::Contributing
# ABSTRACT: Over-detailed contributing guide
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Manual::Contributing - Over-detailed contributing guide
=head1 VERSION
version 2.38
=head1 SYNOPSIS
perldoc Alien::Build::Manual::Contributing
=head1 DESCRIPTION
Thank you for considering to contribute to my open source project! If
you have a small patch please consider just submitting it. Doing so
through the project GitHub is probably the best way:
L<https://github.com/plicease/Alien-Build/issues>
If you have a more invasive enhancement or bugfix to contribute, please
take the time to review these guidelines. In general it is good idea to
work closely with the L<Alien::Build> developers, and the best way to
contact them is on the C<#native> IRC channel on irc.perl.org.
=head2 History
Joel Berger wrote the original L<Alien::Base>. This distribution
included the runtime code L<Alien::Base> and an installer class
L<Alien::Base::ModuleBuild>. The significant thing about L<Alien::Base>
was that it provided tools to make it relatively easy for people to roll
their own L<Alien> distributions. Over time, the PerlAlien (github
organization) or "Alien::Base team" has taken over development of
L<Alien::Base> with myself (Graham Ollis) being responsible for
integration and releases. Joel Berger is still involved in the project.
Since the original development of L<Alien::Base>, L<Module::Build>, on
which L<Alien::Base::ModuleBuild> is based, has been removed from the
core of Perl. It seemed worthwhile to write a replacement installer
that works with L<ExtUtils::MakeMaker> which IS still bundled with the
Perl core. Because this is a significant undertaking it is my intention
to integrate the many lessons learned by Joel Berger, myself and the
"Alien::Base team" as possible. If the interface seems good then it is
because I've stolen the ideas from some pretty good places.
=head2 Philosophy
=head3 Alien runtime should be as config-only as possible.
Ideally the code for an L<Alien::Base> based L<Alien> should simply
inherit from L<Alien::Base>, like so:
package Alien::libfoo;
use base qw( Alien::Base );
1;
The detection logic should be done by the installer code (L<alienfile>
and L<Alien::Build>) and saved into runtime properties (see
L<Alien::Build/runtime_prop>). And as much as
possible the runtime should be implemented in the base class (L<Alien::Base>).
Where reasonable, the base class should be expanded to meet the needs
of this arrangement.
=head3 when downloading a package grab the latest version
If the maintainer of an L<Alien> disappears for a while, and if the
version downloaded during a "share" install is hardcoded in the
L<alienfile>, it can be problematic for end-users.
There are exceptions, of course, in particular when a package provides
a very unstable interface from version to version it makes sense
to hard code the version and for the Alien developer and Alien consumer
developer to coordinate closely.
=head3 when installing a package the operating system as a whole should not be affected
The convenience of using an L<Alien> is that a user of a CPAN module
that consumes an L<Alien> doesn't need to know the exact incantation
to install the libraries on which it depends (or indeed it may not be
easily installed through the package manager anyway).
As a corollary, a user of a CPAN module that consumes an L<Alien>
module shouldn't expect operating system level packages to be
installed, or for these packages to be installed in common system
level directories, like C</usr/local> or C</opt>. Instead a "share"
directory associated with the Perl install and L<Alien> module
should be used.
Plugins that require user opt-in could be written to prompt a user
to automatically install operating system packages, but this should
never be done by default or without consent by the user.
=head3 avoid dependencies
One of the challenges with L<Alien> development is that you are by the
nature of the problem, trying to make everyone happy. Developers
working out of CPAN just want stuff to work, and some build environments
can be hostile in terms of tool availability, so for reliability you end
up pulling a lot of dependencies. On the other hand, operating system
vendors who are building Perl modules usually want to use the system
version of a library so that they do not have to patch libraries in
multiple places. Such vendors have to package any extra dependencies
and having to do so for packages that the don't even use makes them
understandably unhappy.
As general policy the L<Alien::Build> core should have as few
dependencies as possible, and should only pull extra dependencies if
they are needed. Where dependencies cannot be avoidable, popular and
reliable CPAN modules, which are already available as packages in the
major Linux vendors (Debian, Red Hat) should be preferred.
As such L<Alien::Build> is hyper aggressive at using dynamic
prerequisites.
=head3 interface agnostic
One of the challenges with L<Alien::Buil::ModuleBuild> was that
L<Module::Build> was pulled from the core. In addition, there is a
degree of hostility toward L<Module::Build> in some corners of the Perl
community. I agree with Joel Berger's rationale for choosing
L<Module::Build> at the time, as I believe its interface more easily
lends itself to building L<Alien> distributions.
That said, an important feature of L<Alien::Build> is that it is
installer agnostic. Although it is initially designed to work with
L<ExtUtils::MakeMaker>, it has been designed from the ground up to work
with any installer (Perl, or otherwise).
As an extension of this, although L<Alien::Build> may have external CPAN
dependencies, they should not be exposed to developers USING
L<Alien::Build>. As an example, L<Path::Tiny> is used heavily
internally because it does what L<File::Spec> does, plus the things that
it doesn't, and uses forward slashes on Windows (backslashes are the
"correct separator on windows, but actually using them tends to break
everything). However, there aren't any interfaces in L<Alien::Build>
that will return a L<Path::Tiny> object (or if there are, then this is a
bug).
This means that if we ever need to port L<Alien::Build> to a platform
that doesn't support L<Path::Tiny> (such as VMS), then it may require
some work to L<Alien::Build> itself, modules that USE L<Alien::Build>
shouldn't need to be modified.
=head3 plugable
The actual logic that probes the system, downloads source and builds it
should be as pluggable as possible. One of the challenges with
L<Alien::Build::ModuleBuild> was that it was designed to work well with
software that works with C<autoconf> and C<pkg-config>. While you can
build with other tools, you have to know a bit of how the installer
logic works, and which hooks need to be tweaked.
L<Alien::Build> has plugins for C<autoconf>, C<pkgconf> (successor of
C<pkg-config>), vanilla Makefiles, and CMake. If your build system
doesn't have a plugin, then all you have to do is write one! Plugins
that prove their worth may be merged into the L<Alien::Build> core.
Plugins that after a while feel like maybe not such a good idea may be
removed from the core, or even from CPAN itself.
In addition, L<Alien::Build> has a special type of plugin, called a
negotiator which picks the best plugin for the particular environment
that it is running in. This way, as development of the negotiator and
plugins develop over time modules that use L<Alien::Build> will benefit,
without having to change the way they interface with L<Alien::Build>
=head1 ACKNOWLEDGEMENT
I would like to that Joel Berger for getting things running in the first
place. Also important to thank other members of the "Alien::Base team":
Zaki Mughal (SIVOAIS)
Ed J (ETJ, mohawk)
Also kind thanks to all of the developers who have contributed to
L<Alien::Base> over the years:
L<https://metacpan.org/pod/Alien::Base#CONTRIBUTORS>
=head1 SEE ALSO
L<alienfile>, L<Alien::Build::MM>, L<Alien::Build::Plugin>, L<Alien::Base>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,544 @@
# PODNAME: Alien::Build::Manual::FAQ
# ABSTRACT: Frequently Asked Questions about Alien::Build
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Manual::FAQ - Frequently Asked Questions about Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
perldoc Alien::Build::Manual::FAQ
=head1 DESCRIPTION
This document serves to answer the most frequently asked questions made by developers
creating L<Alien> modules using L<Alien::Build>.
=head1 QUESTIONS
=head2 What is Alien, Alien::Base and Alien::Build?
Alien in a Perl namespace for defining dependencies in CPAN for libraries and tools which
are not "native" to CPAN. For a manifesto style description of the Why, and How see
L<Alien>. L<Alien::Base> is a base class for the L<Alien> runtime. L<Alien::Build> is
a tool for probing the operating system for existing libraries and tools, and downloading, building
and installing packages. L<alienfile> is a recipe format for describing how to probe,
download, build and install a package.
=head2 How do I build a package that uses I<build system>
=head3 autoconf
Use the autoconf plugin (L<Alien::Build::Plugin::Build::Autoconf>). If your package
provides a pkg-config C<.pc> file, then you can also use the PkgConfig plugin
(L<Alien::Build::Plugin::PkgConfig::Negotiate>).
use alienfile
plugin PkgConfig => 'libfoo';
share {
start_url => 'http://example.org/dist';
plugin Download => (
version => qr/libfoo-([0-9\.])\.tar\.gz$/,
);
plugin Extract => 'tar.gz';
plugin 'Build::Autoconf';
};
If you need to provide custom flags to configure, you can do that too:
share {
plugin 'Build::Autoconf';
build [
'%{configure} --disable-shared --enable-foo',
'%{make}',
'%{make} install',
];
};
If your package requires GNU Make, use C<%{gmake}> instead of C<%{make}>.
=head3 autoconf-like
If you see an error like this:
Unknown option "--with-pic".
It is because the autoconf plugin uses the C<--with-pic> option by default, since
it makes sense most of the time, and autoconf usually ignores options that it does
not recognize. Some autoconf style build systems fail when they see an option that
they do not recognize. You can turn this behavior off for these packages:
plugin 'Build::Autoconf' => (
with_pic => 0,
);
Another thing about the autoconf plugin is that it uses C<DESTDIR> to do a double
staged install. If you see an error like "nothing was installed into destdir", that
means that your package does not support C<DESTDIR>. You should instead use the
MSYS plugin and use a command sequence to do the build like this:
share {
plugin 'Build::MSYS';
build [
# explicitly running configure with "sh" will make sure that
# it works on windows as well as UNIX.
'sh configure --prefix=%{.install.prefix} --disable-shared',
'%{make}',
'%{make} install',
];
};
=head3 CMake
There is an alien L<Alien::cmake3> that provides C<cmake> 3.x or better (It is preferred to the
older L<Alien::CMake>). Though it is recommended that you use the C<cmake>
(L<Alien::Build::Plugin::Build::CMake>) plugin instead of using L<Alien::cmake3>.
use alienfile;
share {
plugin 'Build::CMake';
build [
# this is the default build step, if you do not specify one.
[ '%{cmake}',
@{ meta->prop->{plugin_build_cmake}->{args} },
# ... put extra cmake args here ...
'.'
],
'%{make}',
'%{make} install',
];
};
=head3 vanilla Makefiles
L<Alien::Build> provides a helper (C<%{make}>) for the C<make> that is used by Perl and
L<ExtUtils::MakeMaker> (EUMM). Unfortunately the C<make> supported by Perl and EUMM on
Windows (C<nmake> and C<dmake>) are not widely supported by most open source projects.
(Thankfully recent perls and EUMM support GNU Make on windows now).
You can use the C<make> plugin (L<Alien::Build::Plugin::Build::Make>) to tell the
L<Alien::Build> system know which make the project that you are alienizing requires.
plugin 'Build::Make' => 'umake';
# umake makes %{make} either GNU Make or BSD Make on Unix and GNU Make on Windows.
build {
build [
# You can use the Perl config compiler and cflags using the %{perl.config...} helper
[ '%{make}', 'CC=%{perl.config.cc}', 'CFLAGS=%{perl.config.cccdlflags} %{perl.config.optimize}' ],
[ '%{make}', 'install', 'PREFIX=%{.install.prefix}' ],
],
};
Some open source projects require GNU Make, and you can specify that, and L<Alien::gmake>
will be pulled in on platforms that do not already have it.
plugin 'Build::Make' => 'gmake';
...
=head2 How do I probe for a package that uses pkg-config
Use the C<pkg-config> plugin (L<Alien::Build::Plugin::PkgConfig::Negotiate>):
use alienfile;
plugin 'PkgConfig' => (
pkg_name => 'libfoo',
);
It will probe for a system version of the library. It will also add the appropriate C<version>
C<cflags> and C<libs> properties on either a C<system> or C<share> install.
=head2 How do I specify a minimum or exact version requirement for packages that use pkg-config?
The various pkg-config plugins all support atleast_version, exact_version and maximum_version
fields, which have the same meaning as the C<pkg-config> command line interface:
use alienfile;
plugin 'PkgConfig', pkg_name => foo, atleast_version => '1.2.3';
or
use alienfile;
plugin 'PkgConfig', pkg_name => foo, exact_version => '1.2.3';
=head2 How to create an Alien module for a packages that do not support pkg-config?
=head3 Packages that provide a configuration script
Many packages provide a command that you can use to get the appropriate version, compiler
and linker flags. For those packages you can just use the commands in your L<alienfile>.
Something like this:
use alienfile;
probe [ 'foo-config --version' ];
share {
...
build [
'%{make} PREFIX=%{.runtime.prefix}',
'%{amek} install PREFIX=%{.runtime.prefix}',
];
};
gather [
[ 'foo-config', '--version', \'%{.runtime.version}' ],
[ 'foo-config', '--cflags', \'%{.runtime.cflags}' ],
[ 'foo-config', '--libs', \'%{.runtime.libs}' ],
];
=head3 Packages that require a compile test
Some packages just expect you do know that C<-lfoo> will work. For those you can use
the C<cbuilder> plugin (L<Alien::Build::Plugin::Probe::CBuilder>.
use alienfile;
plugin 'Probe::CBuilder' => (
cflags => '-I/opt/libfoo/include',
libs => '-L/opt/libfoo/lib -lfoo',
);
share {
...
gather sub {
my($build) = @_;
my $prefix = $build->runtime_prop->{prefix};
$build->runtime_prop->{cflags} = "-I$prefix/include ";
$build->runtime_prop->{libs} = "-L$prefix/lib -lfoo ";
};
}
This plugin will build a small program with these flags and test that it works. (There
are also options to provide a program that can make simple tests to ensure the library
works). If the probe works, it will set the compiler and linker flags. (There are also
options for extracting the version from the test program). If you do a share install
you will need to set the compiler and linker flags yourself in the gather step, if you
aren't using a build plugin that will do that for you.
=head2 Can/Should I write a tool oriented Alien module?
Certainly. The original intent was to provide libraries, but tools are also quite doable using
the L<Alien::Build> toolset. A good example of how to do this is L<Alien::nasm>. You will want
to use the 'Probe::CommandLine':
use alienfile;
plugin 'Probe::CommandLine' => (
command => 'gzip',
);
=head2 How do I test my package once it is built (before it is installed)?
Use L<Test::Alien>. It has extensive documentation, and integrates nicely with L<Alien::Base>.
=head2 How do I patch packages that need alterations?
If you have a diff file you can use patch:
use alienfile;
probe sub { 'share' }; # replace with appropriate probe
share {
...
patch [ '%{patch} -p1 < %{.install.patch}/mypatch.diff' ];
build [ ... ] ;
}
...
You can also patch using Perl if that is easier:
use alienfile;
probe sub { 'share' };
share {
...
patch sub {
my($build) = @_;
# make changes to source prior to build
};
build [ ... ];
};
=head2 The flags that a plugin produces are wrong!
Sometimes, the compiler or linker flags that the PkgConfig plugin comes up with are not quite
right. (Frequently this is actually because a package maintainer is providing a broken
C<.pc> file). (Other plugins may also have problems). You could replace the plugin's C<gather> step
but a better way is to provide a subroutine callback to be called after the gather stage
is complete. You can do this with the L<alienfile> C<after> directive:
use alienfile;
plugin 'PlgConfig' => 'libfoo';
share {
...
after 'gather' => sub {
my($build) = @_;
$build->runtime_prop->{libs} .= " -lbar"; # libfoo also requires libbar
$build->runtime_prop->{libs_static} .= " -lbar -lbaz"; # libfoo also requires libbaz under static linkage
};
};
Sometimes you only need to do this on certain platforms. You can adjust the logic based on C<$^O>
appropriately.
use alienfile;
plugin 'PlgConfig' => 'libfoo';
share {
...
after 'gather' => sub {
my($build) = @_;
if($^O eq 'MSWin32') {
$build->runtime_prop->{libs} .= " -lpsapi";
}
};
};
=head2 "cannot open shared object file" trying to load XS
The error looks something like this:
t/acme_alien_dontpanic2.t ....... 1/?
# Failed test 'xs'
# at t/acme_alien_dontpanic2.t line 13.
# XSLoader failed
# Can't load '/home/cip/.cpanm/work/1581635869.456/Acme-Alien-DontPanic2-2.0401/_alien/tmp/test-alien-lyiQNX/auto/Test/Alien/XS/ Mod0/Mod0.so' for module Test::Alien::XS::Mod0: libdontpanic.so.0: cannot open shared object file: No such file or directory at /opt /perl/5.30.1/lib/5.30.1/x86_64-linux/DynaLoader.pm line 193.
# at /home/cip/perl5/lib/perl5/Test/Alien.pm line 414.
# Compilation failed in require at /home/cip/perl5/lib/perl5/Test/Alien.pm line 414.
# BEGIN failed--compilation aborted at /home/cip/perl5/lib/perl5/Test/Alien.pm line 414.
t/acme_alien_dontpanic2.t ....... Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/6 subtests
t/acme_alien_dontpanic2__ffi.t .. ok
This error happened at test time for the Alien, but depending on your environment and Alien it might
happen later and the actual diagnostic wording might vary.
This is usually because your XS or Alien tries to use dynamic libraries instead of dynamic libraries.
Please consult the section about dynamic vs. static libraries in L<Alien::Build::Manual::AlienAuthor>.
The TL;DR is that L<Alien::Build::Plugin::Gather::IsolateDynamic> might help.
If you are the Alien author and the package you are alienizing doesn't have a static option you can
use L<Alien::Role::Dino>, but please note the extended set of caveats!
=head2 599 Internal Exception errors downloading packages from the internet
Alien::Build::Plugin::Fetch::HTTPTiny> 599 Internal Exception fetching http://dist.libuv.org/dist/v1.15.0
Alien::Build::Plugin::Fetch::HTTPTiny> exception: IO::Socket::SSL 1.42 must be installed for https support
Alien::Build::Plugin::Fetch::HTTPTiny> exception: Net::SSLeay 1.49 must be installed for https support
Alien::Build::Plugin::Fetch::HTTPTiny> An attempt at a SSL URL https was made, but your HTTP::Tiny does not appear to be able to use https.
Alien::Build::Plugin::Fetch::HTTPTiny> Please see: https://metacpan.org/pod/Alien::Build::Manual::FAQ#599-Internal-Exception-errors-downloading-packages-from-the-internet
error fetching http://dist.libuv.org/dist/v1.15.0: 599 Internal Exception at /Users/ollisg/.perlbrew/libs/perl-5.26.0@test1/lib/perl5/Alien/Build/Plugin/Fetch/HTTPTiny.pm line 68.
(Older versions of L<Alien::Build> produced a less verbose more confusing version of this diagnostic).
TL;DR, instead of this:
share {
start_url => 'http://example.org/dist';
...
};
do this:
share {
start_url => 'https://example.org/dist';
};
If the website is going to redirect to a secure URL anyway.
The "599 Internal Exception" indicates an "internal" exception from L<HTTP::Tiny> and is not a real
HTTP status code or error. This could mean a number of different problems, but most frequently
indicates that a SSL request was made without the required modules (L<Net::SSLeay> and
L<IO::Socket::SSL>). Normally the L<Alien::Build::Plugin::Download::Negotiate>
and L<Alien::Build::Plugin::Fetch::HTTPTiny> will make sure that the appropriate modules are added
to your prerequisites for you if you specify a C<https> URL. Some websites allow an initial request
from C<http> but then redirect to C<https>. If you can it is better to specify C<https>, if you
cannot, then you can instead use the C<ssl> property on either of those two plugins.
=head2 Network fetch is turned off
If you get an error like this:
Alien::Build> install type share requested or detected, but network fetch is turned off
Alien::Build> see see https://metacpan.org/pod/Alien::Build::Manual::FAQ#Network-fetch-is-turned-off
This is because your environment is setup not to install aliens that require the network. You
can turn network fetch back on by setting C<ALIEN_INSTALL_NETWORK> to true, or by unsetting it.
This environment variable is designed for environments that don't ever want to install aliens that
require downloading source packages over the internet.
=head2 I would really prefer you not download stuff off the internet
The idea of L<Alien> is to download missing packages and build them automatically to make installing
easier. Some people may not like this, or may even have security requirements that they not download
random package over the internet (caveat, downloading random stuff off of CPAN may not be any safer,
so make sure you audit all of the open source software that you use appropriately). Another reason
you may not want to download from the internet is if you are packaging up an alien for an operating
system vendor, which will always want to use the system version of a library. In that situation you
don't want L<Alien::Build> to go off and download something from the internet because the probe failed
for some reason.
This is easy to take care of, simply set C<ALIEN_INSTALL_TYPE> to C<system> and a build from source
code will never be attempted. On systems that do not provide system versions of the library or tool
you will get an error, allowing you to install the library, and retry the alien install. You can
also set the environment variable on just some aliens.
% export ALIEN_INSTALL_TYPE=system # for everyone
% env ALIEN_INSTALL_TYPE=system cpanm -v Alien::libfoo
=head2 For testing I would like to test both system and share installs!
You can use the C<ALIEN_INSTALL_TYPE> environment variable. It will force either a C<share> or
C<system> install depending on how it is set. For travis you can do something like this:
env:
matrix:
- ALIEN_INSTALL_TYPE=share
- ALIEN_INSTALL_TYPE=system
=head2 How do I use Alien::Build from Dist::Zilla?
For creating L<Alien::Base> and L<Alien::Build> based dist from L<Dist::Zilla> you can use the
dzil plugin L<Dist::Zilla::Plugin::AlienBuild>.
=head2 Cannot find either a share directory or a ConfigData module
If you see an error like this:
Cannot find either a share directory or a ConfigData module for Alien::libfoo.
(Alien::libfoo loaded from lib/Alien/libfoo.pm)
Please see https://metacpan.org/pod/distribution/Alien-Build/lib/Alien/Build/Manual/FAQ.pod#Cannot-find-either-a-share-directory-or-a-ConfigData-module
Can't locate Alien/libfoo/ConfigData.pm in @INC (you may need to install the Alien::libfoo::ConfigData module) (@INC contains: ...)
it means you are trying to use an Alien that hasn't been properly installed. An L<Alien::Base>
based Alien needs to have either the share directory build during the install process or for
older legacy L<Alien::Base::ModuleBuild> based Aliens, a ConfigData module generated by
L<Module::Build>.
This usually happens if you try to use an Alien module from the lib directory as part of the
Alien's distribution. You need to build the alien and use C<blib/lib> instead of C<lib> or
install the alien and use the installed path.
It is also possible that your Alien installer is not set up correctly. Make sure your
C<Makefile.PL> is using L<Alien::Build::MM> correctly.
=head2 I have a question not listed here!
There are a number of forums available to people working on L<Alien>, L<Alien::Base> and
L<Alien::Build> modules:
=over 4
=item C<#native> on irc.perl.org
This is intended for native interfaces in general so is a good place for questions about L<Alien>
generally or L<Alien::Base> and L<Alien::Build> specifically.
=item mailing list
The C<perl5-alien> google group is intended for L<Alien> issues generally, including L<Alien::Base>
and L<Alien::Build>.
L<https://groups.google.com/forum/#!forum/perl5-alien>
=item Open a support ticket
If you have an issue with L<Alie::Build> itself, then please open a support ticket on the project's GitHub issue
tracker.
L<https://github.com/plicease/Alien-Build/issues>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::MM>, L<Alien::Build::Plugin>, L<alienfile>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,497 @@
# PODNAME: Alien::Build::Manual::PluginAuthor
# ABSTRACT: Alien::Build plugin author documentation
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Manual::PluginAuthor - Alien::Build plugin author documentation
=head1 VERSION
version 2.38
=head1 SYNOPSIS
your plugin:
package Alien::Build::Plugin::Build::MyPlugin;
use strict;
use warnings;
use Alien::Build::Plugin;
has arg1 => 'default_for arg1';
has arg2 => sub { [ 'default', 'for', 'arg2' ] };
sub init
{
my($self, $meta) = @_;
...
}
1;
and then from L<alienfile>:
use alienfile;
plugin 'Build::MyPlugin' => (
arg1 => 'override for arg1',
arg2 => [ 'something', 'else' ],
);
=head1 DESCRIPTION
This document explains how to write L<Alien::Build> plugins using the
L<Alien::Build::Plugin> base class. Plugins use L<Alien::Build::Plugin>,
which sets the appropriate base class, and provides you with the C<has>
property builder. C<has> takes two arguments, the name of the property
and the default value. (As with L<Moose> and L<Moo>, you should use a
code reference to specify default values for non-string defaults).
The only method that you need to implement is C<init>. From this method
you can add hooks to change the behavior of the L<alienfile> recipe.
sub init
{
my($self, $meta) = @_;
$meta->register_hook(
probe => sub {
my($build) = @_;
if( ... )
{
return 'system';
}
else
{
return 'share';
}
},
);
}
Hooks get the L<Alien::Build> instance as their first argument, and depending
on the hook may get additional arguments.
You can also modify hooks using C<before_hook>, C<around_hook> and C<after_hook>:
sub init
{
my($self, $meta) = @_;
$meta->before_hook(
build => sub {
my($build) = @_;
$build->log('this runs before the build');
},
);
$meta->after_hook(
build => sub {
my($build) = @_;
$build->log('this runs after the build');
},
);
$meta->around_hook(
build => sub {
my $orig = shift;
# around hooks are useful for setting environment variables
local $ENV{CPPFLAGS} = '-I/foo/include';
$orig->(@_);
},
);
}
You can and should write tests for your plugin. The best way to do
this is using L<Test::Alien::Build>, which allows you to write an
inline L<alienfile> in your test.
use Test::V0;
use Test::Alien::Build;
my $build = alienfile_ok q{
use alienfile;
plugin 'Build::MyPlugin' => (
arg1 => 'override for arg1',
arg2 => [ 'something', 'else' ],
);
...
};
# you can interrogate $build, it is an instance of L<Alien::Build>.
my $alien = alien_build_ok;
# you can interrogate $alien, it is an instance of L<Alien::Base>.
=head1 HOOKS
=head2 probe hook
$meta->register_hook( probe => sub {
my($build) = @_;
return 'system' if ...; # system install
return 'share'; # otherwise
});
$meta->register_hook( probe => [ $command ] );
This hook should return the string C<system> if the operating
system provides the library or tool. It should return C<share>
otherwise.
You can also use a command that returns true when the tool
or library is available. For example for use with C<pkg-config>:
$meta->register_hook( probe =>
[ '%{pkgconf} --exists libfoo' ] );
Or if you needed a minimum version:
$meta->register_hook( probe =>
[ '%{pkgconf} --atleast-version=1.00 libfoo' ] );
Note that this hook SHOULD NOT gather system properties, such as
cflags, libs, versions, etc, because the probe hook will be skipped
in the event the environment variable C<ALIEN_INSTALL_TYPE> is set.
The detection of these properties should instead be done by the
C<gather_system> hook, below.
=head2 gather_system hook
$meta->register_hook( gather_system => sub {
my($build) = @_;
$build->runtime_prop->{cflags} = ...;
$build->runtime_prop->{libs} = ...;
$build->runtime_prop->{version} = ...;
});
This hook is called for a system install to determine the properties
necessary for using the library or tool. These properties should be
stored in the C<runtime_prop> hash as shown above. Typical properties
that are needed for libraries are cflags and libs. If at all possible
you should also try to determine the version of the library or tool.
=head2 download hook
$meta->register_hook( download => sub {
my($build) = @_;
...
});
This hook is used to download from the internet the source. Either as
an archive (like tar, zip, etc), or as a directory of files (git clone,
etc). When the hook is called, the current working directory will be a
new empty directory, so you can save the download to the current
directory. If you store a single file in the directory, L<Alien::Build>
will assume that it is an archive, which will be processed by the
extract hook below. If you store multiple files, L<Alien::Build> will
assume the current directory is the source root. If no files are stored
at all, an exception with an appropriate diagnostic will be thrown.
B<Note>: If you register this hook, then the fetch, decode and prefer
hooks will NOT be called.
=head2 fetch hook
package Alien::Build::Plugin::MyPlugin;
use strict;
use warnings;
use Alien::Build::Plugin;
use Carp ();
has '+url' => sub { Carp::croak "url is required property" };
sub init
{
my($self, $meta) = @_;
$meta->register_hook( fetch => sub {
my($build, $url) = @_;
...
}
}
1;
Used to fetch a resource. The first time it will be called without an
argument, so the configuration used to find the resource should be
specified by the plugin's properties. On subsequent calls the first
argument will be a URL.
Normally the first fetch will be to either a file or a directory listing.
If it is a file then the content should be returned as a hash reference
with the following keys:
# content of file stored in Perl
return {
type => 'file',
filename => $filename,
content => $content,
version => $version, # optional, if known
};
# content of file stored in the filesystem
return {
type => 'file',
filename => $filename,
path => $path, # full file system path to file
version => $version, # optional, if known
tmp => $tmp, # optional
};
C<$tmp> if set will indicate if the file is temporary or not, and can
be used by L<Alien::Build> to save a copy in some cases. The default
is true, so L<Alien::Build> assumes the file or directory is temporary
if you don't tell it otherwise.
If the URL points to a directory listing you should return it as either
a hash reference containing a list of files:
return {
type => 'list',
list => [
# filename: each filename should be just the
# filename portion, no path or url.
# url: each url should be the complete url
# needed to fetch the file.
# version: OPTIONAL, may be provided by some fetch or prefer
{ filename => $filename1, url => $url1, version => $version1 },
{ filename => $filename2, url => $url2, version => $version2 },
]
};
or if the listing is in HTML format as a hash reference containing the
HTML information:
return {
type => 'html',
charset => $charset, # optional
base => $base, # the base URL: used for computing relative URLs
content => $content, # the HTML content
};
or a directory listing (usually produced by ftp servers) as a hash
reference:
return {
type => 'dir_listing',
base => $base,
content => $content,
};
=head2 decode hook
sub init
{
my($self, $meta) = @_;
$meta->register_hook( decode => sub {
my($build, $res) = @_;
...
}
}
This hook takes a response hash reference from the C<fetch> hook above
with a type of C<html> or C<dir_listing> and converts it into a response
hash reference of type C<list>. In short it takes an HTML or FTP file
listing response from a fetch hook and converts it into a list of filenames
and links that can be used by the prefer hook to choose the correct file to
download. See C<fetch> for the specification of the input and response
hash references.
=head2 prefer hook
sub init
{
my($self, $meta) = @_;
$meta->register_hook( prefer => sub {
my($build, $res) = @_;
return {
type => 'list',
list => [sort @{ $res->{list} }],
};
}
}
This hook sorts candidates from a listing generated from either the C<fetch>
or C<decode> hooks. It should return a new list hash reference with the
candidates sorted from best to worst. It may also remove candidates
that are totally unacceptable.
=head2 extract hook
$meta->register_hook( extract => sub {
my($build, $archive) = @_;
...
});
=head2 patch hook
$meta->register_hook( patch => sub {
my($build) = @_;
...
});
This hook is completely optional. If registered, it will be triggered after
extraction and before build. It allows you to apply any patches or make any
modifications to the source if they are necessary.
=head2 patch_ffi hook
$meta->register_hook( patch_ffi => sub {
my($build) = @_;
...
});
This hook is exactly like the C<patch> hook, except it fires only on an
FFI build.
=head2 build hook
$meta->register_hook( build => sub {
my($build) = @_;
...
});
This does the main build of the alienized project and installs it into
the staging area. The current directory is the build root. You need
to run whatever tools are necessary for the project, and install them
into C<%{.install.prefix}>.
=head2 build_ffi hook
$meta->register_hook( build_ffi => sub {
my($build) = @_;
...
});
This is the same as C<build>, except it fires only on a FFI build.
=head2 gather_share hook
$meta->register_hook( gather_share => sub {
my($build) = @_;
...
});
This is the same as C<gather_system>, except it fires after a C<share>
install.
=head2 gather_ffi hook
$meta->register_hook( gather_ffi => sub {
my($build) = @_;
...
});
This is the same as C<gather_share>, except it fires after a C<share> FFI
install.
=head2 override hook
$meta->register_hook( override => sub {
my($build) = @_;
});
This allows you to alter the override logic. It should return one of
C<share>, C<system>, C<default> or C<''>. The default implementation is
just this:
return $ENV{ALIEN_INSTALL_TYPE} || '';
=head2 clean_install
$meta->register_hook( clean_install => sub {
my($build) = @_;
});
This hook allows you to remove files from the final install location before
the files are installed by the installer layer (examples: L<Alien::Build::MM>,
L<Alien::Build::MB> or L<App::af>). This hook is never called by default,
and must be enabled via the interface to the installer layer.
This hook SHOULD NOT remove the C<_alien> directory or its content from the
install location.
The default implementation removes all the files EXCEPT the C<_alien> directory
and its content.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,364 @@
package Alien::Build::Plugin;
use strict;
use warnings;
use 5.008004;
use Data::Dumper ();
use Carp ();
use Digest::SHA ();
our @CARP_NOT = qw( alienfile Alien::Build Alien::Build::Meta );
# ABSTRACT: Plugin base class for Alien::Build
our $VERSION = '2.38'; # VERSION
sub new
{
my $class = shift;
my %args = @_ == 1 ? ($class->meta->default => $_[0]) : @_;
my $instance_id = Digest::SHA::sha1_hex(Data::Dumper->new([$class, \%args])->Sortkeys(1)->Dump);
my $self = bless { instance_id => $instance_id }, $class;
my $prop = $self->meta->prop;
foreach my $name (keys %$prop)
{
$self->{$name} = defined $args{$name}
? delete $args{$name}
: ref($prop->{$name}) eq 'CODE'
? $prop->{$name}->()
: $prop->{$name};
}
foreach my $name (keys %args)
{
Carp::carp "$class has no $name property";
}
$self;
}
sub instance_id { shift->{instance_id} }
sub init
{
my($self) = @_;
$self;
}
sub import
{
my($class) = @_;
return if $class ne __PACKAGE__;
my $caller = caller;
{ no strict 'refs'; @{ "${caller}::ISA" } = __PACKAGE__ }
my $meta = $caller->meta;
my $has = sub {
my($name, $default) = @_;
$meta->add_property($name, $default);
};
{ no strict 'refs'; *{ "${caller}::has" } = $has }
}
sub subplugin
{
my(undef, $name, %args) = @_;
Carp::carp("subplugin method is deprecated");
my $class = "Alien::Build::Plugin::$name";
my $pm = "$class.pm";
$pm =~ s/::/\//g;
require $pm unless eval { $class->can('new') };
delete $args{$_} for grep { ! defined $args{$_} } keys %args;
$class->new(%args);
}
my %meta;
sub meta
{
my($class) = @_;
$class = ref $class if ref $class;
$meta{$class} ||= Alien::Build::PluginMeta->new( class => $class );
}
package Alien::Build::PluginMeta;
sub new
{
my($class, %args) = @_;
my $self = bless {
prop => {},
%args,
}, $class;
}
sub default
{
my($self) = @_;
$self->{default} || do {
Carp::croak "No default for @{[ $self->{class} ]}";
};
}
sub add_property
{
my($self, $name, $default) = @_;
my $single = $name =~ s{^(\+)}{};
$self->{default} = $name if $single;
$self->{prop}->{$name} = $default;
my $accessor = sub {
my($self, $new) = @_;
$self->{$name} = $new if defined $new;
$self->{$name};
};
# add the accessor
{ no strict 'refs'; *{ $self->{class} . '::' . $name} = $accessor }
$self;
}
sub prop
{
shift->{prop};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin - Plugin base class for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
Create your plugin:
package Alien::Build::Plugin::Type::MyPlugin;
use Alien::Build::Plugin;
use Carp ();
has prop1 => 'default value';
has prop2 => sub { 'default value' };
has prop3 => sub { Carp::croak 'prop3 is a required property' };
sub init
{
my($self, $meta) = @_;
my $prop1 = $self->prop1;
my $prop2 = $self->prop2;
my $prop3 = $self->prop3;
$meta->register_hook(sub {
build => [ '%{make}', '%{make} install' ],
});
}
From your L<alienfile>
use alienfile;
plugin 'Type::MyPlugin' => (
prop2 => 'different value',
prop3 => 'need to provide since it is required',
);
=head1 DESCRIPTION
This document describes the L<Alien::Build> plugin base class. For details
on how to write a plugin, see L<Alien::Build::Manual::PluginAuthor>.
Listed are some common types of plugins:
=over 4
=item L<Alien::Build::Plugin::Build>
Tools for building.
=item L<Alien::Build::Plugin::Core>
Tools already included.
=item L<Alien::Build::Plugin::Download>
Methods for retrieving from the internet.
=item L<Alien::Build::Plugin::Decode>
Normally use Download plugins which will pick the correct Decode plugins.
=item L<Alien::Build::Plugin::Extract>
Extract from archives that have been downloaded.
=item L<Alien::Build::Plugin::Fetch>
Normally use Download plugins which will pick the correct Fetch plugins.
=item L<Alien::Build::Plugin::Prefer>
Normally use Download plugins which will pick the correct Prefer plugins.
=item L<Alien::Build::Plugin::Probe>
Look for packages already installed on the system.
=back
=head1 CONSTRUCTOR
=head2 new
my $plugin = Alien::Build::Plugin->new(%props);
=head2 PROPERTIES
=head2 instance_id
my $id = $plugin->instance_id;
Returns an instance id for the plugin. This is computed from the class and
arguments that are passed into the plugin constructor, so technically two
instances with the exact same arguments will have the same instance id, but
in practice you should never have two instances with the exact same arguments.
=head1 METHODS
=head2 init
$plugin->init($ab_class->meta); # $ab is an Alien::Build class name
You provide the implementation for this. The intent is to register
hooks and set meta properties on the L<Alien::Build> class.
=head2 subplugin
B<DEPRECATED>: Maybe removed, but not before 1 October 2018.
my $plugin2 = $plugin1->subplugin($plugin_name, %args);
Finds the given plugin and loads it (unless already loaded) and creats a
new instance and returns it. Most useful from a Negotiate plugin,
like this:
sub init
{
my($self, $meta) = @_;
$self->subplugin(
'Foo::Bar', # loads Alien::Build::Plugin::Foo::Bar,
# or throw exception
foo => 1, # these key/value pairs passsed into new
bar => 2, # for the plugin instance.
)->init($meta);
}
=head2 has
has $prop_name;
has $prop_name => $default;
Specifies a property of the plugin. You may provide a default value as either
a string scalar, or a code reference. The code reference will be called to
compute the default value, and if you want the default to be a list or hash
reference, this is how you want to do it:
has foo => sub { [1,2,3] };
=head2 meta
my $meta = $plugin->meta;
Returns the plugin meta object.
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>, L<Alien::Build::Manual::PluginAuthor>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,115 @@
# PODNAME: Alien::Build::Plugin::Build
# ABSTRACT: Build Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build - Build Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
For autoconf:
use alienfile;
plugin 'Build::Autoconf';
for unixy (even on windows):
use alienfile;
plugin 'Build::MSYS';
=head1 DESCRIPTION
Build plugins provide tools for building your package once it has been
downloaded and extracted.
=over 4
=item L<Alien::Build::Plugin::Build::Autoconf>
=item L<Alien::Build::Plugin::Build::MSYS>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,339 @@
package Alien::Build::Plugin::Build::Autoconf;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use constant _win => $^O eq 'MSWin32';
use Path::Tiny ();
use File::Temp ();
# ABSTRACT: Autoconf plugin for Alien::Build
our $VERSION = '2.38'; # VERSION
has with_pic => 1;
has ffi => 0;
has msys_version => undef;
has config_site => sub {
my $config_site = "# file automatically generated by @{[ __FILE__ ]}\n";
$config_site .= ". $ENV{CONFIG_SITE}\n" if defined $ENV{CONFIG_SITE};
$config_site .= ". $ENV{ALIEN_BUILD_SITE_CONFIG}\n" if defined $ENV{ALIEN_BUILD_SITE_CONFIG};
# on some platforms autofools sorry I mean autotools likes to install into
# exec_prefix/lib64 or even worse exec_prefix/lib/64 but that messes everything
# else up so we try to nip that in the bud.
$config_site .= "libdir='\${prefix}/lib'\n";
$config_site;
};
sub init
{
my($self, $meta) = @_;
$meta->apply_plugin('Build::MSYS',
(defined $self->msys_version ? (msys_version => $self->msys_version) : ()),
);
$meta->prop->{destdir} = 1;
$meta->prop->{autoconf} = 1;
my $intr = $meta->interpolator;
my $set_autoconf_prefix = sub {
my($build) = @_;
my $prefix = $build->install_prop->{prefix};
die "Prefix is not set. Did you forget to run 'make alien_prefix'?"
unless $prefix;
if(_win)
{
$prefix = Path::Tiny->new($prefix)->stringify;
$prefix =~ s!^([a-z]):!/$1!i if _win;
}
$build->install_prop->{autoconf_prefix} = $prefix;
};
$meta->before_hook(
build_ffi => $set_autoconf_prefix,
);
# FFI mode undocumented for now...
if($self->ffi)
{
$meta->add_requires('configure', 'Alien::Build::Plugin::Build::Autoconf' => '0.41');
$meta->default_hook(
build_ffi => [
'%{configure} --enable-shared --disable-static --libdir=%{.install.autoconf_prefix}/dynamic',
'%{make}',
'%{make} install',
]
);
if($^O eq 'MSWin32')
{
# for whatever reason autohell puts the .dll files in bin, even if you
# point --bindir somewhere else.
$meta->after_hook(
build_ffi => sub {
my($build) = @_;
my $prefix = $build->install_prop->{autoconf_prefix};
my $bin = Path::Tiny->new($ENV{DESTDIR})->child($prefix)->child('bin');
my $lib = Path::Tiny->new($ENV{DESTDIR})->child($prefix)->child('dynamic');
if(-d $bin)
{
foreach my $from (grep { $_->basename =~ /.dll$/i } $bin->children)
{
$lib->mkpath;
my $to = $lib->child($from->basename);
$build->log("copy $from => $to");
$from->copy($to);
}
}
}
);
}
}
$meta->around_hook(
build => sub {
my $orig = shift;
my $build = shift;
$set_autoconf_prefix->($build);
my $prefix = $build->install_prop->{autoconf_prefix};
die "Prefix is not set. Did you forget to run 'make alien_prefix'?"
unless $prefix;
local $ENV{CONFIG_SITE} = do {
my $site_config = Path::Tiny->new(File::Temp::tempdir( CLEANUP => 1 ))->child('config.site');
$site_config->spew($self->config_site);
"$site_config";
};
$intr->replace_helper(
configure => sub {
my $configure;
if($build->meta_prop->{out_of_source})
{
my $extract = $build->install_prop->{extract};
$configure = _win ? "sh $extract/configure" : "$extract/configure";
}
else
{
$configure = _win ? 'sh ./configure' : './configure';
}
$configure .= ' --prefix=' . $prefix;
$configure .= ' --with-pic' if $self->with_pic;
$configure;
}
);
my $ret = $orig->($build, @_);
if(_win)
{
my $real_prefix = Path::Tiny->new($build->install_prop->{prefix});
my @pkgconf_dirs;
push @pkgconf_dirs, Path::Tiny->new($ENV{DESTDIR})->child($prefix)->child("$_/pkgconfig") for qw(lib share);
# for any pkg-config style .pc files that are dropped, we need
# to convert the MSYS /C/Foo style paths to C:/Foo
for my $pkgconf_dir (@pkgconf_dirs) {
if(-d $pkgconf_dir)
{
foreach my $pc_file ($pkgconf_dir->children)
{
$pc_file->edit(sub {s/\Q$prefix\E/$real_prefix->stringify/eg;});
}
}
}
}
$ret;
},
);
$intr->add_helper(
configure => sub {
my $configure = _win ? 'sh configure' : './configure';
$configure .= ' --with-pic' if $self->with_pic;
$configure;
},
);
$meta->default_hook(
build => [
'%{configure} --disable-shared',
'%{make}',
'%{make} install',
]
);
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build::Autoconf - Autoconf plugin for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Build::Autoconf';
=head1 DESCRIPTION
This plugin provides some tools for building projects that use autoconf. The main thing
this provides is a C<configure> helper, documented below and the default build stage,
which is:
'%{configure} --disable-shared',
'%{make}',
'%{make} install',
On Windows, this plugin also pulls in the L<Alien::Build::Plugin::Build::MSYS> which is
required for autoconf style projects on windows.
The other thing that this plugin does is that it does a double staged C<DESTDIR> install.
The author has found this improves the overall reliability of L<Alien> modules that are
based on autoconf packages.
This plugin supports out-of-source builds (known in autoconf terms as "VPATH" builds) via
the meta property C<out_of_source>.
=head1 PROPERTIES
=head2 with_pic
Adds C<--with-pic> option when running C<configure>. If supported by your package, it
will generate position independent code on platforms that support it. This is required
to XS modules, and generally what you want.
autoconf normally ignores options that it does not understand, so it is usually a safe
and reasonable default to include it. A small number of projects look like they use
autoconf, but are really an autoconf style interface with a different implementation.
They may fail if you try to provide it with options such as C<--with-pic> that they do
not recognize. Such packages are the rationale for this property.
=head2 msys_version
The version of L<Alien::MSYS> required if it is deemed necessary. If L<Alien::MSYS>
isn't needed (if running under Unix, or MSYS2, for example) this will do nothing.
=head2 config_site
The content for the generated C<config.site>.
=head1 HELPERS
=head2 configure
%{configure}
The correct incantation to start an autoconf style C<configure> script on your platform.
Some reasonable default flags will be provided.
=head1 ENVIRONMENT
=over 4
=item C<ALIEN_BUILD_SITE_CONFIG>
This plugin needs to alter the behavior of autotools via the C<site.config> file and so sets
and possibly overrides any existing C<SITE_CONFIG>. Normally that is what you want but you
can also insert your own C<site.config> in addition by using this environment variable.
=back
=head1 SEE ALSO
L<Alien::Build::Plugin::Build::MSYS>, L<Alien::Build::Plugin>, L<Alien::Build>, L<Alien::Base>, L<Alien>
L<https://www.gnu.org/software/autoconf/autoconf.html>
L<https://www.gnu.org/prep/standards/html_node/DESTDIR.html>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,276 @@
package Alien::Build::Plugin::Build::CMake;
use strict;
use warnings;
use 5.008004;
use Config;
use Alien::Build::Plugin;
use Capture::Tiny qw( capture );
# ABSTRACT: CMake plugin for Alien::Build
our $VERSION = '2.38'; # VERSION
sub cmake_generator
{
if($^O eq 'MSWin32')
{
return 'MinGW Makefiles' if is_dmake();
{
my($out, $err) = capture { system $Config{make}, '/?' };
return 'NMake Makefiles' if $out =~ /NMAKE/;
}
{
my($out, $err) = capture { system $Config{make}, '--version' };
return 'MinGW Makefiles' if $out =~ /GNU Make/;
}
die 'make not detected';
}
else
{
return 'Unix Makefiles';
}
}
sub init
{
my($self, $meta) = @_;
$meta->prop->{destdir} = $^O eq 'MSWin32' ? 0 : 1;
$meta->add_requires('configure' => 'Alien::Build::Plugin::Build::CMake' => '0.99');
$meta->add_requires('share' => 'Alien::cmake3' => '0.02');
if(is_dmake())
{
# even on at least some older versions of strawberry that do not
# use it, come with gmake in the PATH. So to save us the effort
# of having to install Alien::gmake lets just use that version
# if we can find it!
my $found_gnu_make = 0;
foreach my $exe (qw( gmake make mingw32-make ))
{
my($out, $err) = capture { system $exe, '--version' };
if($out =~ /GNU Make/)
{
$meta->interpolator->replace_helper('make' => sub { $exe });
$found_gnu_make = 1;
last;
}
}
if(!$found_gnu_make)
{
$meta->add_requires('share' => 'Alien::gmake' => '0.20');
$meta->interpolator->replace_helper('make' => sub { require Alien::gmake; Alien::gmake->exe });
}
}
$meta->interpolator->replace_helper('cmake' => sub { require Alien::cmake3; Alien::cmake3->exe });
$meta->interpolator->add_helper('cmake_generator' => \&cmake_generator);
my @args = (
-G => '%{cmake_generator}',
'-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true',
'-DCMAKE_INSTALL_PREFIX:PATH=%{.install.prefix}',
'-DCMAKE_INSTALL_LIBDIR:PATH=lib',
'-DCMAKE_MAKE_PROGRAM:PATH=%{make}',
);
$meta->prop->{plugin_build_cmake}->{args} = \@args;
$meta->default_hook(
build => [
['%{cmake}', @args, '%{.install.extract}' ],
['%{make}' ],
['%{make}', 'install' ],
],
);
# TODO: handle destdir on windows ??
}
my $is_dmake;
sub is_dmake
{
unless(defined $is_dmake)
{
if($^O eq 'MSWin32')
{
my($out, $err) = capture { system $Config{make}, '-V' };
$is_dmake = $out =~ /dmake/ ? 1 : 0;
}
else
{
$is_dmake = 0;
}
}
$is_dmake;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build::CMake - CMake plugin for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
plugin 'Build::CMake';
build [
# this is the default build step, if you do not specify one.
[ '%{cmake}',
@{ meta->prop->{plugin_build_cmake}->{args} },
# ... put extra cmake args here ...
'%{.install.extract}'
],
'%{make}',
'%{make} install',
];
};
=head1 DESCRIPTION
This plugin helps build alienized projects that use C<cmake>.
The intention is to make this a core L<Alien::Build> plugin if/when
it becomes stable enough.
This plugin provides a meta property C<plugin_build_cmake.args> which may change over time
but for the moment includes:
-G %{cmake_generator} \
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \
-DCMAKE_INSTALL_PREFIX:PATH=%{.install.prefix} \
-DCMAKE_INSTALL_LIBDIR:PATH=lib \
-DCMAKE_MAKE_PROGRAM:PATH=%{make}
This plugin supports out-of-source builds via the meta property C<out_of_source>.
=head1 METHODS
=head2 cmake_generator
Returns the C<cmake> generator according to your Perl's C<make>.
=head2 is_dmake
Returns true if your Perls C<make> appears to be C<dmake>.
=head1 HELPERS
=head2 cmake
This plugin replaces the default C<cmake> helper with the one that comes from L<Alien::cmake3>.
=head2 cmake_generator
This is the appropriate C<cmake> generator to use based on the make used by your Perl. This is
frequently C<Unix Makefiles>. One place where it may be different is if your Windows Perl uses
C<nmake>, which comes with Visual C++.
=head2 make
This plugin I<may> replace the default C<make> helper if the default C<make> is not supported by
C<cmake>. This is most often an issue with older versions of Strawberry Perl which used C<dmake>.
On Perls that use C<dmake>, this plugin will search for GNU Make in the PATH, and if it can't be
found will fallback on using L<Alien::gmake>.
=head1 SEE ALSO
=over 4
=item L<Alien::Build>
=item L<Alien::Build::Plugin::Build::Autoconf>
=item L<alienfile>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,175 @@
package Alien::Build::Plugin::Build::Copy;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Path::Tiny ();
# ABSTRACT: Copy plugin for Alien::Build
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->add_requires( 'configure', __PACKAGE__, 0);
if($^O eq 'MSWin32')
{
$meta->register_hook(build => sub {
my($build) = @_;
my $stage = Path::Tiny->new($build->install_prop->{stage})->canonpath;
$build->system("xcopy . $stage /E");
});
}
else
{
$meta->register_hook(build => [
'cp -aR * %{.install.stage}', # TODO: some platforms might not support -a
# I think most platforms will support -r
]);
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build::Copy - Copy plugin for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Build::Copy';
=head1 DESCRIPTION
This plugin copies all of the files from the source to the staging prefix.
This is mainly useful for software packages that are provided as binary
blobs. It works on both Unix and Windows using the appropriate commands
for those platforms without having worry about the platform details in your
L<alienfile>.
If you want to filter add or remove files from what gets installed you can
use a C<before> hook.
build {
...
before 'build' => sub {
# remove or modify files
};
plugin 'Build::Copy';
...
};
Some packages might have binary blobs on some platforms and require build
from source on others. In that situation you can use C<if> statements
with the appropriate logic in your L<alienfile>.
configure {
# normally the Build::Copy plugin will insert itself
# as a config requires, but since it is only used
# on some platforms, you will want to explicitly
# require it in your alienfile in case you build your
# alien dist on a platform that doesn't use it.
requires 'Alien::Build::Plugin::Build::Copy';
};
build {
...
if($^O eq 'linux')
{
start_url 'http://example.com/binary-blob-linux.tar.gz';
plugin 'Download';
plugin 'Extract' => 'tar.gz';
plugin 'Build::Copy';
}
else
{
start_url 'http://example.com/source.tar.gz';
plugin 'Download';
plugin 'Extract' => 'tar.gz';
plugin 'Build::Autoconf';
}
};
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,189 @@
package Alien::Build::Plugin::Build::MSYS;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Which ();
use Env qw( @PATH );
# ABSTRACT: MSYS plugin for Alien::Build
our $VERSION = '2.38'; # VERSION
has msys_version => '0.07';
sub init
{
my($self, $meta) = @_;
if($self->msys_version ne '0.07')
{
$meta->add_requires('configure' => 'Alien::Build::Plugin::Build::MSYS' => '0.84');
}
if(_win_and_needs_msys($meta))
{
$meta->add_requires('share' => 'Alien::MSYS' => $self->msys_version);
$meta->around_hook(
$_ => sub {
my $orig = shift;
my $build = shift;
local $ENV{PATH} = $ENV{PATH};
unshift @PATH, Alien::MSYS::msys_path();
$orig->($build, @_);
},
) for qw( build build_ffi test_share test_ffi );
}
if($^O eq 'MSWin32')
{
# Most likely if we are trying to build something unix-y and
# we are using MSYS, then we want to use the make that comes
# with MSYS.
$meta->interpolator->replace_helper(
make => sub { 'make' },
);
}
$self;
}
sub _win_and_needs_msys
{
my($meta) = @_;
# check to see if we are running on windows.
# if we are running on windows, check to see if
# it is MSYS2, then we can just use that. Otherwise
# we are probably on Strawberry, or (less likely)
# VC Perl, in which case we will still need Alien::MSYS
return 0 unless $^O eq 'MSWin32';
return 0 if $meta->prop->{platform}->{system_type} eq 'windows-mingw';
return 1;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build::MSYS - MSYS plugin for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Build::MSYS';
=head1 DESCRIPTION
This plugin sets up the MSYS environment for your build on Windows. It does
not do anything on non-windows platforms. MSYS provides the essential tools
for building software that is normally expected in a UNIX or POSIX environment.
This like C<sh>, C<awk> and C<make>. To provide MSYS, this plugin uses
L<Alien::MSYS>.
=head1 PROPERTIES
=head2 msys_version
The version of L<Alien::MSYS> required if it is deemed necessary. If L<Alien::MSYS>
isn't needed (if running under Unix, or MSYS2, for example) this will do nothing.
=head1 HELPERS
=head2 make
%{make}
On windows the default C<%{make}> helper is replace with the make that comes with
L<Alien::MSYS>. This is almost certainly what you want, as most unix style make
projects will not build with C<nmake> or C<dmake> typically used by Perl on Windows.
=head1 SEE ALSO
L<Alien::Build::Plugin::Autoconf>, L<Alien::Build::Plugin>, L<Alien::Build>, L<Alien::Base>, L<Alien>
L<http://www.mingw.org/wiki/MSYS>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,209 @@
package Alien::Build::Plugin::Build::Make;
use strict;
use warnings;
use 5.008004;
use Carp ();
use Capture::Tiny qw( capture );
use Alien::Build::Plugin;
# ABSTRACT: Make plugin for Alien::Build
our $VERSION = '2.38'; # VERSION
has '+make_type' => undef;
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure', 'Alien::Build::Plugin::Build::Make', '0.99');
my $type = $self->make_type;
return unless defined $type;
$type = 'gmake' if $^O eq 'MSWin32' && $type eq 'umake';
if($type eq 'nmake')
{
$meta->interpolator->replace_helper( make => sub { 'nmake' } );
}
elsif($type eq 'dmake')
{
$meta->interpolator->replace_helper( make => sub { 'dmake' } );
}
elsif($type eq 'gmake')
{
my $found = 0;
foreach my $make (qw( gmake make mingw32-make ))
{
my($out, $err) = capture { system $make, '--version' };
if($out =~ /GNU Make/)
{
$meta->interpolator->replace_helper( make => sub { $make } );
$found = 1;
}
}
unless($found)
{
$meta->add_requires('share' => 'Alien::gmake' => '0.20');
$meta->interpolator->replace_helper('make' => sub { require Alien::gmake; Alien::gmake->exe });
}
}
elsif($type eq 'umake')
{
# nothing
}
else
{
Carp::croak("unknown make type = ", $self->make_type);
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build::Make - Make plugin for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# For a recipe that requires GNU Make
plugin 'Build::Make' => 'gmake';
=head1 DESCRIPTION
By default L<Alien::Build> provides a helper for the C<make> that is used by Perl and L<ExtUtils::MakeMaker> itself.
This is handy, because it is the one make that you can mostly guarantee that you will have. Unfortunately it may be
a C<make> that isn't supported by the library or tool that you are trying to alienize. This is mostly a problem on
Windows, where the supported C<make>s for years were Microsoft's C<nmake> and Sun's C<dmake>, which many open source
projects do not use. This plugin will alter the L<alienfile> recipe to use a different C<make>. It may (as in the
case of C<gmake> / L<Alien::gmake>) automatically download and install an alienized version of that C<make> if it
is not already installed.
This plugin should NOT be used with other plugins that replace the C<make> helper, like
L<Alien::Build::Plugin::Build::CMake>, L<Alien::Build::Plugin::Build::Autoconf>,
L<Alien::Build::Plugin::Build::MSYS>. This plugin is intended instead for projects that use vanilla makefiles of
a specific type.
This plugin is for now distributed separately from L<Alien::Build>, but the intention is for it to soon become
a core plugin for L<Alien::Build>.
=head1 PROPERTIES
=head2 make_type
The make type needed by the L<alienfile> recipe:
=over 4
=item dmake
Sun's dmake.
=item gmake
GNU Make.
=item nmake
Microsoft's nmake. It comes with Visual C++.
=item umake
Any UNIX C<make> Usually either BSD or GNU Make.
=back
=head1 HELPERS
=head2 make
%{make}
This plugin may change the make helper used by your L<alienfile> recipe.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,234 @@
package Alien::Build::Plugin::Build::SearchDep;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Text::ParseWords qw( shellwords );
# ABSTRACT: Add dependencies to library and header search path
our $VERSION = '2.38'; # VERSION
has aliens => {};
has public_I => 0;
has public_l => 0;
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure' => 'Alien::Build::Plugin::Build::SearchDep' => '0.35');
$meta->add_requires('share' => 'Env::ShellWords' => 0.01);
if($self->public_I || $self->public_l)
{
$meta->add_requires('configure' => 'Alien::Build::Plugin::Build::SearchDep' => '0.53');
}
my @aliens;
if(ref($self->aliens) eq 'HASH')
{
@aliens = keys %{ $self->aliens };
$meta->add_requires('share' => $_ => $self->aliens->{$_}) for @aliens;
}
else
{
@aliens = ref $self->aliens ? @{ $self->aliens } : ($self->aliens);
$meta->add_requires('share' => $_ => 0) for @aliens;
}
$meta->around_hook(
build => sub {
my($orig, $build) = @_;
local $ENV{CFLAGS} = $ENV{CFLAGS};
local $ENV{CXXFLAGS} = $ENV{CXXFLAGS};
local $ENV{LDFLAGS} = $ENV{LDFLAGS};
tie my @CFLAGS, 'Env::ShellWords', 'CFLAGS';
tie my @CXXFLAGS, 'Env::ShellWords', 'CXXFLAGS';
tie my @LDFLAGS, 'Env::ShellWords', 'LDFLAGS';
my $cflags = $build->install_prop->{plugin_build_searchdep_cflags} = [];
my $ldflags = $build->install_prop->{plugin_build_searchdep_ldflags} = [];
my $libs = $build->install_prop->{plugin_build_searchdep_libs} = [];
foreach my $other (@aliens)
{
my $other_cflags;
my $other_libs;
if($other->install_type('share'))
{
$other_cflags = $other->cflags_static;
$other_libs = $other->libs_static;
}
else
{
$other_cflags = $other->cflags;
$other_libs = $other->libs;
}
unshift @$cflags, grep /^-I/, shellwords($other_cflags);
unshift @$ldflags, grep /^-L/, shellwords($other_libs);
unshift @$libs, grep /^-l/, shellwords($other_libs);
}
unshift @CFLAGS, @$cflags;
unshift @CXXFLAGS, @$cflags;
unshift @LDFLAGS, @$ldflags;
$orig->($build);
},
);
$meta->after_hook(
gather_share => sub {
my($build) = @_;
$build->runtime_prop->{libs} = '' unless defined $build->runtime_prop->{libs};
$build->runtime_prop->{libs_static} = '' unless defined $build->runtime_prop->{libs_static};
if($self->public_l)
{
$build->runtime_prop->{$_} = join(' ', _space_escape(@{ $build->install_prop->{plugin_build_searchdep_libs} })) . ' ' . $build->runtime_prop->{$_}
for qw( libs libs_static );
}
$build->runtime_prop->{$_} = join(' ', _space_escape(@{ $build->install_prop->{plugin_build_searchdep_ldflags} })) . ' ' . $build->runtime_prop->{$_}
for qw( libs libs_static );
if($self->public_I)
{
$build->runtime_prop->{cflags} = '' unless defined $build->runtime_prop->{cflags};
$build->runtime_prop->{cflags_static} = '' unless defined $build->runtime_prop->{cflags_static};
$build->runtime_prop->{$_} = join(' ', _space_escape(@{ $build->install_prop->{plugin_build_searchdep_cflags} })) . ' ' . $build->runtime_prop->{$_}
for qw( cflags cflags_static );
}
},
);
}
sub _space_escape
{
map {
my $str = $_;
$str =~ s{(\s)}{\\$1}g;
$str;
} @_;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Build::SearchDep - Add dependencies to library and header search path
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Build::SearchDep' => (
aliens => [qw( Alien::Foo Alien::Bar )],
);
=head1 DESCRIPTION
This plugin adds the other aliens as prerequisites, and adds their header and library
search path to C<CFLAGS> and C<LDFLAGS> environment variable, so that tools that use
them (like autoconf) can pick them up.
=head1 PROPERTIES
=head2 aliens
Either a list reference or hash reference of the other aliens. If a hash reference
then the keys are the class names and the values are the versions of those classes.
=head2 public_I
Include the C<-I> flags when setting the runtime cflags property.
=head2 public_l
Include the C<-l> flags when setting the runtime libs property.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,109 @@
# PODNAME: Alien::Build::Plugin::Core
# ABSTRACT: Core Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core - Core Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# core plugins are already loaded
=head1 DESCRIPTION
Core plugins are special plugins that are always loaded, usually first.
=over 4
=item L<Alien::Build::Plugin::Core::Gather>
=item L<Alien::Build::Plugin::Core::Legacy>
Add interoperability with L<Alien::Base::ModuleBuild>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,139 @@
package Alien::Build::Plugin::Core::CleanInstall;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Path::Tiny ();
# ABSTRACT: Implementation for clean_install hook.
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->default_hook(
clean_install => sub {
my($build) = @_;
my $root = Path::Tiny->new(
$build->runtime_prop->{prefix}
);
if(-d $root)
{
foreach my $child ($root->children)
{
if($child->basename eq '_alien')
{
$build->log("keeping $child");
}
else
{
$build->log("removing $child");
$child->remove_tree({ safe => 0});
}
}
}
}
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::CleanInstall - Implementation for clean_install hook.
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin implements the default C<clean_install> hook.
You shouldn't use it directly.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,211 @@
package Alien::Build::Plugin::Core::Download;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Path::Tiny ();
use Alien::Build::Util qw( _mirror );
# ABSTRACT: Core download plugin
our $VERSION = '2.38'; # VERSION
sub _hook
{
my($build) = @_;
my $res = $build->fetch;
if($res->{type} =~ /^(?:html|dir_listing)$/)
{
my $type = $res->{type};
$type =~ s/_/ /;
$build->log("decoding $type");
$res = $build->decode($res);
}
if($res->{type} eq 'list')
{
$res = $build->prefer($res);
die "no matching files in listing" if @{ $res->{list} } == 0;
my $version = $res->{list}->[0]->{version};
my($pick, @other) = map { $_->{url} } @{ $res->{list} };
if(@other > 8)
{
splice @other, 7;
push @other, '...';
}
$build->log("candidate *$pick");
$build->log("candidate $_") for @other;
$res = $build->fetch($pick);
if($version)
{
$version =~ s/\.+$//;
$build->log("setting version based on archive to $version");
$build->runtime_prop->{version} = $version;
}
}
if($res->{type} eq 'file')
{
my $alienfile = $res->{filename};
$build->log("downloaded $alienfile");
if($res->{content})
{
my $tmp = Alien::Build::TempDir->new($build, "download");
my $path = Path::Tiny->new("$tmp/$alienfile");
$path->spew_raw($res->{content});
$build->install_prop->{download} = $path->stringify;
$build->install_prop->{complete}->{download} = 1;
return $build;
}
elsif($res->{path})
{
if(defined $res->{tmp} && !$res->{tmp})
{
if(-e $res->{path})
{
$build->install_prop->{download} = $res->{path};
$build->install_prop->{complete}->{download} = 1;
}
else
{
die "not a file or directory: @{[ $res->{path} ]}";
}
}
else
{
my $from = Path::Tiny->new($res->{path});
my $tmp = Alien::Build::TempDir->new($build, "download");
my $to = Path::Tiny->new("$tmp/@{[ $from->basename ]}");
if(-d $res->{path})
{
# Please note: _mirror and Alien::Build::Util are ONLY
# allowed to be used by core plugins. If you are writing
# a non-core plugin it may be removed. That is why it
# is private.
_mirror $from, $to;
}
else
{
require File::Copy;
File::Copy::copy(
"$from" => "$to",
) || die "copy $from => $to failed: $!";
}
$build->install_prop->{download} = $to->stringify;
$build->install_prop->{complete}->{download} = 1;
}
return $build;
}
die "file without content or path";
}
die "unknown fetch response type: @{[ $res->{type} ]}";
}
sub init
{
my($self, $meta) = @_;
$meta->default_hook(download => \&_hook);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::Download - Core download plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin does some core download logic.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,121 @@
package Alien::Build::Plugin::Core::FFI;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Core FFI plugin
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->default_hook(
$_ => sub {},
) for qw( build_ffi gather_ffi );
$meta->prop->{destdir_ffi_filter} = '^dynamic';
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::FFI - Core FFI plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin helps make the build_ffi work. You should not
need to interact with it directly.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,239 @@
package Alien::Build::Plugin::Core::Gather;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Env qw( @PATH @PKG_CONFIG_PATH );
use Path::Tiny ();
use File::chdir;
use Alien::Build::Util qw( _mirror _destdir_prefix );
use JSON::PP ();
# ABSTRACT: Core gather plugin
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->default_hook(
$_ => sub {},
) for qw( gather_system gather_share );
$meta->around_hook(
gather_share => sub {
my($orig, $build) = @_;
local $ENV{PATH} = $ENV{PATH};
local $ENV{PKG_CONFIG_PATH} = $ENV{PKG_CONFIG_PATH};
unshift @PATH, Path::Tiny->new('bin')->absolute->stringify
if -d 'bin';
for my $dir (qw(share lib)) {
unshift @PKG_CONFIG_PATH, Path::Tiny->new("$dir/pkgconfig")->absolute->stringify
if -d "$dir/pkgconfig";
}
$orig->($build)
}
);
foreach my $type (qw( share ffi ))
{
$meta->around_hook(
"gather_$type" => sub {
my($orig, $build) = @_;
if($build->meta_prop->{destdir})
{
my $destdir = $ENV{DESTDIR};
if(-d $destdir)
{
my $src = Path::Tiny->new(_destdir_prefix($ENV{DESTDIR}, $build->install_prop->{prefix}));
my $dst = Path::Tiny->new($build->install_prop->{stage});
my $res = do {
local $CWD = "$src";
$orig->($build);
};
$build->log("mirror $src => $dst");
$dst->mkpath;
# Please note: _mirror and Alien::Build::Util are ONLY
# allowed to be used by core plugins. If you are writing
# a non-core plugin it may be removed. That is why it
# is private.
_mirror("$src", "$dst", {
verbose => 1,
filter => $build->meta_prop->{$type eq 'share' ? 'destdir_filter' : 'destdir_ffi_filter'},
});
return $res;
}
else
{
die "nothing was installed into destdir" if $type eq 'share';
}
}
else
{
local $CWD = $build->install_prop->{stage};
my $ret = $orig->($build);
# if we are not doing a double staged install we want to substitute the install
# prefix with the runtime prefix.
my $old = $build->install_prop->{prefix};
my $new = $build->runtime_prop->{prefix};
foreach my $flag (qw( cflags cflags_static libs libs_static ))
{
next unless defined $build->runtime_prop->{$flag};
$build->runtime_prop->{$flag} =~ s{(-I|-L|-LIBPATH:)\Q$old\E}{$1 . $new}eg;
}
return $ret;
}
}
);
}
$meta->after_hook(
$_ => sub {
my($build) = @_;
die "stage is not defined. be sure to call set_stage on your Alien::Build instance"
unless $build->install_prop->{stage};
my $stage = Path::Tiny->new($build->install_prop->{stage});
$build->log("mkdir -p $stage/_alien");
$stage->child('_alien')->mkpath;
# drop a alien.json file for the runtime properties
$stage->child('_alien/alien.json')->spew(
JSON::PP->new->pretty->canonical(1)->ascii->encode($build->runtime_prop)
);
# copy the alienfile, if we managed to keep it around.
if($build->meta->filename &&
-r $build->meta->filename &&
$build->meta->filename !~ /\.(pm|pl)$/ &&
! -d $build->meta->filename)
{
Path::Tiny->new($build->meta->filename)
->copy($stage->child('_alien/alienfile'));
}
if($build->install_prop->{patch} && -d $build->install_prop->{patch})
{
# Please note: _mirror and Alien::Build::Util are ONLY
# allowed to be used by core plugins. If you are writing
# a non-core plugin it may be removed. That is why it
# is private.
_mirror($build->install_prop->{patch},
$stage->child('_alien/patch')->stringify);
}
},
) for qw( gather_share gather_system );
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::Gather - Core gather plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin helps make the gather stage work.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,139 @@
package Alien::Build::Plugin::Core::Legacy;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Core Alien::Build plugin to maintain compatibility with legacy Alien::Base
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->after_hook(
$_ => sub {
my($build) = @_;
$build->log("adding legacy hash to config");
my $runtime = $build->runtime_prop;
if($runtime->{cflags} && ! defined $runtime->{cflags_static})
{
$runtime->{cflags_static} = $runtime->{cflags};
}
if($runtime->{libs} && ! defined $runtime->{libs_static})
{
$runtime->{libs_static} = $runtime->{libs};
}
$runtime->{legacy}->{finished_installing} = 1;
$runtime->{legacy}->{install_type} = $runtime->{install_type};
$runtime->{legacy}->{version} = $runtime->{version};
$runtime->{legacy}->{original_prefix} = $runtime->{prefix};
}
) for qw( gather_system gather_share );
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::Legacy - Core Alien::Build plugin to maintain compatibility with legacy Alien::Base
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin provides some compatibility with the legacy L<Alien::Build::ModuleBuild>
interfaces.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,120 @@
package Alien::Build::Plugin::Core::Override;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Core override plugin
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->default_hook(
override => sub {
my($build) = @_;
return $ENV{ALIEN_INSTALL_TYPE} || '';
},
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::Override - Core override plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin implements the C<ALIEN_INSTALL_TYPE> environment variable.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,170 @@
package Alien::Build::Plugin::Core::Setup;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Config;
use File::Which qw( which );
# ABSTRACT: Core setup plugin
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->prop->{platform} ||= {};
$self->_platform($meta->prop->{platform});
}
sub _platform
{
my(undef, $hash) = @_;
if($^O eq 'MSWin32' && $Config{ccname} eq 'cl')
{
$hash->{compiler_type} = 'microsoft';
}
else
{
$hash->{compiler_type} = 'unix';
}
if($^O eq 'MSWin32')
{
$hash->{system_type} = 'windows-unknown';
if(defined &Win32::BuildNumber)
{
$hash->{system_type} = 'windows-activestate';
}
elsif($Config{myuname} =~ /strawberry-perl/)
{
$hash->{system_type} = 'windows-strawberry';
}
elsif($hash->{compiler_type} eq 'microsoft')
{
$hash->{system_type} = 'windows-microsoft';
}
else
{
my $uname_exe = which('uname');
if($uname_exe)
{
my $uname = `$uname_exe`;
if($uname =~ /^(MINGW)(32|64)_NT/)
{
$hash->{system_type} = 'windows-' . lc $1;
}
}
}
}
elsif($^O =~ /^(VMS)$/)
{
# others probably belong in here...
$hash->{system_type} = lc $^O;
}
else
{
$hash->{system_type} = 'unix';
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::Setup - Core setup plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin does some core setup for you.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,118 @@
package Alien::Build::Plugin::Core::Tail;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Core tail setup plugin
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
if($meta->prop->{out_of_source})
{
$meta->add_requires('configure' => 'Alien::Build' => '1.08');
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Core::Tail - Core tail setup plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
# already loaded
=head1 DESCRIPTION
This plugin does some core tail setup for you.
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Base::ModuleBuild>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,112 @@
# PODNAME: Alien::Build::Plugin::Decode
# ABSTRACT: Decode Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Decode - Decode Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Decode::HTML';
plugin 'Decode::DirListing';
=head1 DESCRIPTION
Decode plugins decode HTML and FTP file listings. Normally you
will want to use the L<Alien::Build::Plugin::Download::Negotiate>
plugin which will automatically load the appropriate Decode plugins.
=over 4
=item L<Alien::Build::Plugin::Decode::HTML>
=item L<Alien::Build::Plugin::Decode::DirListing>
=item L<Alien::Build::Plugin::Decode::DirListingFtpcopy>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,149 @@
package Alien::Build::Plugin::Decode::DirListing;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Basename ();
# ABSTRACT: Plugin to extract links from a directory listing
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'File::Listing' => 0);
$meta->add_requires('share' => 'URI' => 0);
$meta->register_hook( decode => sub {
my(undef, $res) = @_;
die "do not know how to decode @{[ $res->{type} ]}"
unless $res->{type} eq 'dir_listing';
my $base = URI->new($res->{base});
return {
type => 'list',
list => [
map {
my($name) = @$_;
my $basename = $name;
$basename =~ s{/$}{};
my %h = (
filename => File::Basename::basename($basename),
url => URI->new_abs($name, $base)->as_string,
);
\%h;
} File::Listing::parse_dir($res->{content})
],
};
});
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Decode::DirListing - Plugin to extract links from a directory listing
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Decode::DirListing';
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate decode plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin decodes a ftp file listing into a list of candidates for your Prefer plugin.
It is useful when fetching from an FTP server via L<Alien::Build::Plugin::Fetch::LWP>.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build::Plugin::Decode::DirListingFtpcopy>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,154 @@
package Alien::Build::Plugin::Decode::DirListingFtpcopy;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Basename ();
# ABSTRACT: Plugin to extract links from a directory listing using ftpcopy
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'File::Listing::Ftpcopy' => 0);
$meta->add_requires('share' => 'URI' => 0);
$meta->register_hook( decode => sub {
my(undef, $res) = @_;
die "do not know how to decode @{[ $res->{type} ]}"
unless $res->{type} eq 'dir_listing';
my $base = URI->new($res->{base});
return {
type => 'list',
list => [
map {
my($name) = @$_;
my $basename = $name;
$basename =~ s{/$}{};
my %h = (
filename => File::Basename::basename($basename),
url => URI->new_abs($name, $base)->as_string,
);
\%h;
} File::Listing::Ftpcopy::parse_dir($res->{content})
],
};
});
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Decode::DirListingFtpcopy - Plugin to extract links from a directory listing using ftpcopy
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Decode::DirListingFtpcopy';
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate decode plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin decodes a ftp file listing into a list of candidates for your Prefer plugin.
It is useful when fetching from an FTP server via L<Alien::Build::Plugin::Fetch::LWP>.
It is different from the similarly named L<Alien::Build::Plugin::Decode::DirListingFtpcopy>
in that it uses L<File::Listing::Ftpcopy> instead of L<File::Listing>. The rationale for
the C<Ftpcopy> version is that it supports a different set of FTP servers, including
OpenVMS. In most cases, however, you probably want to use the non C<Ftpcopy> version
since it is pure perl.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build::Plugin::Decode::DirListing>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,162 @@
package Alien::Build::Plugin::Decode::HTML;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Basename ();
# ABSTRACT: Plugin to extract links from HTML
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'HTML::LinkExtor' => 0);
$meta->add_requires('share' => 'URI' => 0);
$meta->add_requires('share' => 'URI::Escape' => 0);
$meta->register_hook( decode => sub {
my(undef, $res) = @_;
die "do not know how to decode @{[ $res->{type} ]}"
unless $res->{type} eq 'html';
my $base = URI->new($res->{base});
my @list;
my $p = HTML::LinkExtor->new(sub {
my($tag, %links) = @_;
if($tag eq 'base' && $links{href})
{
$base = URI->new($links{href});
}
elsif($tag eq 'a' && $links{href})
{
my $href = $links{href};
return if $href =~ m!^\.\.?/?$!;
my $url = URI->new_abs($href, $base);
my $path = $url->path;
$path =~ s{/$}{}; # work around for Perl 5.8.7- gh#8
push @list, {
filename => URI::Escape::uri_unescape(File::Basename::basename($path)),
url => URI::Escape::uri_unescape($url->as_string),
};
}
});
$p->parse($res->{content});
return {
type => 'list',
list => \@list,
};
});
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Decode::HTML - Plugin to extract links from HTML
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Decode::HTML';
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate decode plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin decodes an HTML file listing into a list of candidates for your Prefer plugin.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,209 @@
package Alien::Build::Plugin::Decode::Mojo;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Plugin to extract links from HTML using Mojo::DOM or Mojo::DOM58
our $VERSION = '2.38'; # VERSION
sub _load ($;$)
{
my($class, $version) = @_;
my $pm = "$class.pm";
$pm =~ s/::/\//g;
eval { require $pm };
return 0 if $@;
if(defined $version)
{
eval { $class->VERSION($version) };
return 0 if $@;
}
return 1;
}
has _class => sub {
return 'Mojo::DOM58' if _load 'Mojo::DOM58';
return 'Mojo::DOM' if _load 'Mojo::DOM' and _load 'Mojolicious', 7.00;
return 'Mojo::DOM58';
};
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'URI' => 0);
$meta->add_requires('share' => 'URI::Escape' => 0);
my $class = $meta->prop->{plugin_decode_mojo_class} ||= $self->_class;
if($class eq 'Mojo::DOM58')
{
$meta->add_requires('share' => 'Mojo::DOM58' => '1.00');
}
elsif($class eq 'Mojo::DOM')
{
$meta->add_requires('share' => 'Mojolicious' => '7.00');
$meta->add_requires('share' => 'Mojo::DOM' => '0');
}
else
{
die "bad class";
}
$meta->register_hook( decode => sub {
my(undef, $res) = @_;
die "do not know how to decode @{[ $res->{type} ]}"
unless $res->{type} eq 'html';
my $dom = $class->new($res->{content});
my $base = URI->new($res->{base});
if(my $base_element = $dom->find('head base')->first)
{
my $href = $base_element->attr('href');
$base = URI->new($href) if defined $href;
}
my @list = map {
my $url = URI->new_abs($_, $base);
my $path = $url->path;
$path =~ s{/$}{}; # work around for Perl 5.8.7- gh#8
{
filename => URI::Escape::uri_unescape(File::Basename::basename($path)),
url => URI::Escape::uri_unescape($url->as_string),
}
}
grep !/^\.\.?\/?$/,
map { $_->attr('href') || () }
@{ $dom->find('a')->to_array };
return {
type => 'list',
list => \@list,
};
})
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Decode::Mojo - Plugin to extract links from HTML using Mojo::DOM or Mojo::DOM58
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Decode::Mojo';
Force using C<Decode::Mojo> via the download negotiator:
use alienfile 1.68;
configure {
requires 'Alien::Build::Plugin::Decode::Mojo';
};
plugin 'Download' => (
...
decoder => 'Decode::Mojo',
);
=head1 DESCRIPTION
Note: in most cases you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate decode plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin decodes an HTML file listing into a list of candidates for your Prefer plugin.
It works just like L<Alien::Build::Plugin::Decode::HTML> except it uses either L<Mojo::DOM>
or L<Mojo::DOM58> to do its job.
This plugin is much lighter than The C<Decode::HTML> plugin, and doesn't require XS. It
is the default decode plugin used by L<Alien::Build::Plugin::Download::Negotiate> if it
detects that you need to parse an HTML index.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,108 @@
# PODNAME: Alien::Build::Plugin::Download
# ABSTRACT: Download Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Download - Download Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile
share {
start_url 'http://ftp.gnu.org/gnu/make';
plugin 'Download';
};
=head1 DESCRIPTION
Download plugins download packages from the internet.
=over 4
=item L<Alien::Build::Plugin::Download::Negotiate>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,377 @@
package Alien::Build::Plugin::Download::Negotiate;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Alien::Build::Util qw( _has_ssl );
use Carp ();
# ABSTRACT: Download negotiation plugin
our $VERSION = '2.38'; # VERSION
has '+url' => undef;
has 'filter' => undef;
has 'version' => undef;
has 'ssl' => 0;
has 'passive' => 0;
has 'scheme' => undef;
has 'bootstrap_ssl' => 0;
has 'prefer' => 1;
has 'decoder' => undef;
sub pick
{
my($self) = @_;
my($fetch, @decoders) = $self->_pick;
if($self->decoder)
{
@decoders = ref $self->decoder ? @{ $self->decoder } : ($self->decoder);
}
($fetch, @decoders);
}
sub _pick_decoder
{
my($self) = @_;
if(eval { require Mojo::DOM58; Mojo::DOM58->VERSION(1.00); 1 })
{ return "Decode::Mojo" }
elsif(eval { require Mojo::DOM; require Mojolicious; Mojolicious->VERSION('7.00'); 1 })
{ return "Decode::Mojo" }
elsif(eval { require HTML::LinkExtor; 1; })
{ return "Decode::HTML" }
else
{ return "Decode::Mojo" }
}
sub _pick
{
my($self) = @_;
$self->scheme(
$self->url !~ m!(ftps?|https?|file):!i
? 'file'
: $self->url =~ m!^([a-z]+):!i
) unless defined $self->scheme;
if($self->scheme eq 'https' || ($self->scheme eq 'http' && $self->ssl))
{
if($self->bootstrap_ssl && ! _has_ssl)
{
return (['Fetch::CurlCommand','Fetch::Wget'], __PACKAGE__->_pick_decoder);
}
elsif(_has_ssl)
{
return ('Fetch::HTTPTiny', __PACKAGE__->_pick_decoder);
}
elsif(do { require Alien::Build::Plugin::Fetch::CurlCommand; Alien::Build::Plugin::Fetch::CurlCommand->protocol_ok('https') })
{
return ('Fetch::CurlCommand', __PACKAGE__->_pick_decoder);
}
else
{
return ('Fetch::HTTPTiny', __PACKAGE__->_pick_decoder);
}
}
elsif($self->scheme eq 'http')
{
return ('Fetch::HTTPTiny', __PACKAGE__->_pick_decoder);
}
elsif($self->scheme eq 'ftp')
{
if($ENV{ftp_proxy} || $ENV{all_proxy})
{
return $self->scheme =~ /^ftps?/
? ('Fetch::LWP', 'Decode::DirListing', __PACKAGE__->_pick_decoder)
: ('Fetch::LWP', __PACKAGE__->_pick_decoder);
}
else
{
return ('Fetch::NetFTP');
}
}
elsif($self->scheme eq 'file')
{
return ('Fetch::Local');
}
else
{
die "do not know how to handle scheme @{[ $self->scheme ]} for @{[ $self->url ]}";
}
}
sub init
{
my($self, $meta) = @_;
unless(defined $self->url)
{
if(defined $meta->prop->{start_url})
{
$self->url($meta->prop->{start_url});
}
else
{
Carp::croak "url is a required property unless you use the start_url directive";
}
}
$meta->add_requires('share' => 'Alien::Build::Plugin::Download::Negotiate' => '0.61')
if $self->passive;
$meta->prop->{plugin_download_negotiate_default_url} = $self->url;
my($fetch, @decoders) = $self->pick;
$fetch = [ $fetch ] unless ref $fetch;
foreach my $fetch (@$fetch)
{
my @args;
push @args, ssl => $self->ssl;
# For historical reasons, we pass the URL into older fetch plugins, because
# this used to be the interface. Using start_url is now preferred!
push @args, url => $self->url if $fetch =~ /^Fetch::(HTTPTiny|LWP|Local|LocalDir|NetFTP|CurlCommand)$/;
push @args, passive => $self->passive if $fetch eq 'Fetch::NetFTP';
push @args, bootstrap_ssl => $self->bootstrap_ssl if $self->bootstrap_ssl;
$meta->apply_plugin($fetch, @args);
}
if($self->version)
{
$meta->apply_plugin($_) for @decoders;
if(defined $self->prefer && ref($self->prefer) eq 'CODE')
{
$meta->add_requires('share' => 'Alien::Build::Plugin::Download::Negotiate' => '1.30');
$meta->register_hook(
prefer => $self->prefer,
);
}
elsif($self->prefer)
{
$meta->apply_plugin('Prefer::SortVersions',
(defined $self->filter ? (filter => $self->filter) : ()),
version => $self->version,
);
}
else
{
$meta->add_requires('share' => 'Alien::Build::Plugin::Download::Negotiate' => '1.30');
}
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Download::Negotiate - Download negotiation plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'http://ftp.gnu.org/gnu/make';
plugin 'Download' => (
filter => qr/^make-.*\.tar\.gz$/,
version => qr/([0-9\.]+)/,
);
};
=head1 DESCRIPTION
This is a negotiator plugin for downloading packages from the internet. This
plugin picks the best Fetch, Decode and Prefer plugins to do the actual work.
Which plugins are picked depend on the properties you specify, your platform
and environment. It is usually preferable to use a negotiator plugin rather
than the Fetch, Decode and Prefer plugins directly from your L<alienfile>.
=head1 PROPERTIES
=head2 url
[DEPRECATED] use C<start_url> instead.
The Initial URL for your package. This may be a directory listing (either in
HTML or ftp listing format) or the final tarball intended to be downloaded.
=head2 filter
This is a regular expression that lets you filter out files that you do not
want to consider downloading. For example, if the directory listing contained
tarballs and readme files like this:
foo-1.0.0.tar.gz
foo-1.0.0.readme
You could specify a filter of C<qr/\.tar\.gz$/> to make sure only tarballs are
considered for download.
=head2 version
Regular expression to parse out the version from a filename. The regular expression
should store the result in C<$1>.
Note: if you provide a C<version> property, this plugin will assume that you will
be downloading an initial index to select package downloads from. Depending on
the protocol (and typically this is the case for http and HTML) that may bring in
additional dependencies. If start_url points to a tarball or other archive directly
(without needing to do through an index selection process), it is recommended that
you not specify this property.
=head2 ssl
If your initial URL does not need SSL, but you know ahead of time that a subsequent
request will need it (for example, if your directory listing is on C<http>, but includes
links to C<https> URLs), then you can set this property to true, and the appropriate
Perl SSL modules will be loaded.
=head2 passive
If using FTP, attempt a passive mode transfer first, before trying an active mode transfer.
=head2 bootstrap_ssl
If set to true, then the download negotiator will avoid using plugins that have a dependency
on L<Net::SSLeay>, or other Perl SSL modules. The intent for this option is to allow
OpenSSL to be alienized and be a useful optional dependency for L<Net::SSLeay>.
The implementation may improve over time, but as of this writing, this option relies on you
having a working C<curl> or C<wget> with SSL support in your C<PATH>.
=head2 prefer
How to sort candidates for selection. This should be one of three types of values:
=over 4
=item code reference
This will be used as the prefer hook.
=item true value
Use L<Alien::Build::Plugin::Prefer::SortVersions>.
=item false value
Don't set any preference at all. A hook must be installed, or another prefer plugin specified.
=back
=head2 decoder
Override the detected decoder.
=head1 METHODS
=head2 pick
my($fetch, @decoders) = $plugin->pick;
Returns the fetch plugin and any optional decoders that should be used.
=head1 SEE ALSO
L<Alien::Build::Plugin::Prefer::BadVersion>, L<Alien::Build::Plugin::Prefer::GoodVersion>
L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,118 @@
# PODNAME: Alien::Build::Plugin::Extract
# ABSTRACT: Extract Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Extract - Extract Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile
share {
plugin 'Extract' => 'tar.gz';
};
=head1 DESCRIPTION
Extract plugins extract packages that have been downloaded from the internet.
Unless you are doing something unusual you will likely want to use the
L<Alien::Build::Plugin::Extract::Negotiate> plugin to select the best
Extract plugin available.
=over 4
=item L<Alien::Build::Plugin::Extract::ArchiveTar>
=item L<Alien::Build::Plugin::Extract::ArchiveZip>
=item L<Alien::Build::Plugin::Extract::CommandLine>
=item L<Alien::Build::Plugin::Extract::Directory>
=item L<Alien::Build::Plugin::Extract::Negotiate>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,218 @@
package Alien::Build::Plugin::Extract::ArchiveTar;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::chdir;
use File::Temp ();
use Path::Tiny ();
# ABSTRACT: Plugin to extract a tarball using Archive::Tar
our $VERSION = '2.38'; # VERSION
has '+format' => 'tar';
sub handles
{
my(undef, $ext) = @_;
return 1 if $ext =~ /^(tar|tar.gz|tar.bz2|tbz|taz)$/;
return 0;
}
sub available
{
my(undef, $ext) = @_;
if($ext eq 'tar.gz')
{
return !! eval { require Archive::Tar; Archive::Tar->has_zlib_support };
}
elsif($ext eq 'tar.bz2')
{
return !! eval { require Archive::Tar; Archive::Tar->has_bzip2_support && __PACKAGE__->_can_bz2 };
}
else
{
return $ext eq 'tar';
}
}
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'Archive::Tar' => 0);
if($self->format eq 'tar.gz' || $self->format eq 'tgz')
{
$meta->add_requires('share' => 'IO::Zlib' => 0);
}
elsif($self->format eq 'tar.bz2' || $self->format eq 'tbz')
{
$meta->add_requires('share' => 'IO::Uncompress::Bunzip2' => 0);
$meta->add_requires('share' => 'IO::Compress::Bzip2' => 0);
}
$meta->register_hook(
extract => sub {
my($build, $src) = @_;
my $tar = Archive::Tar->new;
$tar->read($src);
$tar->extract;
}
);
}
sub _can_bz2
{
# even when Archive::Tar reports that it supports bz2, I can sometimes get this error:
# 'Cannot read enough bytes from the tarfile', so lets just probe for actual support!
my $dir = Path::Tiny->new(File::Temp::tempdir( CLEANUP => 1 ));
eval {
local $CWD = $dir;
my $tarball = unpack "u", q{M0EIH.3%!62936=+(]$0``$A[D-$0`8!``7^``!!AI)Y`!```""``=!JGIH-(MT#0]0/2!**---&F@;4#0&:D;X?(6@JH(2<%'N$%3VHC-9E>S/N@"6&I*1@GNJNHCC2>$I5(<0BKR.=XBZ""HVZ;T,CV\LJ!K&*?9`#\7<D4X4)#2R/1$`};
Path::Tiny->new('xx.tar.bz2')->spew_raw($tarball);
require Archive::Tar;
my $tar = Archive::Tar->new;
$tar->read('xx.tar.bz2');
$tar->extract;
my $content = Path::Tiny->new('xx.txt')->slurp;
die unless $content && $content eq "xx\n";
};
my $error = $@;
$dir->remove_tree;
!$error;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Extract::ArchiveTar - Plugin to extract a tarball using Archive::Tar
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Extract::ArchiveTar' => (
format => 'tar.gz',
);
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Extract::Negotiate>
instead. It picks the appropriate Extract plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin extracts from an archive in tarball format (optionally compressed by either
gzip or bzip2) using L<Archive::Tar>.
=head1 PROPERTIES
=head2 format
Gives a hint as to the expected format. This helps make sure the prerequisites are set
correctly, since compressed archives require extra Perl modules to be installed.
=head1 METHODS
=head2 handles
Alien::Build::Plugin::Extract::ArchiveTar->handles($ext);
$plugin->handles($ext);
Returns true if the plugin is able to handle the archive of the
given format.
=head2 available
Alien::Build::Plugin::Extract::ArchiveTar->available($ext);
Returns true if the plugin has what it needs right now to extract from the given format
=head1 SEE ALSO
L<Alien::Build::Plugin::Extract::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,174 @@
package Alien::Build::Plugin::Extract::ArchiveZip;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Plugin to extract a tarball using Archive::Zip
our $VERSION = '2.38'; # VERSION
has '+format' => 'zip';
sub handles
{
my($class, $ext) = @_;
return 1 if $ext eq 'zip';
return 0;
}
sub available
{
my(undef, $ext) = @_;
!! ( $ext eq 'zip' && eval { require Archive::Zip; 1} );
}
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'Archive::Zip' => 0);
$meta->register_hook(
extract => sub {
my($build, $src) = @_;
my $zip = Archive::Zip->new;
$zip->read($src);
$zip->extractTree;
}
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Extract::ArchiveZip - Plugin to extract a tarball using Archive::Zip
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Extract::ArchiveZip' => (
format => 'zip',
);
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Extract::Negotiate>
instead. It picks the appropriate Extract plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
B<Note>: Seriously do NOT use this plugin! L<Archive::Zip> is pretty unreliable and
breaks all-the-time. If you use the negotiator plugin mentioned above, then it will
prefer installing L<Alien::unzip>, which is much more reliable than L<Archive::Zip>.
This plugin extracts from an archive in zip format using L<Archive::Zip>.
=head2 format
Gives a hint as to the expected format. This should always be C<zip>.
=head1 METHODS
=head2 handles
Alien::Build::Plugin::Extract::ArchiveZip->handles($ext);
$plugin->handles($ext);
Returns true if the plugin is able to handle the archive of the
given format.
=head2 available
Alien::Build::Plugin::Extract::ArchiveZip->available($ext);
Returns true if the plugin has what it needs right now to extract from the given format
=head1 SEE ALSO
L<Alien::Build::Plugin::Extract::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,557 @@
package Alien::Build::Plugin::Extract::CommandLine;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Path::Tiny ();
use File::Which ();
use File::chdir;
use File::Temp qw( tempdir );
use Capture::Tiny qw( capture_merged );
# ABSTRACT: Plugin to extract an archive using command line tools
our $VERSION = '2.38'; # VERSION
has '+format' => 'tar';
sub gzip_cmd
{
_which('gzip') ? 'gzip' : undef;
}
sub _which { scalar File::Which::which(@_) }
sub bzip2_cmd
{
_which('bzip2') ? 'bzip2' : undef;
}
sub xz_cmd
{
_which('xz') ? 'xz' : undef;
}
{
my $bsd_tar;
# Note: GNU tar can be iffy to very bad on windows, where absolute
# paths get confused with remote tars. We used to assume that 'tar.exe'
# is borked on Windows, but recent versions of Windows 10 come bundled
# with bsdtar (libarchive) named 'tar.exe', and we should definitely
# prefer that to ptar.
sub _windows_tar_is_bsdtar
{
return 1 if $^O ne 'MSWin32';
return $bsd_tar if defined $bsd_tar;
my($out) = capture_merged {
system 'tar', '--version';
};
return $bsd_tar = $out =~ /bsdtar/ ? 1 : 0
}
}
sub tar_cmd
{
_which('bsdtar')
? 'bsdtar'
# Slowlaris /usr/bin/tar doesn't seem to like pax global header
# but seems to have gtar in the path by default, which is okay with it
: $^O eq 'solaris' && _which('gtar')
? 'gtar'
# See note above for Windows logic.
: _which('tar') && _windows_tar_is_bsdtar()
? 'tar'
: _which('ptar')
? 'ptar'
: undef;
};
sub unzip_cmd
{
if($^O eq 'MSWin32' && _which('tar') && _windows_tar_is_bsdtar())
{
(_which('tar'), 'xf');
}
else
{
_which('unzip') ? 'unzip' : undef;
}
}
sub _run
{
my(undef, $build, @cmd) = @_;
$build->log("+ @cmd");
system @cmd;
die "execute failed" if $?;
}
sub _cp
{
my(undef, $build, $from, $to) = @_;
require File::Copy;
$build->log("copy $from => $to");
File::Copy::cp($from, $to) || die "unable to copy: $!";
}
sub _mv
{
my(undef, $build, $from, $to) = @_;
$build->log("move $from => $to");
rename($from, $to) || die "unable to rename: $!";
}
sub _dcon
{
my($self, $src) = @_;
my $name;
my $cmd;
if($src =~ /\.(gz|tgz|Z|taz)$/)
{
$self->gzip_cmd(_which('gzip')) unless defined $self->gzip_cmd;
if($src =~ /\.(gz|tgz)$/)
{
$cmd = $self->gzip_cmd unless $self->_tar_can('tar.gz');
}
elsif($src =~ /\.(Z|taz)$/)
{
$cmd = $self->gzip_cmd unless $self->_tar_can('tar.Z');
}
}
elsif($src =~ /\.(bz2|tbz)$/)
{
$self->bzip2_cmd(_which('bzip2')) unless defined $self->bzip2_cmd;
$cmd = $self->bzip2_cmd unless $self->_tar_can('tar.bz2');
}
elsif($src =~ /\.(xz|txz)$/)
{
$self->xz_cmd(_which('xz')) unless defined $self->xz_cmd;
$cmd = $self->xz_cmd unless $self->_tar_can('tar.xz');
}
if($cmd && $src =~ /\.(gz|bz2|xz|Z)$/)
{
$name = $src;
$name =~ s/\.(gz|bz2|xz|Z)$//g;
}
elsif($cmd && $src =~ /\.(tgz|tbz|txz|taz)$/)
{
$name = $src;
$name =~ s/\.(tgz|tbz|txz|taz)$/.tar/;
}
($name,$cmd);
}
sub handles
{
my($class, $ext) = @_;
my $self = ref $class
? $class
: __PACKAGE__->new;
$ext = 'tar.Z' if $ext eq 'taz';
$ext = 'tar.gz' if $ext eq 'tgz';
$ext = 'tar.bz2' if $ext eq 'tbz';
$ext = 'tar.xz' if $ext eq 'txz';
return 1 if $ext eq 'tar.gz' && $self->_tar_can('tar.gz');
return 1 if $ext eq 'tar.Z' && $self->_tar_can('tar.Z');
return 1 if $ext eq 'tar.bz2' && $self->_tar_can('tar.bz2');
return 1 if $ext eq 'tar.xz' && $self->_tar_can('tar.xz');
return 0 if $ext =~ s/\.(gz|Z)$// && (!$self->gzip_cmd);
return 0 if $ext =~ s/\.bz2$// && (!$self->bzip2_cmd);
return 0 if $ext =~ s/\.xz$// && (!$self->xz_cmd);
return 1 if $ext eq 'tar' && $self->_tar_can('tar');
return 1 if $ext eq 'zip' && $self->_tar_can('zip');
return 0;
}
sub available
{
my(undef, $ext) = @_;
# this is actually the same as handles
__PACKAGE__->handles($ext);
}
sub init
{
my($self, $meta) = @_;
if($self->format eq 'tar.xz' && !$self->handles('tar.xz'))
{
$meta->add_requires('share' => 'Alien::xz' => '0.06');
}
elsif($self->format eq 'tar.bz2' && !$self->handles('tar.bz2'))
{
$meta->add_requires('share' => 'Alien::Libbz2' => '0.22');
}
elsif($self->format =~ /^tar\.(gz|Z)$/ && !$self->handles($self->format))
{
$meta->add_requires('share' => 'Alien::gzip' => '0.03');
}
elsif($self->format eq 'zip' && !$self->handles('zip'))
{
$meta->add_requires('share' => 'Alien::unzip' => '0');
}
$meta->register_hook(
extract => sub {
my($build, $src) = @_;
my($dcon_name, $dcon_cmd) = _dcon($self, $src);
if($dcon_name)
{
unless($dcon_cmd)
{
die "unable to decompress $src";
}
# if we have already decompressed, then keep it.
unless(-f $dcon_name)
{
# we don't use pipes, because that may not work on Windows.
# keep the original archive, in case another extract
# plugin needs it. keep the decompressed archive
# in case WE need it again.
my $src_tmp = Path::Tiny::path($src)
->parent
->child('x'.Path::Tiny::path($src)->basename);
my $dcon_tmp = Path::Tiny::path($dcon_name)
->parent
->child('x'.Path::Tiny::path($dcon_name)->basename);
$self->_cp($build, $src, $src_tmp);
$self->_run($build, $dcon_cmd, "-d", $src_tmp);
$self->_mv($build, $dcon_tmp, $dcon_name);
}
$src = $dcon_name;
}
if($src =~ /\.zip$/i)
{
$self->_run($build, $self->unzip_cmd, $src);
}
elsif($src =~ /\.tar/ || $src =~ /(\.tgz|\.tbz|\.txz|\.taz)$/i)
{
$self->_run($build, $self->tar_cmd, '-xf', $src);
}
else
{
die "not sure of archive type from extension";
}
}
);
}
my %tars;
sub _tar_can
{
my($self, $ext) = @_;
unless(%tars)
{
my $name = '';
local $_; # to avoid dynamically scoped read-only $_ from upper scopes
while(my $line = <DATA>)
{
if($line =~ /^\[ (.*) \]$/)
{
$name = $1;
}
else
{
$tars{$name} .= $line;
}
}
foreach my $key (keys %tars)
{
$tars{$key} = unpack "u", $tars{$key};
}
}
my $name = "xx.$ext";
return 0 unless $tars{$name};
local $CWD = tempdir( CLEANUP => 1 );
my $cleanup = sub {
my $save = $CWD;
unlink $name;
unlink 'xx.txt';
$CWD = '..';
rmdir $save;
};
Path::Tiny->new($name)->spew_raw($tars{$name});
my @cmd = ($self->tar_cmd, 'xf', $name);
if($ext eq 'zip')
{
@cmd = ($self->unzip_cmd, $name);
}
my(undef, $exit) = capture_merged {
system(@cmd);
$?;
};
if($exit)
{
$cleanup->();
return 0;
}
my $content = eval { Path::Tiny->new('xx.txt')->slurp };
$cleanup->();
return defined $content && $content eq "xx\n";
}
1;
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Extract::CommandLine - Plugin to extract an archive using command line tools
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Extract::CommandLine' => (
format => 'tar.gz',
);
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Extract::Negotiate>
instead. It picks the appropriate Extract plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin extracts from an archive in various formats using command line tools.
=head1 PROPERTIES
=head2 format
Gives a hint as to the expected format.
=head2 gzip_cmd
The C<gzip> command, if available. C<undef> if not available.
=head2 bzip2_cmd
The C<bzip2> command, if available. C<undef> if not available.
=head2 xz_cmd
The C<xz> command, if available. C<undef> if not available.
=head2 tar_cmd
The C<tar> command, if available. C<undef> if not available.
=head2 unzip_cmd
The C<unzip> command, if available. C<undef> if not available.
=head1 METHODS
=head2 handles
Alien::Build::Plugin::Extract::CommandLine->handles($ext);
$plugin->handles($ext);
Returns true if the plugin is able to handle the archive of the
given format.
=head2 available
Alien::Build::Plugin::Extract::CommandLine->available($ext);
Returns true if the plugin is available to extract without
installing anything new.
=head1 SEE ALSO
L<Alien::Build::Plugin::Extract::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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
__DATA__
[ xx.tar ]
M>'@N='AT````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````#`P,#8T-"``,#`P-S8U(``P,#`P,C0@`#`P,#`P,#`P,#`S
M(#$S-#,U,#0S-#(R(#`Q,C<P,P`@,```````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,&]L;&ES
M9P``````````````````````````````````<W1A9F8`````````````````
M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````!X>`H`````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
7````````````````````````````````
[ xx.tar.Z ]
M'YV0>/"XH(.'#H"#"!,J7,BPH<.'$"-*1`BCH@T:-$``J`CCAHT:&CG"D)%Q
MH\B3,T#$F$%C1@T8+6G(D`$"1@P9-V#,`%!SHL^?0(,*!5!G#ITP<DR^8<,F
MS9PS0Q<:#6/&3-2%)V&$/*GQJM>O8,.*'1I0P=BS:-.J7<NVK=NW<./*G4NW
7KMV[>//JW<NWK]^_@`,+'DRXL.'#0P$`
[ xx.tar.bz2 ]
M0EIH.3%!629365(,+ID``$A[D-$0`8!``7^``!!AI)Y`!```""``=!JGIBC3
M30&CU`]($HHTTR:`>D#0)SI*Z'R%H*J"&3@H]P@J>U$F5BMHOC`$L-"8C!(V
I"`'?*WA:(9*4U)@4)+"(V%.G]#W(_E6B'J8G]D`/Q=R13A0D%(,+ID``
[ xx.tar.gz ]
M'XL("!)'=%P``WAX+G1A<@"KJ-`KJ2AAH"DP,#`P,S%1`-'F9J9@VL`(PH<"
M8P5#8Q-C4P,38Q,C(P4#0R-S`V,&!0/:.@L"2HM+$HN`3LG/R<DL3L>M#J@L
E+0V/.1"/*,#I(0(J*K@&V@FC8!2,@E$P"@8````U:,3F``@`````
[ xx.tar.xz ]
M_3=Z6%H```3FUK1&`@`A`18```!T+^6CX`?_`&!=`#Q@M.AX.4O&N38V648.
M[J6L\\<_[3M*R;CASOTX?B.F\V:^)+G;\YY4"!4MLF9`*\N40G=O+K,J0"NF
M0VU7J%NN(A,R^DM8@/(_YGR5CAO+1CS_YNHE:,1!G%6L1\GT``"[$^?"O*"!
9`P`!?(`0````:OY*7K'$9_L"``````196@``
[ xx.zip ]
M4$L#!`H``````%5V64X:^I"B`P````,````&`!P`>'@N='AT550)``,21W1<
M$D=T7'5X"P`!!/4!```$%````'AX"E!+`0(>`PH``````%5V64X:^I"B`P``
M``,````&`!@```````$```"D@0````!X>"YT>'155`4``Q)'=%QU>`L``03U
>`0``!!0```!02P4&``````$``0!,````0P``````

View File

@@ -0,0 +1,181 @@
package Alien::Build::Plugin::Extract::Directory;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Alien::Build::Util qw( _mirror );
use Path::Tiny ();
# ABSTRACT: Plugin to extract a downloaded directory to a build directory
our $VERSION = '2.38'; # VERSION
has '+format' => 'd';
sub handles
{
my(undef, $ext) = @_;
$ext eq 'd' ? 1 : ();
}
sub available
{
my(undef, $ext) = @_;
__PACKAGE__->handles($ext);
}
sub init
{
my($self, $meta) = @_;
$meta->register_hook(
extract => sub {
my($build, $src) = @_;
die "not a directory: $src" unless -d $src;
if($build->meta_prop->{out_of_source})
{
$build->install_prop->{extract} = Path::Tiny->new($src)->absolute->stringify;
}
else
{
my $dst = Path::Tiny->new('.')->absolute;
# Please note: _mirror and Alien::Build::Util are ONLY
# allowed to be used by core plugins. If you are writing
# a non-core plugin it may be removed. That is why it
# is private.
_mirror $src => $dst, { verbose => 1 };
}
}
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Extract::Directory - Plugin to extract a downloaded directory to a build directory
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Extract::Directory';
=head1 DESCRIPTION
Some Download or Fetch plugins may produce a directory instead of an archive
file. This plugin is used to mirror the directory from the Download step
into a fresh directory in the Extract step. An example of when you might use
this plugin is if you were using the C<git> command in the Download step,
which results in a directory hierarchy.
=head1 PROPERTIES
=head2 format
Should always set to C<d> (for directories).
=head1 METHODS
=head2 handles
Alien::Build::Plugin::Extract::Directory->handles($ext);
$plugin->handles($ext);
Returns true if the plugin is able to handle the archive of the
given format. Only returns true for C<d> (for directory).
=head2 available
Alien::Build::Plugin::Extract::Directory->available($ext);
$plugin->available($ext);
Returns true if the plugin can extract the given format with
what is already installed.
=head1 SEE ALSO
L<Alien::Build::Plugin::Extract::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,194 @@
package Alien::Build::Plugin::Extract::Negotiate;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Alien::Build::Plugin::Extract::ArchiveTar;
use Alien::Build::Plugin::Extract::ArchiveZip;
use Alien::Build::Plugin::Extract::CommandLine;
use Alien::Build::Plugin::Extract::Directory;
# ABSTRACT: Extraction negotiation plugin
our $VERSION = '2.38'; # VERSION
has '+format' => 'tar';
sub init
{
my($self, $meta) = @_;
my $format = $self->format;
$format = 'tar.gz' if $format eq 'tgz';
$format = 'tar.bz2' if $format eq 'tbz';
$format = 'tar.xz' if $format eq 'txz';
my $plugin = $self->pick($format);
$meta->apply_plugin($plugin, format => $format);
$self;
}
sub pick
{
my(undef, $format) = @_;
if($format =~ /^tar(\.(gz|bz2))?$/)
{
if(Alien::Build::Plugin::Extract::ArchiveTar->available($format))
{
return 'Extract::ArchiveTar';
}
else
{
return 'Extract::CommandLine';
}
}
elsif($format eq 'zip')
{
# Archive::Zip is not that reliable. But if it is already installed it is probably working
if(Alien::Build::Plugin::Extract::ArchiveZip->available($format))
{
return 'Extract::ArchiveZip';
}
# If it isn't available, then use the command-line unzip. Alien::unzip will be used
# as necessary in environments where it isn't already installed.
else
{
return 'Extract::CommandLine';
}
}
elsif($format eq 'tar.xz' || $format eq 'tar.Z')
{
return 'Extract::CommandLine';
}
elsif($format eq 'd')
{
return 'Extract::Directory';
}
else
{
die "do not know how to handle format: $format";
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Extract::Negotiate - Extraction negotiation plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Extract' => (
format => 'tar.gz',
);
=head1 DESCRIPTION
This is a negotiator plugin for extracting packages downloaded from the internet.
This plugin picks the best Extract plugin to do the actual work. Which plugins are
picked depend on the properties you specify, your platform and environment. It is
usually preferable to use a negotiator plugin rather than using a specific Extract
Plugin from your L<alienfile>.
=head1 PROPERTIES
=head2 format
The expected format for the download. Possible values include:
C<tar>, C<tar.gz>, C<tar.bz2>, C<tar.xz>, C<zip>, C<d>.
=head1 METHODS
=head2 pick
my $name = Alien::Build::Plugin::Extract::Negotiate->pick($format);
Returns the name of the best plugin for the given format.
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,120 @@
# PODNAME: Alien::Build::Plugin::Fetch
# ABSTRACT: Fetch Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch - Fetch Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'http://ftp.gnu.org/gnu/make';
plugin 'Download';
};
=head1 DESCRIPTION
Fetch plugins retrieve single resources from the internet. The difference
between a Fetch plugin and a Download plugin is that Download
plugin may fetch several resources from the internet (usually using
a Fetch plugin), before finding the final archive. Normally you
will not need to use Fetch plugins directly but should instead
use the L<Alien::Build::Plugin::Download::Negotiate> plugin, which
will pick the best plugins for your given URL.
=over 4
=item L<Alien::Build::Plugin::Fetch::HTTPTiny>
=item L<Alien::Build::Plugin::Fetch::Local>
=item L<Alien::Build::Plugin::Fetch::LWP>
=item L<Alien::Build::Plugin::Fetch::NetFTP>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,358 @@
package Alien::Build::Plugin::Fetch::CurlCommand;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Which qw( which );
use Path::Tiny qw( path );
use Capture::Tiny qw( capture );
use File::Temp qw( tempdir );
use List::Util 1.33 qw( any );
use File::chdir;
# ABSTRACT: Plugin for fetching files using curl
our $VERSION = '2.38'; # VERSION
sub curl_command
{
defined $ENV{CURL} ? scalar which($ENV{CURL}) : scalar which('curl');
}
has ssl => 0;
has _see_headers => 0;
has '+url' => '';
# when bootstrapping we have to specify this plugin as a prereq
# 1 is the default so that when this plugin is used directly
# you also get the prereq
has bootstrap_ssl => 1;
sub protocol_ok
{
my($class, $protocol) = @_;
my $curl = $class->curl_command;
return 0 unless defined $curl;
my($out, $err, $exit) = capture {
system $curl, '--version';
};
{
# make sure curl supports the -J option.
# CentOS 6 for example is recent enough
# that it does not. gh#147, gh#148, gh#149
local $CWD = tempdir( CLEANUP => 1 );
my $file1 = path('foo/foo.txt');
$file1->parent->mkpath;
$file1->spew("hello world\n");
my $url = 'file://' . $file1->absolute;
my($out, $err, $exit) = capture {
system $curl, '-O', '-J', $url;
};
my $file2 = $file1->parent->child($file1->basename);
unlink "$file1";
unlink "$file2";
rmdir($file1->parent);
return 0 if $exit;
}
foreach my $line (split /\n/, $out)
{
if($line =~ /^Protocols:\s*(.*)\s*$/)
{
my %proto = map { $_ => 1 } split /\s+/, $1;
return $proto{$protocol} if $proto{$protocol};
}
}
return 0;
}
sub init
{
my($self, $meta) = @_;
$meta->prop->{start_url} ||= $self->url;
$self->url($meta->prop->{start_url});
$self->url || Carp::croak('url is a required property');
$meta->add_requires('configure', 'Alien::Build::Plugin::Fetch::CurlCommand' => '1.19')
if $self->bootstrap_ssl;
$meta->register_hook(
fetch => sub {
my($build, $url) = @_;
$url ||= $self->url;
my($scheme) = $url =~ /^([a-z0-9]+):/i;
if($scheme =~ /^https?$/)
{
local $CWD = tempdir( CLEANUP => 1 );
my @writeout = (
"ab-filename :%{filename_effective}",
"ab-content_type :%{content_type}",
"ab-url :%{url_effective}",
);
$build->log("writeout: $_\\n") for @writeout;
path('writeout')->spew(join("\\n", @writeout));
my @command = (
$self->curl_command,
'-L', '-f', '-O', '-J',
-w => '@writeout',
);
push @command, -D => 'head' if $self->_see_headers;
push @command, $url;
my($stdout, $stderr) = $self->_execute($build, @command);
my %h = map { /^ab-(.*?)\s*:(.*)$/ ? ($1 => $2) : () } split /\n/, $stdout;
if(-e 'head')
{
$build->log(" ~ $_ => $h{$_}") for sort keys %h;
$build->log(" header: $_") for path('headers')->lines;
}
my($type) = split /;/, $h{content_type};
if($type eq 'text/html')
{
return {
type => 'html',
base => $h{url},
content => scalar path($h{filename})->slurp,
};
}
else
{
return {
type => 'file',
filename => $h{filename},
path => path($h{filename})->absolute->stringify,
};
}
}
# elsif($scheme eq 'ftp')
# {
# if($url =~ m{/$})
# {
# my($stdout, $stderr) = $self->_execute($build, $self->curl_command, -l => $url);
# chomp $stdout;
# return {
# type => 'list',
# list => [
# map { { filename => $_, url => "$url$_" } } sort split /\n/, $stdout,
# ],
# };
# }
#
# my $first_error;
#
# {
# local $CWD = tempdir( CLEANUP => 1 );
#
# my($filename) = $url =~ m{/([^/]+)$};
# $filename = 'unknown' if (! defined $filename) || ($filename eq '');
# my($stdout, $stderr) = eval { $self->_execute($build, $self->curl_command, -o => $filename, $url) };
# $first_error = $@;
# if($first_error eq '')
# {
# return {
# type => 'file',
# filename => $filename,
# path => path($filename)->absolute->stringify,
# };
# }
# }
#
# {
# my($stdout, $stderr) = eval { $self->_execute($build, $self->curl_command, -l => "$url/") };
# if($@ eq '')
# {
# chomp $stdout;
# return {
# type => 'list',
# list => [
# map { { filename => $_, url => "$url/$_" } } sort split /\n/, $stdout,
# ],
# };
# };
# }
#
# $first_error ||= 'unknown error';
# die $first_error;
#
# }
else
{
die "scheme $scheme is not supported by the Fetch::CurlCommand plugin";
}
},
) if $self->curl_command;
$self;
}
sub _execute
{
my($self, $build, @command) = @_;
$build->log("+ @command");
my($stdout, $stderr, $err) = capture {
system @command;
$?;
};
if($err)
{
chomp $stderr;
$build->log($_) for split /\n/, $stderr;
if($stderr =~ /Remote filename has no length/ && !!(any { /^-O$/ } @command))
{
my @new_command = map {
/^-O$/ ? ( -o => 'index.html' ) : /^-J$/ ? () : ($_)
} @command;
return $self->_execute($build, @new_command);
}
die "error in curl fetch";
}
($stdout, $stderr);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::CurlCommand - Plugin for fetching files using curl
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'https://www.openssl.org/source/';
plugin 'Fetch::CurlCommand';
};
=head1 DESCRIPTION
This plugin provides a fetch based on the C<curl> command. It works with other fetch
plugins (that is, the first one which succeeds will be used). Most of the time the best plugin
to use will be L<Alien::Build::Plugin::Download::Negotiate>, but for some SSL bootstrapping
it may be desirable to try C<curl> first.
Protocols supported: C<http>, C<https>
C<https> support requires that curl was built with SSL support.
=head1 PROPERTIES
=head2 curl_command
The full path to the C<curl> command. The default is usually correct.
=head2 ssl
Ignored by this plugin. Provided for compatibility with some other fetch plugins.
=head1 METHODS
=head2 protocol_ok
my $bool = $plugin->protocol_ok($protocol);
my $bool = Alien::Build::Plugin::Fetch::CurlCommand->protocol_ok($protocol);
=head1 SEE ALSO
=over 4
=item L<alienfile>
=item L<Alien::Build>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,235 @@
package Alien::Build::Plugin::Fetch::HTTPTiny;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Basename ();
use Alien::Build::Util qw( _ssl_reqs );
use Carp ();
# ABSTRACT: Plugin for fetching files using HTTP::Tiny
our $VERSION = '2.38'; # VERSION
has '+url' => '';
has ssl => 0;
# ignored for compatability
has bootstrap_ssl => 1;
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'HTTP::Tiny' => '0.044' );
$meta->add_requires('share' => 'URI' => 0 );
$meta->prop->{start_url} ||= $self->url;
$self->url($meta->prop->{start_url});
$self->url || Carp::croak('url is a required property');
if($self->url =~ /^https:/ || $self->ssl)
{
my $reqs = _ssl_reqs;
foreach my $mod (sort keys %$reqs)
{
$meta->add_requires('share' => $mod => $reqs->{$mod});
}
}
$meta->register_hook( fetch => sub {
my($build, $url) = @_;
$url ||= $self->url;
my $ua = HTTP::Tiny->new;
my $res = $ua->get($url);
unless($res->{success})
{
my $status = $res->{status} || '---';
my $reason = $res->{reason} || 'unknown';
$build->log("$status $reason fetching $url");
if($status == 599)
{
$build->log("exception: $_") for split /\n/, $res->{content};
my($can_ssl, $why_ssl) = HTTP::Tiny->can_ssl;
if(! $can_ssl)
{
if($res->{redirects}) {
foreach my $redirect (@{ $res->{redirects} })
{
if(defined $redirect->{headers}->{location} && $redirect->{headers}->{location} =~ /^https:/)
{
$build->log("An attempt at a SSL URL https was made, but your HTTP::Tiny does not appear to be able to use https.");
$build->log("Please see: https://metacpan.org/pod/Alien::Build::Manual::FAQ#599-Internal-Exception-errors-downloading-packages-from-the-internet");
}
}
}
}
}
die "error fetching $url: $status $reason";
}
my($type) = split /;/, $res->{headers}->{'content-type'};
$type = lc $type;
my $base = URI->new($res->{url});
my $filename = File::Basename::basename do { my $name = $base->path; $name =~ s{/$}{}; $name };
# TODO: this doesn't get exercised by t/bin/httpd
if(my $disposition = $res->{headers}->{"content-disposition"})
{
# Note: from memory without quotes does not match the spec,
# but many servers actually return this sort of value.
if($disposition =~ /filename="([^"]+)"/ || $disposition =~ /filename=([^\s]+)/)
{
$filename = $1;
}
}
if($type eq 'text/html')
{
return {
type => 'html',
base => $base->as_string,
content => $res->{content},
};
}
else
{
return {
type => 'file',
filename => $filename || 'downloadedfile',
content => $res->{content},
};
}
});
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::HTTPTiny - Plugin for fetching files using HTTP::Tiny
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'http://ftp.gnu.org/gnu/make';
plugin 'Fetch::HTTPTiny';
};
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This fetch plugin fetches files and directory listings via the C<http> and C<https>
protocol using L<HTTP::Tiny>. If the URL specified uses the C<https> scheme, then
the required SSL modules will automatically be injected as requirements. If your
initial URL is not C<https>, but you know that it will be needed on a subsequent
request you can use the ssl property below.
=head1 PROPERTIES
=head2 url
The initial URL to fetch. This may be a directory listing (in HTML) or the final file.
=head2 ssl
If set to true, then the SSL modules required to make an C<https> connection will be
added as prerequisites.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,197 @@
package Alien::Build::Plugin::Fetch::LWP;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
# ABSTRACT: Plugin for fetching files using LWP
our $VERSION = '2.38'; # VERSION
has '+url' => '';
has ssl => 0;
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'LWP::UserAgent' => 0 );
$meta->prop->{start_url} ||= $self->url;
$self->url($meta->prop->{start_url});
$self->url || Carp::croak('url is a required property');
if($self->url =~ /^https:/ || $self->ssl)
{
$meta->add_requires('share' => 'LWP::Protocol::https' => 0 );
}
$meta->register_hook( fetch => sub {
my(undef, $url) = @_;
$url ||= $self->url;
my $ua = LWP::UserAgent->new;
$ua->env_proxy;
my $res = $ua->get($url);
die "error fetching $url: @{[ $res->status_line ]}"
unless $res->is_success;
my($type, $charset) = $res->content_type_charset;
my $base = $res->base;
my $filename = $res->filename;
if($type eq 'text/html')
{
return {
type => 'html',
charset => $charset,
base => "$base",
content => $res->decoded_content || $res->content,
};
}
elsif($type eq 'text/ftp-dir-listing')
{
return {
type => 'dir_listing',
base => "$base",
content => $res->decoded_content || $res->content,
};
}
else
{
return {
type => 'file',
filename => $filename || 'downloadedfile',
content => $res->content,
};
}
});
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::LWP - Plugin for fetching files using LWP
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'http://ftp.gnu.org/gnu/make';
plugin 'Fetch::LWP';
};
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This fetch plugin fetches files and directory listings via the C<http> C<https>, C<ftp>,
C<file> protocol using L<LWP>. If the URL specified uses the C<https> scheme, then
the required SSL modules will automatically be injected as requirements. If your
initial URL is not C<https>, but you know that it will be needed on a subsequent
request you can use the ssl property below.
=head1 PROPERTIES
=head2 url
The initial URL to fetch. This may be a directory listing (in HTML) or the final file.
=head2 ssl
If set to true, then the SSL modules required to make an C<https> connection will be
added as prerequisites.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,226 @@
package Alien::Build::Plugin::Fetch::Local;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::chdir;
use Path::Tiny ();
# ABSTRACT: Plugin for fetching a local file
our $VERSION = '2.38'; # VERSION
has '+url' => '';
has root => undef;
has ssl => 0;
sub init
{
my($self, $meta) = @_;
$meta->prop->{start_url} ||= $self->url;
$self->url($meta->prop->{start_url} || 'patch');
if($self->url =~ /^file:/)
{
$meta->add_requires('share' => 'URI' => 0 );
$meta->add_requires('share' => 'URI::file' => 0 );
$meta->add_requires('share' => 'URI::Escape' => 0 );
}
{
my $root = $self->root;
if(defined $root)
{
$root = Path::Tiny->new($root)->absolute->stringify;
}
else
{
$root = "$CWD";
}
$self->root($root);
}
$meta->register_hook( fetch => sub {
my(undef, $path) = @_;
$path ||= $self->url;
if($path =~ /^file:/)
{
my $root = URI::file->new($self->root);
my $url = URI->new_abs($path, $root);
$path = URI::Escape::uri_unescape($url->path);
$path =~ s{^/([a-z]:)}{$1}i if $^O eq 'MSWin32';
}
$path = Path::Tiny->new($path)->absolute($self->root);
if(-d $path)
{
return {
type => 'list',
list => [
map { { filename => $_->basename, url => $_->stringify } }
sort { $a->basename cmp $b->basename } $path->children,
],
};
}
elsif(-f $path)
{
return {
type => 'file',
filename => $path->basename,
path => $path->stringify,
tmp => 0,
};
}
else
{
die "no such file or directory $path";
}
});
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::Local - Plugin for fetching a local file
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'patch/libfoo-1.00.tar.gz';
plugin 'Fetch::Local';
};
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This fetch plugin fetches files from the local file system. It is mostly useful if you
intend to bundle packages (as tarballs or zip files) with your Alien. If you intend to
bundle a source tree, use L<Alien::Build::Plugin::Fetch::LocalDir>.
=head1 PROPERTIES
=head2 url
The initial URL to fetch. This may be a C<file://> style URL, or just the path on the
local system.
=head2 root
The directory from which the URL should be relative. The default is usually reasonable.
=head2 ssl
This property is for compatibility with other fetch plugins, but is not used.
=head1 SEE ALSO
=over 4
=item L<Alien::Build::Plugin::Download::Negotiate>
=item L<Alien::Build::Plugin::Fetch::LocalDir>
=item L<Alien::Build>
=item L<alienfile>
=item L<Alien::Build::MM>
=item L<Alien>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,210 @@
package Alien::Build::Plugin::Fetch::LocalDir;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::chdir;
use Path::Tiny ();
# ABSTRACT: Plugin for fetching a local directory
our $VERSION = '2.38'; # VERSION
has root => undef;
has ssl => 0;
sub init
{
my($self, $meta) = @_;
my $url = $meta->prop->{start_url} || 'patch';
$meta->add_requires('configure' => 'Alien::Build::Plugin::Fetch::LocalDir' => '0.72' );
if($url =~ /^file:/)
{
$meta->add_requires('share' => 'URI' => 0 );
$meta->add_requires('share' => 'URI::file' => 0 );
}
{
my $root = $self->root;
if(defined $root)
{
$root = Path::Tiny->new($root)->absolute->stringify;
}
else
{
$root = "$CWD";
}
$self->root($root);
}
$meta->register_hook(
fetch => sub {
my($build, $path) = @_;
$path ||= $url;
if($path =~ /^file:/)
{
my $root = URI::file->new($self->root);
my $url = URI->new_abs($path, $root);
$path = $url->path;
$path =~ s{^/([a-z]:)}{$1}i if $^O eq 'MSWin32';
}
$path = Path::Tiny->new($path)->absolute($self->root);
if(-d $path)
{
return {
type => 'file',
filename => $path->basename,
path => $path->stringify,
tmp => 0,
};
}
else
{
$build->log("path $path is not a directory");
$build->log("(you specified $url with root @{[ $self->root ]})");
die "$path is not a directory";
}
}
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::LocalDir - Plugin for fetching a local directory
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'patch/libfoo-1.00/';
plugin 'Fetch::LocalDir';
};
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This fetch plugin fetches files from the local file system. It is mostly useful if you
intend to bundle source with your Alien. If you are bundling tarballs see
L<Alien::Build::Plugin::Fetch::Local>.
=head1 PROPERTIES
=head2 root
The directory from which the start URL should be relative. The default is usually reasonable.
=head2 ssl
This property is for compatibility with other fetch plugins, but is not used.
=head1 SEE ALSO
=over 4
=item L<Alien::Build::Plugin::Download::Negotiate>
=item L<Alien::Build::Plugin::Fetch::Local>
=item L<Alien::Build>
=item L<alienfile>
=item L<Alien::Build::MM>
=item L<Alien>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,267 @@
package Alien::Build::Plugin::Fetch::NetFTP;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
use File::Temp ();
use Path::Tiny qw( path );
# ABSTRACT: Plugin for fetching files using Net::FTP
our $VERSION = '2.38'; # VERSION
has '+url' => '';
has ssl => 0;
has passive => 0;
sub init
{
my($self, $meta) = @_;
$meta->prop->{start_url} ||= $self->url;
$self->url($meta->prop->{start_url});
$self->url || Carp::croak('url is a required property');
$meta->add_requires('share' => 'Net::FTP' => 0 );
$meta->add_requires('share' => 'URI' => 0 );
$meta->add_requires('share' => 'Alien::Build::Plugin::Fetch::NetFTP' => '0.61')
if $self->passive;
$meta->register_hook( fetch => sub {
my($build, $url) = @_;
$url ||= $self->url;
$url = URI->new($url);
die "Fetch::NetFTP does not support @{[ $url->scheme ]}"
unless $url->scheme eq 'ftp';
$build->log("trying passive mode FTP first") if $self->passive;
my $ftp = _ftp_connect($url, $self->passive);
my $path = $url->path;
unless($path =~ m!/$!)
{
my(@parts) = split /\//, $path;
my $filename = pop @parts;
my $dir = join '/', @parts;
my $path = eval {
$ftp->cwd($dir) or die;
my $tdir = File::Temp::tempdir( CLEANUP => 1);
my $path = path("$tdir/$filename")->stringify;
unless(eval { $ftp->get($filename, $path) }) # NAT problem? try to use passive mode
{
$ftp->quit;
$build->log("switching to @{[ $self->passive ? 'active' : 'passive' ]} mode");
$ftp = _ftp_connect($url, !$self->passive);
$ftp->cwd($dir) or die;
$ftp->get($filename, $path) or die;
}
$path;
};
if(defined $path)
{
return {
type => 'file',
filename => $filename,
path => $path,
};
}
$path .= "/";
}
$ftp->quit;
$ftp = _ftp_connect($url, $self->passive);
$ftp->cwd($path) or die "unable to fetch $url as either a directory or file";
my $list = eval { $ftp->ls };
unless(defined $list) # NAT problem? try to use passive mode
{
$ftp->quit;
$build->log("switching to @{[ $self->passive ? 'active' : 'passive' ]} mode");
$ftp = _ftp_connect($url, !$self->passive);
$ftp->cwd($path) or die "unable to fetch $url as either a directory or file";
$list = $ftp->ls;
die "cannot list directory $path on $url" unless defined $list;
}
die "no files found at $url" unless @$list;
$path .= '/' unless $path =~ /\/$/;
return {
type => 'list',
list => [
map {
my $filename = $_;
my $furl = $url->clone;
$furl->path($path . $filename);
my %h = (
filename => $filename,
url => $furl->as_string,
);
\%h;
} sort @$list,
],
};
});
$self;
}
sub _ftp_connect {
my $url = shift;
my $is_passive = shift || 0;
my $ftp = Net::FTP->new(
$url->host, Port =>$url->port, Passive =>$is_passive,
) or die "error fetching $url: $@";
$ftp->login($url->user, $url->password)
or die "error on login $url: @{[ $ftp->message ]}";
$ftp->binary;
$ftp;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::NetFTP - Plugin for fetching files using Net::FTP
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'ftp://ftp.gnu.org/gnu/make';
plugin 'Fetch::NetFTP';
};
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This fetch plugin fetches files and directory listings via the C<ftp>, protocol using
L<Net::FTP>.
=head1 PROPERTIES
=head2 url
The initial URL to fetch. This may be a directory or the final file.
=head2 ssl
This property is for compatibility with other fetch plugins, but is not used.
=head2 passive
If set to true, try passive mode FIRST. By default it will try an active mode, then
passive mode.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,219 @@
package Alien::Build::Plugin::Fetch::Wget;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::Temp qw( tempdir );
use Path::Tiny qw( path );
use File::Which qw( which );
use Capture::Tiny qw( capture );
use File::chdir;
# ABSTRACT: Plugin for fetching files using wget
our $VERSION = '2.38'; # VERSION
has wget_command => sub { defined $ENV{WGET} ? which($ENV{WGET}) : which('wget') };
has ssl => 0;
# when bootstrapping we have to specify this plugin as a prereq
# 1 is the default so that when this plugin is used directly
# you also get the prereq
has bootstrap_ssl => 1;
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure', 'Alien::Build::Plugin::Fetch::Wget' => '1.19')
if $self->bootstrap_ssl;
$meta->register_hook(
fetch => sub {
my($build, $url) = @_;
$url ||= $meta->prop->{start_url};
my($scheme) = $url =~ /^([a-z0-9]+):/i;
if($scheme eq 'http' || $scheme eq 'https')
{
local $CWD = tempdir( CLEANUP => 1 );
my($stdout, $stderr) = $self->_execute(
$build,
$self->wget_command,
'-k', '--content-disposition', '-S',
$url,
);
my($path) = path('.')->children;
die "no file found after wget" unless $path;
my($type) = $stderr =~ /Content-Type:\s*(.*?)$/m;
$type =~ s/;.*$// if $type;
if($type eq 'text/html')
{
return {
type => 'html',
base => $url,
content => scalar $path->slurp,
};
}
else
{
return {
type => 'file',
filename => $path->basename,
path => $path->absolute->stringify,
};
}
}
else
{
die "scheme $scheme is not supported by the Fetch::Wget plugin";
}
},
) if $self->wget_command;
}
sub _execute
{
my($self, $build, @command) = @_;
$build->log("+ @command");
my($stdout, $stderr, $err) = capture {
system @command;
$?;
};
if($err)
{
chomp $stderr;
$stderr = [split /\n/, $stderr]->[-1];
die "error in wget fetch: $stderr";
}
($stdout, $stderr);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Fetch::Wget - Plugin for fetching files using wget
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'https://www.openssl.org/source/';
plugin 'Fetch::Wget';
};
=head1 DESCRIPTION
B<WARNING>: This plugin is somewhat experimental at this time.
This plugin provides a fetch based on the C<wget> command. It works with other fetch
plugins (that is, the first one which succeeds will be used). Most of the time the best plugin
to use will be L<Alien::Build::Plugin::Download::Negotiate>, but for some SSL bootstrapping
it may be desirable to try C<wget> first.
Protocols supported: C<http>, C<https>
=head1 PROPERTIES
=head2 wget_command
The full path to the C<wget> command. The default is usually correct.
=head2 ssl
Ignored by this plugin. Provided for compatibility with some other fetch plugins.
=head1 SEE ALSO
=over 4
=item L<alienfile>
=item L<Alien::Build>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,159 @@
package Alien::Build::Plugin::Gather::IsolateDynamic;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Path::Tiny ();
use Alien::Build::Util qw( _destdir_prefix );
use File::Copy ();
# ABSTRACT: Plugin to gather dynamic libraries into a separate directory
our $VERSION = '2.38'; # VERSION
sub init
{
my($self, $meta) = @_;
# plugin was introduced in 0.42, but had a bug which was fixed in 0.48
$meta->add_requires('share' => 'Alien::Build::Plugin::Gather::IsolateDynamic' => '0.48' );
$meta->after_hook(
gather_share => sub {
my($build) = @_;
$build->log("Isolating dynamic libraries ...");
my $install_root;
if($build->meta_prop->{destdir})
{
my $destdir = $ENV{DESTDIR};
$install_root = Path::Tiny->new(_destdir_prefix($ENV{DESTDIR}, $build->install_prop->{prefix}));
}
else
{
$install_root = Path::Tiny->new($build->install_prop->{stage});
}
foreach my $dir (map { $install_root->child($_) } qw( bin lib ))
{
next unless -d $dir;
foreach my $from ($dir->children)
{
next unless $from->basename =~ /\.so/
|| $from->basename =~ /\.(dylib|bundle|la|dll|dll\.a)$/;
my $to = $install_root->child('dynamic', $from->basename);
$to->parent->mkpath;
unlink "$to" if -e $to;
$build->log("move @{[ $from->parent->basename ]}/@{[ $from->basename ]} => dynamic/@{[ $to->basename ]}");
File::Copy::move("$from", "$to") || die "unable to move $from => $to $!";
}
}
$build->log(" Done!");
},
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Gather::IsolateDynamic - Plugin to gather dynamic libraries into a separate directory
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Gather::IsolateDynamic';
=head1 DESCRIPTION
This plugin moves dynamic libraries from the C<lib> and C<bin> directories and puts them in
their own C<dynamic> directory. This allows them to be used by FFI modules, but to be ignored
by XS modules.
This plugin provides the equivalent functionality of the C<alien_isolate_dynamic> attribute
from L<Alien::Base::ModuleBuild>.
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,326 @@
package Alien::Build::Plugin::PkgConfig::CommandLine;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
# ABSTRACT: Probe system and determine library or tool properties using the pkg-config command line interface
our $VERSION = '2.38'; # VERSION
has '+pkg_name' => sub {
Carp::croak "pkg_name is a required property";
};
# NOT used, for compat with other PkgConfig plugins
has register_prereqs => 1;
sub _bin_name {
# We prefer pkgconf to pkg-config because it seems to be the future.
require File::Which;
File::Which::which($ENV{PKG_CONFIG})
? $ENV{PKG_CONFIG}
: File::Which::which('pkgconf')
? 'pkgconf'
: File::Which::which('pkg-config')
? 'pkg-config'
: undef;
};
has bin_name => \&_bin_name;
has atleast_version => undef;
has exact_version => undef;
has max_version => undef;
has minimum_version => undef;
sub _val
{
my($build, $args, $prop_name) = @_;
my $string = $args->{out};
chomp $string;
$string =~ s{^\s+}{};
if($prop_name =~ /version$/)
{ $string =~ s{\s*$}{} }
else
{ $string =~ s{\s*$}{ } }
if($prop_name =~ /^(.*?)\.(.*?)\.(.*?)$/)
{ $build->runtime_prop->{$1}->{$2}->{$3} = $string }
else
{ $build->runtime_prop->{$prop_name} = $string }
();
}
sub available
{
!!_bin_name();
}
sub init
{
my($self, $meta) = @_;
my @probe;
my @gather;
my $pkgconf = $self->bin_name;
unless(defined $meta->prop->{env}->{PKG_CONFIG})
{
$meta->prop->{env}->{PKG_CONFIG} = $pkgconf;
}
my($pkg_name, @alt_names) = (ref $self->pkg_name) ? (@{ $self->pkg_name }) : ($self->pkg_name);
push @probe, map { [$pkgconf, '--exists', $_] } ($pkg_name, @alt_names);
if(defined $self->minimum_version)
{
push @probe, [ $pkgconf, '--atleast-version=' . $self->minimum_version, $pkg_name ];
}
elsif(defined $self->atleast_version)
{
push @probe, [ $pkgconf, '--atleast-version=' . $self->atleast_version, $pkg_name ];
}
if(defined $self->exact_version)
{
push @probe, [ $pkgconf, '--exact-version=' . $self->exact_version, $pkg_name ];
}
if(defined $self->max_version)
{
push @probe, [ $pkgconf, '--max-version=' . $self->max_version, $pkg_name ];
}
push @probe, [ $pkgconf, '--modversion', $pkg_name, sub {
my($build, $args) = @_;
my $version = $args->{out};
$version =~ s{^\s+}{};
$version =~ s{\s*$}{};
$build->hook_prop->{version} = $version;
}];
unshift @probe, sub {
my($build) = @_;
$build->runtime_prop->{legacy}->{name} ||= $pkg_name;
$build->hook_prop->{probe_class} = __PACKAGE__;
$build->hook_prop->{probe_instance_id} = $self->instance_id;
};
$meta->register_hook(
probe => \@probe
);
push @gather, sub {
my($build) = @_;
die 'pkg-config command line probe does not match gather' if $build->hook_prop->{name} eq 'gather_system'
&& ($build->install_prop->{system_probe_instance_id} || '') ne $self->instance_id;
};
push @gather, map { [ $pkgconf, '--exists', $_] } ($pkg_name, @alt_names);
foreach my $prop_name (qw( cflags libs version ))
{
my $flag = $prop_name eq 'version' ? '--modversion' : "--$prop_name";
push @gather,
[ $pkgconf, $flag, $pkg_name, sub { _val @_, $prop_name } ];
if(@alt_names)
{
foreach my $alt ($pkg_name, @alt_names)
{
push @gather,
[ $pkgconf, $flag, $alt, sub { _val @_, "alt.$alt.$prop_name" } ];
}
}
}
foreach my $prop_name (qw( cflags libs ))
{
push @gather,
[ $pkgconf, '--static', "--$prop_name", $pkg_name, sub { _val @_, "${prop_name}_static" } ];
if(@alt_names)
{
foreach my $alt ($pkg_name, @alt_names)
{
push @gather,
[ $pkgconf, '--static', "--$prop_name", $alt, sub { _val @_, "alt.$alt.${prop_name}_static" } ];
}
}
}
$meta->register_hook(gather_system => [@gather]);
if($meta->prop->{platform}->{system_type} eq 'windows-mingw')
{
@gather = map {
if(ref $_ eq 'ARRAY') {
my($pkgconf, @rest) = @$_;
[$pkgconf, '--dont-define-prefix', @rest],
} else {
$_
}
} @gather;
}
$meta->register_hook(gather_share => [@gather]);
$meta->after_hook(
$_ => sub {
my($build) = @_;
if(keys %{ $build->runtime_prop->{alt} } < 2)
{
delete $build->runtime_prop->{alt};
}
},
) for qw( gather_system gather_share );
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::PkgConfig::CommandLine - Probe system and determine library or tool properties using the pkg-config command line interface
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'PkgConfig::CommandLine' => (
pkg_name => 'libfoo',
);
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::PkgConfig::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin provides Probe and Gather steps for pkg-config based packages. It uses
the best command line tools to accomplish this task.
=head1 PROPERTIES
=head2 pkg_name
The package name. If this is a list reference then .pc files with all those package
names must be present.
=head2 atleast_version
The minimum required version that is acceptable version as provided by the system.
=head2 exact_version
The exact required version that is acceptable version as provided by the system.
=head2 max_version
The max required version that is acceptable version as provided by the system.
=head2 minimum_version
Alias for C<atleast_version> for backward compatibility.
=head1 METHODS
=head2 available
my $bool = Alien::Build::Plugin::PkgConfig::CommandLine->available;
Returns true if the necessary prereqs for this plugin are I<already> installed.
=head1 SEE ALSO
L<Alien::Build::Plugin::PkgConfig::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,301 @@
package Alien::Build::Plugin::PkgConfig::LibPkgConf;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
# ABSTRACT: Probe system and determine library or tool properties using PkgConfig::LibPkgConf
our $VERSION = '2.38'; # VERSION
has '+pkg_name' => sub {
Carp::croak "pkg_name is a required property";
};
has atleast_version => undef;
has exact_version => undef;
has max_version => undef;
has minimum_version => undef;
# private for now, used by negotiator
has register_prereqs => 1;
use constant _min_version => '0.04';
sub available
{
!!eval { require PkgConfig::LibPkgConf; PkgConfig::LibPkgConf->VERSION(_min_version) };
}
sub init
{
my($self, $meta) = @_;
unless(defined $meta->prop->{env}->{PKG_CONFIG})
{
# TODO: this doesn't yet find pkgconf in the bin dir of a share
# install.
my $command_line =
File::Which::which('pkgconf')
? 'pkgconf'
: File::Which::which('pkg-config')
? 'pkg-config'
: undef;
$meta->prop->{env}->{PKG_CONFIG} = $command_line
if defined $command_line;
}
if($self->register_prereqs)
{
# Also update in Neotiate.pm
$meta->add_requires('configure' => 'PkgConfig::LibPkgConf::Client' => _min_version);
if(defined $self->minimum_version || defined $self->atleast_version || defined $self->exact_version || defined $self->max_version)
{
$meta->add_requires('configure' => 'PkgConfig::LibPkgConf::Util' => _min_version);
}
}
my($pkg_name, @alt_names) = (ref $self->pkg_name) ? (@{ $self->pkg_name }) : ($self->pkg_name);
$meta->register_hook(
probe => sub {
my($build) = @_;
$build->runtime_prop->{legacy}->{name} ||= $pkg_name;
$build->hook_prop->{probe_class} = __PACKAGE__;
$build->hook_prop->{probe_instance_id} = $self->instance_id;
require PkgConfig::LibPkgConf::Client;
my $client = PkgConfig::LibPkgConf::Client->new;
my $pkg = $client->find($pkg_name);
die "package $pkg_name not found" unless $pkg;
$build->hook_prop->{version} = $pkg->version;
my $atleast_version = $self->atleast_version;
$atleast_version = $self->minimum_version unless defined $self->atleast_version;
if($atleast_version)
{
require PkgConfig::LibPkgConf::Util;
if(PkgConfig::LibPkgConf::Util::compare_version($pkg->version, $atleast_version) < 0)
{
die "package $pkg_name is version @{[ $pkg->version ]}, but at least $atleast_version is required.";
}
}
if($self->exact_version)
{
require PkgConfig::LibPkgConf::Util;
if(PkgConfig::LibPkgConf::Util::compare_version($pkg->version, $self->exact_version) != 0)
{
die "package $pkg_name is version @{[ $pkg->version ]}, but exactly @{[ $self->exact_version ]} is required.";
}
}
if($self->max_version)
{
require PkgConfig::LibPkgConf::Util;
if(PkgConfig::LibPkgConf::Util::compare_version($pkg->version, $self->max_version) > 0)
{
die "package $pkg_name is version @{[ $pkg->version ]}, but max @{[ $self->max_version ]} is required.";
}
}
foreach my $alt (@alt_names)
{
my $pkg = $client->find($alt);
die "package $alt not found" unless $pkg;
}
'system';
},
);
$meta->register_hook(
$_ => sub {
my($build) = @_;
return if $build->hook_prop->{name} eq 'gather_system'
&& ($build->install_prop->{system_probe_instance_id} || '') ne $self->instance_id;
require PkgConfig::LibPkgConf::Client;
my $client = PkgConfig::LibPkgConf::Client->new;
foreach my $name ($pkg_name, @alt_names)
{
my $pkg = $client->find($name);
die "reload of package $name failed" unless defined $pkg;
my %prop;
$prop{version} = $pkg->version;
$prop{cflags} = $pkg->cflags;
$prop{libs} = $pkg->libs;
$prop{cflags_static} = $pkg->cflags_static;
$prop{libs_static} = $pkg->libs_static;
$build->runtime_prop->{alt}->{$name} = \%prop;
}
foreach my $key (keys %{ $build->runtime_prop->{alt}->{$pkg_name} })
{
$build->runtime_prop->{$key} = $build->runtime_prop->{alt}->{$pkg_name}->{$key};
}
if(keys %{ $build->runtime_prop->{alt} } == 1)
{
delete $build->runtime_prop->{alt};
}
},
) for qw( gather_system gather_share );
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::PkgConfig::LibPkgConf - Probe system and determine library or tool properties using PkgConfig::LibPkgConf
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'PkgConfig::LibPkgConf' => (
pkg_name => 'libfoo',
);
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::PkgConfig::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin provides Probe and Gather steps for pkg-config based packages. It uses
L<PkgConfig::LibPkgConf> to accomplish this task.
This plugin is part of the Alien::Build core For Now, but may be removed in a future
date. While It Seemed Like A Good Idea at the time, it may not be appropriate to keep
it in core. If it is spun off it will get its own distribution some time in the future.
=head1 PROPERTIES
=head2 pkg_name
The package name. If this is a list reference then .pc files with all those package
names must be present.
=head2 atleast_version
The minimum required version that is acceptable version as provided by the system.
=head2 exact_version
The exact required version that is acceptable version as provided by the system.
=head2 max_version
The max required version that is acceptable version as provided by the system.
=head2 minimum_version
Alias for C<atleast_version> for backward compatibility.
=head1 METHODS
=head2 available
my $bool = Alien::Build::Plugin::PkgConfig::LibPkgConf->available;
Returns true if the necessary prereqs for this plugin are I<already> installed.
=head1 SEE ALSO
L<Alien::Build::Plugin::PkgConfig::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,200 @@
package Alien::Build::Plugin::PkgConfig::MakeStatic;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Path::Tiny ();
# ABSTRACT: Convert .pc files into static
our $VERSION = '2.38'; # VERSION
has path => undef;
sub _convert
{
my($self, $build, $path) = @_;
die "unable to read $path" unless -r $path;
die "unable to write $path" unless -w $path;
$build->log("converting $path to static");
my %h = map {
my($key, $value) = /^(.*?):(.*?)$/;
$value =~ s{^\s+}{};
$value =~ s{\s+$}{};
($key => $value);
} grep /^(?:Libs|Cflags)(?:\.private)?:/, $path->lines;
$h{Cflags} = '' unless defined $h{Cflags};
$h{Libs} = '' unless defined $h{Libs};
$h{Cflags} .= ' ' . $h{"Cflags.private"} if defined $h{"Cflags.private"};
$h{Libs} .= ' ' . $h{"Libs.private"} if defined $h{"Libs.private"};
$h{"Cflags.private"} = '';
$h{"Libs.private"} = '';
$path->edit_lines(sub {
if(/^(.*?):/)
{
my $key = $1;
if(defined $h{$key})
{
s/^(.*?):.*$/$1: $h{$key} /;
delete $h{$key};
}
}
});
$path->append("$_: $h{$_}\n") foreach keys %h;
}
sub _recurse
{
my($self, $build, $dir) = @_;
foreach my $child ($dir->children)
{
if(-d $child)
{
$self->_recurse($build, $child);
}
elsif($child->basename =~ /\.pc$/)
{
$self->_convert($build, $child);
}
}
}
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure' => 'Alien::Build::Plugin::Build::SearchDep' => '0.35');
$meta->before_hook(
gather_share => sub {
my($build) = @_;
if($self->path)
{
$self->_convert($build, Path::Tiny->new($self->path)->absolute);
}
else
{
$self->_recurse($build, Path::Tiny->new(".")->absolute);
}
},
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::PkgConfig::MakeStatic - Convert .pc files into static
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'PkgConfig::MakeStatic' => (
path => 'lib/pkgconfig/foo.pc',
);
=head1 DESCRIPTION
Convert C<.pc> file to use static linkage by default. This is an experimental
plugin, so use with caution.
=head1 PROPERTIES
=head2 path
The path to the C<.pc> file. If not provided, all C<.pc> files in the stage
directory will be converted.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,248 @@
package Alien::Build::Plugin::PkgConfig::Negotiate;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Alien::Build::Plugin::PkgConfig::PP;
use Alien::Build::Plugin::PkgConfig::LibPkgConf;
use Alien::Build::Plugin::PkgConfig::CommandLine;
use Alien::Build::Util qw( _perl_config );
use Carp ();
# ABSTRACT: Package configuration negotiation plugin
our $VERSION = '2.38'; # VERSION
has '+pkg_name' => sub {
Carp::croak "pkg_name is a required property";
};
has atleast_version => undef;
has exact_version => undef;
has max_version => undef;
has minimum_version => undef;
sub pick
{
my($class) = @_;
return $ENV{ALIEN_BUILD_PKG_CONFIG} if $ENV{ALIEN_BUILD_PKG_CONFIG};
if(Alien::Build::Plugin::PkgConfig::LibPkgConf->available)
{
return 'PkgConfig::LibPkgConf';
}
if(Alien::Build::Plugin::PkgConfig::CommandLine->available)
{
# TODO: determine environment or flags necessary for using pkg-config
# on solaris 64 bit.
# Some advice on pkg-config and 64 bit Solaris
# https://docs.oracle.com/cd/E53394_01/html/E61689/gplhi.html
my $is_solaris64 = (_perl_config('osname') eq 'solaris' && _perl_config('ptrsize') == 8);
# PkgConfig.pm is more reliable on windows
my $is_windows = _perl_config('osname') eq 'MSWin32';
if(!$is_solaris64 && !$is_windows)
{
return 'PkgConfig::CommandLine';
}
}
if(Alien::Build::Plugin::PkgConfig::PP->available)
{
return 'PkgConfig::PP';
}
else
{
# this is a fata error. because we check for a pkg-config implementation
# at configure time, we expect at least one of these to work. (and we
# fallback on installing PkgConfig.pm as a prereq if nothing else is avail).
# we therefore expect at least one of these to work, if not, then the configuration
# of the system has shifted from underneath us.
Carp::croak("Could not find an appropriate pkg-config or pkgconf implementation, please install PkgConfig.pm, PkgConfig::LibPkgConf, pkg-config or pkgconf");
}
}
sub init
{
my($self, $meta) = @_;
my $plugin = $self->pick;
Alien::Build->log("Using PkgConfig plugin: $plugin");
if(ref($self->pkg_name) eq 'ARRAY')
{
$meta->add_requires('configure', 'Alien::Build::Plugin::PkgConfig::Negotiate' => '0.79');
}
if($self->atleast_version || $self->exact_version || $self->max_version)
{
$meta->add_requires('configure', 'Alien::Build::Plugin::PkgConfig::Negotiate' => '1.53');
}
my @args;
push @args, pkg_name => $self->pkg_name;
push @args, register_prereqs => 0;
foreach my $method (map { "${_}_version" } qw( minimum atleast exact max ))
{
push @args, $method => $self->$method if defined $self->$method;
}
$meta->apply_plugin($plugin, @args);
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::PkgConfig::Negotiate - Package configuration negotiation plugin
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'PkgConfig' => (
pkg_name => 'libfoo',
);
=head1 DESCRIPTION
This plugin provides Probe and Gather steps for pkg-config based packages. It picks
the best C<PkgConfig> plugin depending your platform and environment.
=head1 PROPERTIES
=head2 pkg_name
The package name.
=head2 atleast_version
The minimum required version that is acceptable version as provided by the system.
=head2 exact_version
The exact required version that is acceptable version as provided by the system.
=head2 max_version
The max required version that is acceptable version as provided by the system.
=head2 minimum_version
Alias for C<atleast_version> for backward compatibility.
=head1 METHODS
=head2 pick
my $name = Alien::Build::Plugijn::PkgConfig::Negotiate->pick;
Returns the name of the negotiated plugin.
=head1 ENVIRONMENT
=over 4
=item ALIEN_BUILD_PKG_CONFIG
If set, this plugin will be used instead of the build in logic
which attempts to automatically pick the best plugin.
=back
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,313 @@
package Alien::Build::Plugin::PkgConfig::PP;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
use File::Which ();
use Env qw( @PKG_CONFIG_PATH );
# ABSTRACT: Probe system and determine library or tool properties using PkgConfig.pm
our $VERSION = '2.38'; # VERSION
has '+pkg_name' => sub {
Carp::croak "pkg_name is a required property";
};
has atleast_version => undef;
has exact_version => undef;
has max_version => undef;
has minimum_version => undef;
use constant _min_version => '0.14026';
# private for now, used by negotiator
has register_prereqs => 1;
sub available
{
!!eval { require PkgConfig; PkgConfig->VERSION(_min_version) };
}
sub _cleanup
{
my($value) = @_;
$value =~ s{\s*$}{ };
$value;
}
sub init
{
my($self, $meta) = @_;
unless(defined $meta->prop->{env}->{PKG_CONFIG})
{
# TODO: Better would be to to "execute" lib/PkgConfig.pm
# as that should always be available, and will match the
# exact version of PkgConfig.pm that we are using here.
# there are a few corner cases to deal with before we
# can do this. What is here should handle most use cases.
my $command_line =
File::Which::which('ppkg-config')
? 'ppkg-config'
: File::Which::which('pkg-config.pl')
? 'pkg-config.pl'
: File::Which::which('pkg-config')
? 'pkg-config'
: undef;
$meta->prop->{env}->{PKG_CONFIG} = $command_line
if defined $command_line;
}
if($self->register_prereqs)
{
$meta->add_requires('configure' => 'PkgConfig' => _min_version);
}
my($pkg_name, @alt_names) = (ref $self->pkg_name) ? (@{ $self->pkg_name }) : ($self->pkg_name);
$meta->register_hook(
probe => sub {
my($build) = @_;
$build->runtime_prop->{legacy}->{name} ||= $pkg_name;
$build->hook_prop->{probe_class} = __PACKAGE__;
$build->hook_prop->{probe_instance_id} = $self->instance_id;
require PkgConfig;
my $pkg = PkgConfig->find($pkg_name);
die "package @{[ $pkg_name ]} not found" if $pkg->errmsg;
$build->hook_prop->{version} = $pkg->pkg_version;
my $version = PkgConfig::Version->new($pkg->pkg_version);
my $atleast_version = $self->atleast_version;
$atleast_version = $self->minimum_version unless defined $atleast_version;
if(defined $atleast_version)
{
my $need = PkgConfig::Version->new($atleast_version);
if($version < $need)
{
die "package @{[ $pkg_name ]} is @{[ $pkg->pkg_version ]}, but at least $atleast_version is required.";
}
}
if(defined $self->exact_version)
{
my $need = PkgConfig::Version->new($self->exact_version);
if($version != $need)
{
die "package @{[ $pkg_name ]} is @{[ $pkg->pkg_version ]}, but exactly @{[ $self->exact_version ]} is required.";
}
}
if(defined $self->max_version)
{
my $need = PkgConfig::Version->new($self->max_version);
if($version > $need)
{
die "package @{[ $pkg_name ]} is @{[ $pkg->pkg_version ]}, but max of @{[ $self->max_version ]} is required.";
}
}
foreach my $alt (@alt_names)
{
my $pkg = PkgConfig->find($alt);
die "package $alt not found" if $pkg->errmsg;
}
'system';
},
);
$meta->register_hook(
$_ => sub {
my($build) = @_;
return if $build->hook_prop->{name} eq 'gather_system'
&& ($build->install_prop->{system_probe_instance_id} || '') ne $self->instance_id;
require PkgConfig;
foreach my $name ($pkg_name, @alt_names)
{
require PkgConfig;
my $pkg = PkgConfig->find($name, search_path => [@PKG_CONFIG_PATH]);
if($pkg->errmsg)
{
$build->log("Trying to load the pkg-config information from the source code build");
$build->log("of your package failed");
$build->log("You are currently using the pure-perl implementation of pkg-config");
$build->log("(AB Plugin is named PkgConfig::PP, which uses PkgConfig.pm");
$build->log("It may work better with the real pkg-config.");
$build->log("Try installing your OS' version of pkg-config or unset ALIEN_BUILD_PKG_CONFIG");
die "second load of PkgConfig.pm @{[ $name ]} failed: @{[ $pkg->errmsg ]}"
}
my %prop;
$prop{cflags} = _cleanup scalar $pkg->get_cflags;
$prop{libs} = _cleanup scalar $pkg->get_ldflags;
$prop{version} = $pkg->pkg_version;
$pkg = PkgConfig->find($name, static => 1, search_path => [@PKG_CONFIG_PATH]);
$prop{cflags_static} = _cleanup scalar $pkg->get_cflags;
$prop{libs_static} = _cleanup scalar $pkg->get_ldflags;
$build->runtime_prop->{alt}->{$name} = \%prop;
}
foreach my $key (keys %{ $build->runtime_prop->{alt}->{$pkg_name} })
{
$build->runtime_prop->{$key} = $build->runtime_prop->{alt}->{$pkg_name}->{$key};
}
if(keys %{ $build->runtime_prop->{alt} } == 1)
{
delete $build->runtime_prop->{alt};
}
}
) for qw( gather_system gather_share );
$self;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::PkgConfig::PP - Probe system and determine library or tool properties using PkgConfig.pm
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'PkgConfig::PP' => (
pkg_name => 'libfoo',
);
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::PkgConfig::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This plugin provides Probe and Gather steps for pkg-config based packages. It uses
L<PkgConfig> to accomplish this task.
=head1 PROPERTIES
=head2 pkg_name
The package name. If this is a list reference then .pc files with all those package
names must be present.
=head2 atleast_version
The minimum required version that is acceptable version as provided by the system.
=head2 exact_version
The exact required version that is acceptable version as provided by the system.
=head2 max_version
The max required version that is acceptable version as provided by the system.
=head2 minimum_version
Alias for C<atleast_version> for backward compatibility.
=head1 METHODS
=head2 available
my $bool = Alien::Build::Plugin::PkgConfig::PP->available;
Returns true if the necessary prereqs for this plugin are I<already> installed.
=head1 SEE ALSO
L<Alien::Build::Plugin::PkgConfig::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,112 @@
# PODNAME: Alien::Build::Plugin::Prefer
# ABSTRACT: Prefer Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Prefer - Prefer Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
share {
start_url 'http://ftp.gnu.org/gnu/make';
plugin 'Download';
};
=head1 DESCRIPTION
Prefer plugins sort
Decode plugins decode HTML and FTP file listings. Normally you
will want to use the L<Alien::Build::Plugin::Download::Negotiate>
plugin which will automatically load the appropriate Prefer plugins.
=over 4
=item L<Alien::Build::Plugin::Prefer::SortVersions>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,219 @@
package Alien::Build::Plugin::Prefer::BadVersion;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
# ABSTRACT: Plugin to filter out known bad versions
our $VERSION = '2.38'; # VERSION
has '+filter' => sub { Carp::croak("The filter property is required for the Prefer::BadVersion plugin") };
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure', __PACKAGE__, '1.05');
my $filter;
if(ref($self->filter) eq '')
{
my $string = $self->filter;
$filter = sub {
my($file) = @_;
$file->{version} ne $string;
};
}
elsif(ref($self->filter) eq 'ARRAY')
{
my %filter = map { $_ => 1 } @{ $self->filter };
$filter = sub {
my($file) = @_;
! $filter{$file->{version}};
};
}
elsif(ref($self->filter) eq 'CODE')
{
my $code = $self->filter;
$filter = sub { ! $code->($_[0]) };
}
else
{
Carp::croak("unknown filter type for Prefer::BadVersion");
}
$meta->around_hook(
prefer => sub {
my($orig, $build, @therest) = @_;
my $res1 = $orig->($build, @therest);
return $res1 unless $res1->{type} eq 'list';
return {
type => 'list',
list => [
grep { $filter->($_) } @{ $res1->{list} }
],
};
},
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Prefer::BadVersion - Plugin to filter out known bad versions
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Prefer::BadVersion' => '1.2.3';
=head1 DESCRIPTION
This plugin allows you to easily filter out known bad versions of libraries in a share install.
It doesn't affect a system install at all. You need a Prefer plugin that filters and sorts files
first. You may specify the filter in one of three ways:
=over
=item as a string
Filter out any files that match the given version.
use alienfile;
plugin 'Prefer::BadVersion' => '1.2.3';
=item as an array
Filter out all files that match any of the given versions.
use alienfile;
plugin 'Prefer::BadVersion' => [ '1.2.3', '1.2.4' ];
=item as a code reference
Filter out any files return a true value.
use alienfile;
plugin 'Prefer::BadVersion' => sub {
my($file) = @_;
$file->{version} eq '1.2.3'; # same as the string version above
};
=back
This plugin can also be used to filter out known bad versions of a library on just one platform.
For example, if you know that version 1.2.3 if bad on windows, but okay on other platforms:
use alienfile;
plugin 'Prefer::BadVersion' => '1.2.3' if $^O eq 'MSWin32';
=head1 PROPERTIES
=head2 filter
Filter out entries that match the filter.
=head1 CAVEATS
If you are using the string or array mode, then you need an existing Prefer plugin that sets the
version number for each file candidate, such as L<Alien::Build::Plugin::Prefer::SortVersions>.
Unless you want to exclude the latest version from a share install, this plugin isn't really
that useful. It has no effect on system installs, which may not be obvious at first.
=head1 SEE ALSO
=over 4
=item L<alienfile>
=item L<Alien::Build>
=item L<Alien::Build::Plugin::Prefer::SortVersions>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,221 @@
package Alien::Build::Plugin::Prefer::GoodVersion;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
# ABSTRACT: Plugin to filter known good versions
our $VERSION = '2.38'; # VERSION
has '+filter' => sub { Carp::croak("The filter property is required for the Prefer::GoodVersion plugin") };
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure', __PACKAGE__, '1.44');
my $filter;
if(ref($self->filter) eq '')
{
my $string = $self->filter;
$filter = sub {
my($file) = @_;
$file->{version} eq $string;
};
}
elsif(ref($self->filter) eq 'ARRAY')
{
my %filter = map { $_ => 1 } @{ $self->filter };
$filter = sub {
my($file) = @_;
!! $filter{$file->{version}};
};
}
elsif(ref($self->filter) eq 'CODE')
{
my $code = $self->filter;
$filter = sub { !! $code->($_[0]) };
}
else
{
Carp::croak("unknown filter type for Prefer::GoodVersion");
}
$meta->around_hook(
prefer => sub {
my($orig, $build, @therest) = @_;
my $res1 = $orig->($build, @therest);
return $res1 unless $res1->{type} eq 'list';
return {
type => 'list',
list => [
grep { $filter->($_) } @{ $res1->{list} }
],
};
},
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Prefer::GoodVersion - Plugin to filter known good versions
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Prefer::GoodVersion' => '1.2.3';
=head1 DESCRIPTION
This plugin allows you to specify one or more good versions of a library. This doesn't affect
a system install at all. This plugin does the opposite of the C<Prefer::BadVersion> plugin.
You need need a Prefer plugin that filters and sorts files first. You may specify the filter
in one of three ways:
=over
=item as a string
Filter any files that match the given version.
use alienfile;
plugin 'Prefer::GoodVersion' => '1.2.3';
=item as an array
Filter all files that match any of the given versions.
use alienfile;
plugin 'Prefer::GoodVersion' => [ '1.2.3', '1.2.4' ];
=item as a code reference
Filter any files return a true value.
use alienfile;
plugin 'Prefer::GoodVersion' => sub {
my($file) = @_;
$file->{version} eq '1.2.3'; # same as the string version above
};
=back
This plugin can also be used to filter known good versions of a library on just one platform.
For example, if you know that version 1.2.3 if good on windows, but the default logic is fine
on other platforms:
use alienfile;
plugin 'Prefer::GoodVersion' => '1.2.3' if $^O eq 'MSWin32';
=head1 PROPERTIES
=head2 filter
Filter entries that match the filter.
=head1 CAVEATS
If you are using the string or array mode, then you need an existing Prefer plugin that sets the
version number for each file candidate, such as L<Alien::Build::Plugin::Prefer::SortVersions>.
Unless you want to exclude the latest version from a share install, this plugin isn't really
that useful. It has no effect on system installs, which may not be obvious at first.
=head1 SEE ALSO
=over 4
=item L<alienfile>
=item L<Alien::Build>
=item L<Alien::Build::Plugin::Prefer::SortVersions>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,172 @@
package Alien::Build::Plugin::Prefer::SortVersions;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Plugin to sort candidates by most recent first
our $VERSION = '2.38'; # VERSION
has 'filter' => undef;
has '+version' => qr/([0-9](?:[0-9\.]*[0-9])?)/;
sub init
{
my($self, $meta) = @_;
$meta->add_requires('share' => 'Sort::Versions' => 0);
$meta->register_hook( prefer => sub {
my(undef, $res) = @_;
my $cmp = sub {
my($A,$B) = map { ($_ =~ $self->version)[0] } @_;
Sort::Versions::versioncmp($B,$A);
};
my @list = sort { $cmp->($a->{filename}, $b->{filename}) }
map {
($_->{version}) = $_->{filename} =~ $self->version;
$_ }
grep { $_->{filename} =~ $self->version }
grep { defined $self->filter ? $_->{filename} =~ $self->filter : 1 }
@{ $res->{list} };
return {
type => 'list',
list => \@list,
};
});
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Prefer::SortVersions - Plugin to sort candidates by most recent first
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Prefer::SortVersions';
=head1 DESCRIPTION
Note: in most case you will want to use L<Alien::Build::Plugin::Download::Negotiate>
instead. It picks the appropriate fetch plugin based on your platform and environment.
In some cases you may need to use this plugin directly instead.
This Prefer plugin sorts the packages that were retrieved from a dir listing, either
directly from a Fetch plugin, or from a Decode plugin. It Returns a listing with the
items sorted from post preferable to least, and filters out any undesirable candidates.
This plugin updates the file list to include the versions that are extracted, so they
can be used by other plugins, such as L<Alien::Build::Plugin::Prefer::BadVersion>.
=head1 PROPERTIES
=head2 filter
This is a regular expression that lets you filter out files that you do not
want to consider downloading. For example, if the directory listing contained
tarballs and readme files like this:
foo-1.0.0.tar.gz
foo-1.0.0.readme
You could specify a filter of C<qr/\.tar\.gz$/> to make sure only tarballs are
considered for download.
=head2 version
Regular expression to parse out the version from a filename. The regular expression
should store the result in C<$1>. The default C<qr/([0-9\.]+)/> is frequently
reasonable.
=head1 SEE ALSO
L<Alien::Build::Plugin::Download::Negotiate>, L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,125 @@
# PODNAME: Alien::Build::Plugin::Probe
# ABSTRACT: Probe Alien::Build plugins
# VERSION
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Probe - Probe Alien::Build plugins
=head1 VERSION
version 2.38
=head1 SYNOPSIS
look for libraries in known location:
use alienfile;
plugin 'Probe::CBuilder' => (
cflags => '-I/opt/libfoo/include',
libs => '-L/opt/libfoo/lib -lfoo',
);
look for tools in the path:
use alienfile;
plugin 'Probe::CommandLine' => (
command => 'gzip',
args => [ '--version' ],
match => qr/gzip/,
version => qr/gzip ([0-9\.]+)/,
);
=head1 DESCRIPTION
Probe plugins try to find existing libraries and tools
I<already> installed on the system. If found they can
be used instead of downloading the source from the
internet and building.
=over 4
=item L<Alien::Build::Plugin::Probe::CBuilder>
=item L<Alien::Build::Plugin::Probe::CommandLine>
=back
=head1 SEE ALSO
L<Alien::Build>, L<Alien::Build::Plugin>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,297 @@
package Alien::Build::Plugin::Probe::CBuilder;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use File::chdir;
use File::Temp ();
use Capture::Tiny qw( capture_merged capture );
# ABSTRACT: Probe for system libraries by guessing with ExtUtils::CBuilder
our $VERSION = '2.38'; # VERSION
has options => sub { {} };
has cflags => '';
has libs => '';
has program => 'int main(int argc, char *argv[]) { return 0; }';
has version => undef;
has aliens => [];
has lang => 'C';
sub init
{
my($self, $meta) = @_;
$meta->add_requires('configure' => 'ExtUtils::CBuilder' => 0 );
if(@{ $self->aliens })
{
die "You can't specify both 'aliens' and either 'cflags' or 'libs' for the Probe::CBuilder plugin" if $self->cflags || $self->libs;
$meta->add_requires('configure' => $_ => 0 ) for @{ $self->aliens };
$meta->add_requires('Alien::Build::Plugin::Probe::CBuilder' => '0.53');
my $cflags = '';
my $libs = '';
foreach my $alien (@{ $self->aliens })
{
my $pm = "$alien.pm";
$pm =~ s/::/\//g;
require $pm;
$cflags .= $alien->cflags . ' ';
$libs .= $alien->libs . ' ';
}
$self->cflags($cflags);
$self->libs($libs);
}
my @cpp;
if($self->lang ne 'C')
{
$meta->add_requires('Alien::Build::Plugin::Probe::CBuilder' => '0.53');
@cpp = ('C++' => 1) if $self->lang eq 'C++';
}
$meta->register_hook(
probe => sub {
my($build) = @_;
$build->hook_prop->{probe_class} = __PACKAGE__;
$build->hook_prop->{probe_instance_id} = $self->instance_id;
local $CWD = File::Temp::tempdir( CLEANUP => 1, DIR => $CWD );
open my $fh, '>', 'mytest.c';
print $fh $self->program;
close $fh;
$build->log("trying: cflags=@{[ $self->cflags ]} libs=@{[ $self->libs ]}");
my $cb = ExtUtils::CBuilder->new(%{ $self->options });
my($out1, $obj) = capture_merged { eval {
$cb->compile(
source => 'mytest.c',
extra_compiler_flags => $self->cflags,
@cpp,
);
} };
if(my $error = $@)
{
$build->log("compile failed: $error");
$build->log("compile failed: $out1");
die $@;
}
my($out2, $exe) = capture_merged { eval {
$cb->link_executable(
objects => [$obj],
extra_linker_flags => $self->libs,
);
} };
if(my $error = $@)
{
$build->log("link failed: $error");
$build->log("link failed: $out2");
die $@;
}
my($out, $err, $ret) = capture { system($^O eq 'MSWin32' ? $exe : "./$exe") };
die "execute failed" if $ret;
my $cflags = $self->cflags;
my $libs = $self->libs;
$cflags =~ s{\s*$}{ };
$libs =~ s{\s*$}{ };
$build->install_prop->{plugin_probe_cbuilder_gather}->{$self->instance_id} = {
cflags => $cflags,
libs => $libs,
};
if(defined $self->version)
{
my($version) = $out =~ $self->version;
$build->hook_prop->{version} = $version;
$build->install_prop->{plugin_probe_cbuilder_gather}->{$self->instance_id}->{version} = $version;
}
'system';
}
);
$meta->register_hook(
gather_system => sub {
my($build) = @_;
return if $build->hook_prop->{name} eq 'gather_system'
&& ($build->install_prop->{system_probe_instance_id} || '') ne $self->instance_id;
if(my $p = $build->install_prop->{plugin_probe_cbuilder_gather}->{$self->instance_id})
{
$build->runtime_prop->{$_} = $p->{$_} for keys %$p;
}
},
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Probe::CBuilder - Probe for system libraries by guessing with ExtUtils::CBuilder
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Probe::CBuilder' => (
cflags => '-I/opt/libfoo/include',
libs => '-L/opt/libfoo/lib -lfoo',
);
alternately:
ues alienfile;
plugin 'Probe::CBuilder' => (
aliens => [ 'Alien::libfoo', 'Alien::libbar' ],
);
=head1 DESCRIPTION
This plugin probes for compiler and linker flags using L<ExtUtils::CBuilder>. This is a useful
alternative to L<Alien::Build::Plugin::PkgConfig::Negotiate> for packages that do not provide
a pkg-config C<.pc> file, or for when those C<.pc> files may not be available. (For example,
on FreeBSD, C<libarchive> is a core part of the operating system, but doesn't include a C<.pc>
file which is usually provided when you install the C<libarchive> package on Linux).
=head1 PROPERTIES
=head2 options
Any extra options that you want to have passed into the constructor to L<ExtUtils::CBuilder>.
=head2 cflags
The compiler flags.
=head2 libs
The linker flags
=head2 program
The program to use in the test.
=head2 version
This is a regular expression to parse the version out of the output from the
test program.
=head2 aliens
List of aliens to query fro compiler and linker flags.
=head2 lang
The programming language to use. One of either C<C> or C<C++>.
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,248 @@
package Alien::Build::Plugin::Probe::CommandLine;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
use Capture::Tiny qw( capture );
use File::Which ();
# ABSTRACT: Probe for tools or commands already available
our $VERSION = '2.38'; # VERSION
has '+command' => sub { Carp::croak "@{[ __PACKAGE__ ]} requires command property" };
has 'args' => [];
has 'secondary' => 0;
has 'match' => undef;
has 'match_stderr' => undef;
has 'version' => undef;
has 'version_stderr' => undef;
sub init
{
my($self, $meta) = @_;
my $check = sub {
my($build) = @_;
unless(File::Which::which($self->command))
{
die 'Command not found ' . $self->command;
}
if(defined $self->match || defined $self->match_stderr || defined $self->version || defined $self->version_stderr)
{
my($out,$err,$ret) = capture {
system( $self->command, @{ $self->args } );
};
die 'Command did not return a true value' if $ret;
die 'Command output did not match' if defined $self->match && $out !~ $self->match;
die 'Command standard error did not match' if defined $self->match_stderr && $err !~ $self->match_stderr;
if(defined $self->version)
{
if($out =~ $self->version)
{
$build->runtime_prop->{version} = $1;
}
}
if(defined $self->version_stderr)
{
if($err =~ $self->version_stderr)
{
$build->hook_prop->{version} = $1;
$build->runtime_prop->{version} = $1;
}
}
}
$build->runtime_prop->{command} = $self->command;
'system';
};
if($self->secondary)
{
$meta->around_hook(
probe => sub {
my $orig = shift;
my $build = shift;
my $type = $orig->($build, @_);
return $type unless $type eq 'system';
$check->($build);
},
);
}
else
{
$meta->register_hook(
probe => $check,
);
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Probe::CommandLine - Probe for tools or commands already available
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Probe::CommandLine' => (
command => 'gzip',
args => [ '--version' ],
match => qr/gzip/,
version => qr/gzip ([0-9\.]+)/,
);
=head1 DESCRIPTION
This plugin probes for the existence of the given command line program.
=head1 PROPERTIES
=head2 command
The name of the command.
=head2 args
The arguments to pass to the command.
=head2 secondary
If you are using another probe plugin (such as L<Alien::Build::Plugin::Probe::CBuilder> or
L<Alien::Build::Plugin::PkgConfig::Negotiate>) to detect the existence of a library, but
also need a program to exist, then you should set secondary to a true value. For example
when you need both:
use alienfile;
# requires both liblzma library and xz program
plugin 'PkgConfig' => 'liblzma';
plugin 'Probe::CommandLine => (
command => 'xz',
secondary => 1,
);
When you don't:
use alienfile;
plugin 'Probe::CommandLine' => (
command => 'gzip',
secondary => 0, # default
);
=head2 match
Regular expression for which the program output should match.
=head2 match_stderr
Regular expression for which the program standard error should match.
=head2 version
Regular expression to parse out the version from the program output.
The regular expression should store the version number in C<$1>.
=head2 version_stderr
Regular expression to parse out the version from the program standard error.
The regular expression should store the version number in C<$1>.
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,269 @@
package Alien::Build::Plugin::Probe::Vcpkg;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
# ABSTRACT: Probe for system libraries using Vcpkg
our $VERSION = '2.38'; # VERSION
has '+name';
has 'lib';
has 'ffi_name';
has 'include';
sub init
{
my($self, $meta) = @_;
if(defined $self->include)
{
$meta->add_requires('configure' => 'Alien::Build::Plugin::Probe::Vcpkg' => '2.16' );
}
elsif(defined $self->ffi_name)
{
$meta->add_requires('configure' => 'Alien::Build::Plugin::Probe::Vcpkg' => '2.14' );
}
else
{
$meta->add_requires('configure' => 'Alien::Build::Plugin::Probe::Vcpkg' => '0' );
}
if($meta->prop->{platform}->{compiler_type} eq 'microsoft')
{
$meta->register_hook(
probe => sub {
my($build) = @_;
$build->hook_prop->{probe_class} = __PACKAGE__;
$build->hook_prop->{probe_instance_id} = $self->instance_id;
eval {
require Win32::Vcpkg;
require Win32::Vcpkg::List;
require Win32::Vcpkg::Package;
Win32::Vcpkg->VERSION('0.02');
};
if(my $error = $@)
{
$build->log("unable to load Win32::Vcpkg: $error");
return 'share';
}
my $package;
if($self->name)
{
$package = Win32::Vcpkg::List->new
->search($self->name, include => $self->include);
}
elsif($self->lib)
{
$package = eval { Win32::Vcpkg::Package->new( lib => $self->lib, include => $self->include) };
return 'share' if $@;
}
else
{
$build->log("you must provode either name or lib property for Probe::Vcpkg");
return 'share';
}
my $version = $package->version;
$version = 'unknown' unless defined $version;
$build->install_prop->{plugin_probe_vcpkg}->{$self->instance_id} = {
version => $version,
cflags => $package->cflags,
libs => $package->libs,
};
$build->hook_prop->{version} = $version;
$build->install_prop->{plugin_probe_vcpkg}->{$self->instance_id}->{ffi_name} = $self->ffi_name
if defined $self->ffi_name;
return 'system';
},
);
$meta->register_hook(
gather_system => sub {
my($build) = @_;
return if $build->hook_prop->{name} eq 'gather_system'
&& ($build->install_prop->{system_probe_instance_id} || '') ne $self->instance_id;
if(my $c = $build->install_prop->{plugin_probe_vcpkg}->{$self->instance_id})
{
$build->runtime_prop->{version} = $c->{version} unless defined $build->runtime_prop->{version};
$build->runtime_prop->{$_} = $c->{$_} for grep { defined $c->{$_} } qw( cflags libs ffi_name );
}
},
);
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Probe::Vcpkg - Probe for system libraries using Vcpkg
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Probe::Vcpkg' => 'libffi';
=head1 DESCRIPTION
This plugin probe can be used to find "system" packages using Microsoft's C<Vcpkg> package manager for
Visual C++ builds of Perl. C<Vcpkg> is a package manager for Visual C++ that includes a number of
open source packages. Although C<Vcpkg> does also support Linux and macOS, this plugin does not
support finding C<Vcpkg> packages on those platforms. For more details on C<Vcpkg>, see the project
github page here:
L<https://github.com/microsoft/vcpkg>
Here is the quick start guide for getting L<Alien::Build> to work with C<Vpkg>:
# install Vcpkg
C:\> git clone https://github.com/Microsoft/vcpkg.git
C:\> cd vcpkg
C:\vcpkg> .\bootstrap-vcpkg.bat
C:\vcpkg> .\vcpkg integrate install
# update PATH to include the bin directory
# so that .DLL files can be found by Perl
C:\vcpkg> path c:\vcpkg\installed\x64-windows\bin;%PATH%
# install the packages that you want
C:\vcpkg> .\vcpkg install libffi
# install the alien that uses it
C:\vcpkg> cpanm Alien::FFI
If you are using 32 bit build of Perl, then substitute C<x86-windows> for C<x64-windows>. If you do
not want to add the C<bin> directory to the C<PATH>, then you can use C<x64-windows-static> instead,
which will provide static libraries. (As of this writing static libraries for 32 bit Windows are not
available). The main downside to using C<x64-windows-static> is that Aliens that require dynamic
libraries for FFI will not be installable.
If you do not want to install C<Vcpkg> user wide (the C<integrate install> command above), then you
can use the C<PERL_WIN32_VCPKG_ROOT> environment variable instead:
# install Vcpkg
C:\> git clone https://github.com/Microsoft/vcpkg.git
C:\> cd vcpkg
C:\vcpkg> .\bootstrap-vcpkg.bat
C:\vcpkg> set PERL_WIN32_VCPKG_ROOT=c:\vcpkg
=head1 PROPERTIES
=head2 name
Specifies the name of the Vcpkg. This should not be used with the C<lib> property below, choose only one.
This is the default property, so these two are equivalent:
plugin 'Probe::Vcpkg' => (name => 'foo');
and
plugin 'Probe::Vcpkg' => 'foo';
=head2 lib
Specifies the list of libraries that make up the Vcpkg. This should not be used with the C<name> property
above, choose only one. Note that using this detection method, the version number of the package will
not be automatically determined (since multiple packages could potentially make up the list of libraries),
so you need to determine the version number another way if you need it.
This must be an array reference. Do not include the C<.lib> extension.
plugin 'Probe::Vcpkg' => (lib => ['foo','bar']);
=head2 ffi_name
Specifies an alternate ffi_name for finding dynamic libraries.
=head1 SEE ALSO
L<Alien::Build>, L<alienfile>, L<Alien::Build::MM>, L<Alien>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,442 @@
package Alien::Build::Plugin::Test::Mock;
use strict;
use warnings;
use 5.008004;
use Alien::Build::Plugin;
use Carp ();
use Path::Tiny ();
use File::chdir;
# ABSTRACT: Mock plugin for testing
our $VERSION = '2.38'; # VERSION
has 'probe';
has 'download';
has 'extract';
has 'build';
has 'gather';
sub init
{
my($self, $meta) = @_;
if(my $probe = $self->probe)
{
if($probe =~ /^(share|system)$/)
{
$meta->register_hook(
probe => sub {
$probe;
},
);
}
elsif($probe eq 'die')
{
$meta->register_hook(
probe => sub {
die "fail";
},
);
}
else
{
Carp::croak("usage: plugin 'Test::Mock' => ( probe => $probe ); where $probe is one of share, system or die");
}
}
if(my $download = $self->download)
{
$download = { 'foo-1.00.tar.gz' => _tarball() } unless ref $download eq 'HASH';
$meta->register_hook(
download => sub {
my($build) = @_;
_fs($build, $download);
},
);
}
if(my $extract = $self->extract)
{
$extract = {
'foo-1.00' => {
'configure' => _tarball_configure(),
'foo.c' => _tarball_foo_c(),
},
} unless ref $extract eq 'HASH';
$meta->register_hook(
extract => sub {
my($build) = @_;
_fs($build, $extract);
},
);
}
if(my $build = $self->build)
{
$build = [
{
'foo.o', => _build_foo_o(),
'libfoo.a' => _build_libfoo_a(),
},
{
'lib' => {
'libfoo.a' => _build_libfoo_a(),
'pkgconfig' => {
'foo.pc' => sub {
my($build) = @_;
"prefix=$CWD\n" .
"exec_prefix=\${prefix}\n" .
"libdir=\${prefix}/lib\n" .
"includedir=\${prefix}/include\n" .
"\n" .
"Name: libfoo\n" .
"Description: libfoo\n" .
"Version: 1.0.0\n" .
"Cflags: -I\${includedir}\n" .
"Libs: -L\${libdir} -lfoo\n";
},
},
},
},
] unless ref $build eq 'ARRAY';
my($build_dir, $install_dir) = @$build;
$meta->register_hook(
build => sub {
my($build) = @_;
_fs($build, $build_dir);
local $CWD = $build->install_prop->{prefix};
_fs($build, $install_dir);
},
);
}
if(my $gather = $self->gather)
{
$meta->register_hook(
$_ => sub {
my($build) = @_;
if(ref $gather eq 'HASH')
{
foreach my $key (keys %$gather)
{
$build->runtime_prop->{$key} = $gather->{$key};
}
}
else
{
my $prefix = $build->runtime_prop->{prefix};
$build->runtime_prop->{cflags} = "-I$prefix/include";
$build->runtime_prop->{libs} = "-L$prefix/lib -lfoo";
}
},
) for qw( gather_share gather_system );
}
}
sub _fs
{
my($build, $hash) = @_;
foreach my $key (sort keys %$hash)
{
my $val = $hash->{$key};
if(ref $val eq 'HASH')
{
mkdir $key;
local $CWD = $key;
_fs($build,$val);
}
elsif(ref $val eq 'CODE')
{
Path::Tiny->new($key)->spew($val->($build));
}
elsif(defined $val)
{
Path::Tiny->new($key)->spew($val);
}
}
}
sub _tarball
{
return unpack 'u', <<'EOF';
M'XL(`+DM@5@``^V4P4K$,!"&>YZGF-V]J*SM9#=)#RN^B'BHV;0)U`32U(OX
M[D;0*LJREZVRF.\R?TA@)OS\TWI_S4JBJI@/(JJ%P%19+>AKG4"V)4Z;C922
M(;T=6(%BQIDFQB$V(8WB^]X.W>%WQ^[?_S'5,Z']\%]YU]IN#/KT/8[ZO^6?
M_B=-C-=<%$BG'^4G_]S_U:)ZL*X:#(!6QN/26(Q&![W<P5_/EIF?*?])E&J>
M'BD/DO/#^6<DON__6O*<_]]@99WJQ[W&FR'NK2_-+8!U$1X;ZRZ2P"9T:HW*
D-`&ODGZZN[^$9T`,.H[!(>W@)2^*3":3.3]>`:%LBYL`#@``
`
EOF
}
sub _tarball_configure
{
return unpack 'u', <<'EOF';
<(R$O8FEN+W-H"@IE8VAO(")H:2!T:&5R92(["@``
`
EOF
}
sub _tarball_foo_c
{
return unpack 'u', <<'EOF';
M(VEN8VQU9&4@/'-T9&EO+F@^"@II;G0*;6%I;BAI;G0@87)G8RP@8VAA<B`J
887)G=EM=*0I["B`@<F5T=7)N(#`["GT*
`
EOF
}
sub _build_foo_o
{
return unpack 'u', <<'EOF';
MS_KM_@<```$#`````0````0```"P`0```"`````````9````.`$`````````
M`````````````````````````&@`````````T`$```````!H``````````<`
M```'`````P````````!?7W1E>'0`````````````7U]415A4````````````
M````````````"`````````#0`0``!`````````````````0`@```````````
M`````%]?8V]M<&%C=%]U;G=I;F1?7TQ$````````````````"``````````@
M`````````-@!```#````.`(```$````````"````````````````7U]E:%]F
M<F%M90```````%]?5$585``````````````H`````````$``````````^`$`
M``,```````````````L``&@````````````````D````$``````-"@``````
M`@```!@```!``@```0```%`"```(````"P```%`````````````````````!
M`````0``````````````````````````````````````````````````````
M``````````````````!52(GE,<!=PP``````````"`````````$`````````
M````````````%``````````!>E(``7@0`1`,!PB0`0``)````!P```"X____
M_____P@``````````$$.$(8"0PT&```````````````!```&`0````\!````
/``````````!?;6%I;@``
`
EOF
}
sub _build_libfoo_a
{
return unpack 'u', <<'EOF';
M(3QA<F-H/@HC,2\R,"`@("`@("`@("`@,34S,S$U-38Q."`@-3`Q("`@,C`@
M("`@,3`P-C0T("`T-"`@("`@("`@8`I?7RY364U$148@4T]25$5$``````@`
M````````<`````@```!?;6%I;@```",Q+S$R("`@("`@("`@("`Q-3,S,34U
M-#8X("`U,#$@("`R,"`@("`Q,#`V-#0@(#8Q,B`@("`@("!@"F9O;RYO````
M`````,_Z[?X'```!`P````$````$````L`$````@````````&0```#@!````
M``````````````````````````````!H`````````-`!````````:```````
M```'````!P````,`````````7U]T97AT`````````````%]?5$585```````
M``````````````````@`````````T`$```0````````````````$`(``````
M``````````!?7V-O;7!A8W1?=6YW:6YD7U],1`````````````````@`````
M````(`````````#8`0```P```#@"```!`````````@```````````````%]?
M96A?9G)A;64```````!?7U1%6%0`````````````*`````````!`````````
M`/@!```#```````````````+``!H````````````````)````!``````#0H`
M``````(````8````0`(```$```!0`@``"`````L```!0````````````````
M`````0````$`````````````````````````````````````````````````
M````````````````````````54B)Y3'`7<,```````````@````````!````
M`````````````````!0``````````7I2``%X$`$0#`<(D`$``"0````<````
MN/________\(``````````!!#A"&`D,-!@```````````````0``!@$````/
3`0``````````````7VUA:6X`````
`
EOF
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Plugin::Test::Mock - Mock plugin for testing
=head1 VERSION
version 2.38
=head1 SYNOPSIS
use alienfile;
plugin 'Test::Mock' => (
probe => 'share',
download => 1,
extract => 1,
build => 1,
gather => 1,
);
=head1 DESCRIPTION
This plugin is used for testing L<Alien::Build> plugins. Usually you only want to test
one or two phases in an L<alienfile> for your plugin, but you still have to have a fully
formed L<alienfile> that contains all required phases. This plugin lets you fill in the
other phases with the appropriate hooks. This is usually better than using real plugins
which may pull in additional dynamic requirements that you do not want to rely on at
test time.
=head1 PROPERTIES
=head2 probe
plugin 'Test::Mock' => (
probe => $probe,
);
Override the probe behavior by one of the following:
=over
=item share
For a C<share> build.
=item system
For a C<system> build.
=item die
To throw an exception in the probe hook. This will usually cause L<Alien::Build>
to try the next probe hook, if available, or to assume a C<share> install.
=back
=head2 download
plugin 'Test::Mock' => (
download => \%fs_spec,
);
plugin 'Test::Mock' => (
download => 1,
);
Mock out a download. The C<%fs_spec> is a hash where the hash values are directories
and the string values are files. This a spec like this:
plugin 'Test::Mock' => (
download => {
'foo-1.00' => {
'README.txt' => "something to read",
'foo.c' => "#include <stdio.h>\n",
"int main() {\n",
" printf(\"hello world\\n\");\n",
"}\n",
}
},
);
Would generate two files in the directory 'foo-1.00', a C<README.txt> and a C file named C<foo.c>.
The default, if you provide a true non-hash value is to generate a single tarball with the name
C<foo-1.00.tar.gz>.
=head2 extract
plugin 'Test::Mock' => (
extract => \%fs_spec,
);
plugin 'Test::Mock' => (
extract => 1,
);
Similar to C<download> above, but for the C<extract> phase.
=head2 build
plugin 'Test::Mock' => (
build => [ \%fs_spec_build, \%fs_spec_install ],
);
plugin 'Test::Mock' => (
build => 1,
);
=head2 gather
plugin 'Test::Mock' => (
gather => \%runtime_prop,
);
plugin 'Test::Mock' => (
gather => 1,
);
This adds a gather hook (for both C<share> and C<system>) that adds the given runtime properties, or
if a true non-hash value is provided, some reasonable runtime properties for testing.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,159 @@
package Alien::Build::Temp;
use strict;
use warnings;
use 5.008004;
use Carp ();
use Path::Tiny ();
use File::Temp ();
use File::Spec ();
# ABSTRACT: Temp Dir support for Alien::Build
our $VERSION = '2.38'; # VERSION
# problem with vanilla File::Temp is that is often uses
# as /tmp that has noexec turned on. Workaround is to
# create a temp directory in the build directory, but
# we have to be careful about cleanup. This puts all that
# (attempted) carefulness in one place so that when we
# later discover it isn't so careful we can fix it in
# one place rather thabn alllll the places that we need
# temp directories.
my %root;
sub _root
{
return File::Spec->tmpdir if $^O eq 'MSWin32';
my $root = Path::Tiny->new(-d "_alien" ? "_alien/tmp" : ".tmp")->absolute;
unless(-d $root)
{
mkdir $root or die "unable to create temp root $!";
}
# TODO: doesn't account for fork...
my $lock = $root->child("l$$");
unless(-f $lock)
{
open my $fh, '>', $lock;
close $fh;
}
$root{"$root"} = 1;
$root;
}
END {
foreach my $root (keys %root)
{
my $lock = Path::Tiny->new($root)->child("l$$");
unlink $lock;
# try to delete if possible.
# if not possible then punt
rmdir $root if -d $root;
}
}
sub newdir
{
my $class = shift;
Carp::croak "uneven" if @_ % 2;
File::Temp->newdir(DIR => _root, @_);
}
sub new
{
my $class = shift;
Carp::croak "uneven" if @_ % 2;
File::Temp->new(DIR => _root, @_);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Temp - Temp Dir support for Alien::Build
=head1 VERSION
version 2.38
=head1 DESCRIPTION
This class is private to L<Alien::Build>.
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,235 @@
package Alien::Build::Util;
use strict;
use warnings;
use 5.008004;
use base qw( Exporter );
use Path::Tiny qw( path );
use Config;
# ABSTRACT: Private utility functions for Alien::Build
our $VERSION = '2.38'; # VERSION
our @EXPORT_OK = qw( _mirror _dump _destdir_prefix _perl_config _ssl_reqs _has_ssl );
# usage: _mirror $source_directory, $dest_direction, \%options
#
# options:
# - filter -> regex for files that should match
# - empty_directory -> if true, create all directories, including empty ones.
# - verbose -> turn on verbosity
sub _mirror
{
my($src_root, $dst_root, $opt) = @_;
($src_root, $dst_root) = map { path($_) } ($src_root, $dst_root);
$opt ||= {};
require Alien::Build;
require File::Find;
require File::Copy;
File::Find::find({
wanted => sub {
next unless -e $File::Find::name;
my $src = path($File::Find::name)->relative($src_root);
return if $opt->{filter} && "$src" !~ $opt->{filter};
return if "$src" eq '.';
my $dst = $dst_root->child("$src");
$src = $src->absolute($src_root);
if(-d "$src")
{
if($opt->{empty_directory})
{
unless(-d $dst)
{
Alien::Build->log("mkdir $dst") if $opt->{verbose};
mkdir($dst) || die "unable to create directory $dst: $!";
}
}
}
elsif(-l "$src")
{
unless(-d $dst->parent)
{
Alien::Build->log("mkdir -p @{[ $dst->parent ]}") if $opt->{verbose};
$dst->parent->mkpath;
}
# TODO: rmtree if a directory?
if(-e "$dst")
{ unlink "$dst" }
my $target = readlink "$src";
Alien::Build->log("ln -s $target $dst") if $opt->{verbose};
symlink($target, $dst) || die "unable to symlink $target => $dst";
}
elsif(-f "$src")
{
unless(-d $dst->parent)
{
Alien::Build->log("mkdir -p @{[ $dst->parent ]}") if $opt->{verbose};
$dst->parent->mkpath;
}
# TODO: rmtree if a directory?
if(-e "$dst")
{ unlink "$dst" }
Alien::Build->log("cp $src $dst") if $opt->{verbose};
File::Copy::cp("$src", "$dst") || die "copy error $src => $dst: $!";
if($] < 5.012 && -x "$src" && $^O ne 'MSWin32')
{
# apparently Perl 5.8 and 5.10 do not preserver perms
my $mode = [stat "$src"]->[2] & oct(777);
eval { chmod $mode, "$dst" };
}
}
},
no_chdir => 1,
}, "$src_root");
();
}
sub _dump
{
if(eval { require YAML })
{
return YAML::Dump(@_);
}
else
{
require Data::Dumper;
return Data::Dumper::Dumper(@_);
}
}
sub _destdir_prefix
{
my($destdir, $prefix) = @_;
$prefix =~ s{^/?([a-z]):}{$1}i if $^O eq 'MSWin32';
path($destdir)->child($prefix)->stringify;
}
sub _perl_config
{
my($key) = @_;
$Config{$key};
}
sub _ssl_reqs
{
return {
'Net::SSLeay' => '1.49',
'IO::Socket::SSL' => '1.56',
};
}
sub _has_ssl
{
my %reqs = %{ _ssl_reqs() };
eval {
require Net::SSLeay;
die "need Net::SSLeay $reqs{'Net::SSLeay'}" unless Net::SSLeay->VERSION($reqs{'Net::SSLeay'});
require IO::Socket::SSL;
die "need IO::Socket::SSL $reqs{'IO::Socket::SSL'}" unless IO::Socket::SSL->VERSION($reqs{'IO::Socket::SSL'});
};
$@ eq '';
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Util - Private utility functions for Alien::Build
=head1 VERSION
version 2.38
=head1 DESCRIPTION
This module contains some private utility functions used internally by
L<Alien::Build>. It shouldn't be used by any distribution other than
C<Alien-Build>. That includes L<Alien::Build> plugins that are not
part of the L<Alien::Build> core.
You have been warned. The functionality within may be removed at
any time!
=head1 SEE ALSO
L<Alien::Build>
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,249 @@
package Alien::Build::Version::Basic;
use strict;
use warnings;
use 5.008004;
use Carp ();
use base qw( Exporter );
use overload
'<=>' => sub { shift->cmp(@_) },
'cmp' => sub { shift->cmp(@_) },
'""' => sub { shift->as_string },
bool => sub { 1 },
fallback => 1;
our @EXPORT_OK = qw( version );
# ABSTRACT: Very basic version object for Alien::Build
our $VERSION = '2.38'; # VERSION
sub new
{
my($class, $value) = @_;
$value =~ s/\.$//; # trim trailing dot
Carp::croak("invalud version: $value")
unless $value =~ /^[0-9]+(\.[0-9]+)*$/;
bless \$value, $class;
}
sub version ($)
{
my($value) = @_;
__PACKAGE__->new($value);
}
sub as_string
{
my($self) = @_;
"@{[ $$self ]}";
}
sub cmp
{
my @x = split /\./, ${$_[0]};
my @y = split /\./, ${ref($_[1]) ? $_[1] : version($_[1])};
while(@x or @y)
{
my $x = (shift @x) || 0;
my $y = (shift @y) || 0;
return $x <=> $y if $x <=> $y;
}
0;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Version::Basic - Very basic version object for Alien::Build
=head1 VERSION
version 2.38
=head1 SYNOPSIS
OO interface:
use Alien::Build::Version::Basic;
my $version = Alien::Build::Version::Basic->new('1.2.3');
if($version > '1.2.2') # true
{
...
}
Function interface:
use Alien::Build::Version::Basic qw( version );
if(version('1.2.3') > version('1.2.2')) # true
{
...
}
my @sorted = sort map { version($_) } qw( 2.1 1.2.3 1.2.2 );
# will come out in the order 1.2.2, 1.2.3, 2.1
=head1 DESCRIPTION
This module provides a very basic class for comparing versions.
This is already a crowded space on CPAN. Parts of L<Alien::Build>
already use L<Sort::Versions>, which is fine for sorting versions.
Sometimes you need to compare to see if versions match exact I<values>,
and the best candidates (such as L<Sort::Versions> on CPAN compare
C<1.2.3.0> and C<1.2.3> as being different. This class compares
those two as the same.
This class is also quite limited, in that it only works with version
schemes using a doted version numbers or real numbers with a fixed
number of digits. Versions with: dashes, letters, hex digits, or
anything else are not supported.
This class overloads both C<E<lt>=E<gt>> and C<cmp> to compare the version in
the way that you would expect for version numbers. This way you can
compare versions like numbers, or sort them using sort.
if(version($v1) > version($v2))
{
...
}
my @sorted = sort map { version($_) } @unsorted;
it also overloads C<""> to stringify as whatever string value you
passed to the constructor.
=head1 CONSTRUCTOR
=head2 new
my $version = Alien::Build::Version::Basic->new($value);
This is the long form of the constructor, if you don't want to import
anything into your namespace.
=head2 version
my $version = version($value);
This is the short form of the constructor, if you are sane. It is
NOT exported by default so you will have to explicitly import it.
=head1 METHODS
=head2 as_string
my $string = $version->as_string;
my $string = "$version";
Returns the string representation of the version object.
=head2 cmp
my $bool = $version->cmp($other);
my $bool = $version <=> $other;
my $bool = $version cmp $other;
Returns C<-1>, C<0> or C<1> just like the regular C<E<lt>=E<gt>> and C<cmp>
operators. Although C<$version> must be a version object, C<$other> may
be either a version object, or a string that could be used to create a
valid version object.
=head1 SEE ALSO
=over 4
=item L<Sort::Versions>
Good, especially if you have to support rpm style versions (like C<1.2.3-2-b>)
or don't care if trailing zeros (C<1.2.3> vs C<1.2.3.0>) are treated as
different values.
=item L<version>
Problematic for historical reasons.
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

View File

@@ -0,0 +1,161 @@
package Alien::Build::rc;
use strict;
use warnings;
use 5.008004;
# ABSTRACT: Alien::Build local config
our $VERSION = '2.38'; # VERSION
sub logx ($)
{
unshift @_, 'Alien::Build';
goto &Alien::Build::log;
}
sub preload ($)
{
push @Alien::Build::rc::PRELOAD, $_[0];
}
sub postload ($)
{
push @Alien::Build::rc::POSTLOAD, $_[0];
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::rc - Alien::Build local config
=head1 VERSION
version 2.38
=head1 SYNOPSIS
in your C<~/.alienbuild/rc.pl>:
preload 'Foo::Bar';
postload 'Baz::Frooble';
=head1 DESCRIPTION
L<Alien::Build> will load your C<~/.alienbuild/rc.pl> file, if it exists
before running the L<alienfile> recipe. This allows you to alter the
behavior of L<Alien::Build> based L<Alien>s if you have local configuration
requirements. For example you can prompt before downloading remote content
or fetch from a local mirror.
=head1 FUNCTIONS
=head2 logx
log $message;
Send a message to the L<Alien::Build> log.
=head2 preload
preload $plugin;
Preload the given plugin.
=head2 postload
postload $plugin;
Postload the given plugin.
=head1 SEE ALSO
=over 4
=item L<Alien::Build::Plugin::Fetch::Cache>
=item L<Alien::Build::Plugin::Fetch::Prompt>
=item L<Alien::Build::Plugin::Fetch::Rewrite>
=item L<Alien::Build::Plugin::Probe::Override>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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

117
database/perl/vendor/lib/Alien/GMP.pm vendored Normal file
View File

@@ -0,0 +1,117 @@
package Alien::GMP;
use strict;
use warnings;
use base 'Alien::Base';
our $VERSION = '1.16'; # VERSION
# ABSTRACT: Alien package for the GNU Multiple Precision library.
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::GMP - Alien package for the GNU Multiple Precision library.
=head1 VERSION
version 1.16
=head1 SYNOPSIS
In your Build.PL:
use Module::Build;
use Alien::GMP;
my $builder = Module::Build->new(
...
configure_requires => {
'Alien::GMP' => '0',
...
},
extra_compiler_flags => Alien::GMP->cflags,
extra_linker_flags => Alien::GMP->libs,
...
);
$build->create_build_script;
In your Makefile.PL:
use ExtUtils::MakeMaker;
use Config;
use Alien::GMP;
WriteMakefile(
...
CONFIGURE_REQUIRES => {
'Alien::GMP' => '0',
},
CCFLAGS => Alien::GMP->cflags . " $Config{ccflags}",
LIBS => [ Alien::GMP->libs ],
...
);
=head1 DESCRIPTION
This distribution installs GMP so that it can be used by other Perl distributions. If already
installed for your operating system, and it can be found, this distribution will use the GMP
that comes with your operating system, otherwise it will download it from the Internet, build and
install it for you.
=head2 C++ support
This Alien will provide the C++ bindings for GMP (libgmpxx) if possible. If you do not have a
C++ compiler, or if your operating system vendor provides a GMP package without the needed C++
files then it will not be available. To use the C++ bindings, you can use the C<alt> method
to create a C++ instance of this GMP Alien. For example:
use ExtUtils::MakeMaker;
use Config;
use Alien::GMP;
WriteMakefile(
...
CONFIGURE_REQUIRES => {
'Alien::GMP' => '1.06', # require version that provides C++ bindings
},
CCFLAGS => Alien::GMP->alt('gmpxx')->cflags . " $Config{ccflags}",
LIBS => [ Alien::GMP->alt('gmpxx')->libs ],
...
);
=head1 Inline support
This module supports L<Inline's with functionality|Inline/"Playing 'with' Others">.
=head1 SEE ALSO
L<GMP|https://gmplib.org/>
=head1 AUTHOR
Original author: Richard Simões (RSIMOES)
Current maintainer: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Zakariyya Mughal (ZMUGHAL)
William N. Braswell, Jr. (WBRASWELL)
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012-2018 by Richard Simões.
This is free software, licensed under:
The GNU Lesser General Public License, Version 3, June 2007
=cut

View File

@@ -0,0 +1,12 @@
package Alien::GMP::Install::Files;
use strict;
use warnings;
require Alien::GMP;
sub Inline { shift; Alien::GMP->Inline(@_) }
1;
=begin Pod::Coverage
Inline
=cut

View File

@@ -0,0 +1,120 @@
package Alien::Libxml2;
use strict;
use warnings;
use base qw( Alien::Base );
# ABSTRACT: Install the C libxml2 library on your system
our $VERSION = '0.17'; # VERSION
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Libxml2 - Install the C libxml2 library on your system
=head1 VERSION
version 0.17
=head1 SYNOPSIS
In your Makefile.PL:
use ExtUtils::MakeMaker;
use Alien::Base::Wrapper ();
WriteMakefile(
Alien::Base::Wrapper->new('Alien::Libxml2')->mm_args2(
# MakeMaker args
NAME => 'My::XS',
...
),
);
In your Build.PL:
use Module::Build;
use Alien::Base::Wrapper qw( Alien::Libxml2 !export );
my $builder = Module::Build->new(
...
configure_requires => {
'Alien::Libxml2' => '0',
...
},
Alien::Base::Wrapper->mb_args,
...
);
$build->create_build_script;
In your L<FFI::Platypus> script or module:
use FFI::Platypus;
use Alien::Libxml2;
my $ffi = FFI::Platypus->new(
lib => [ Alien::Libxml2->dynamic_libs ],
);
=head1 DESCRIPTION
This module provides C<libxml2> for other modules to use.
=head1 CAVEATS
There was an older existing L<Alien::LibXML>, but it uses the older
L<Alien::Build::ModuleBuild> and the author prefers this version which
is based on the more robust L<alienfile> system.
C<libxml2> has some optional prereqs, including C<zlib> and C<iconv>.
For a C<share> install you will want to make sure that these are installed
prior to installing L<Alien::Libxml2> if you want to make use of features
relying on them.
For a system install, you want to make sure the development packages for
C<libxml2>, C<zlib> and C<iconv> are installed if C<libxml2> has been
configured to use them, otherwise L<XML::LibXML> will not install as
expected. If the tests for this module fail with a missing C<iconv.h>
or C<zlib.h>, then this is likely the reason.
=head1 SEE ALSO
=over 4
=item L<Alien::LibXML>
Older Alien for the same library.
=item L<XML::LibXML>
Perl interface to C<libxml2>, which uses this L<Alien>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Shlomi Fish (shlomif)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2013 by Graham Ollis.
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

View File

@@ -0,0 +1,12 @@
package Alien::Libxml2::Install::Files;
use strict;
use warnings;
require Alien::Libxml2;
sub Inline { shift; Alien::Libxml2->Inline(@_) }
1;
=begin Pod::Coverage
Inline
=cut

138
database/perl/vendor/lib/Alien/Role.pm vendored Normal file
View File

@@ -0,0 +1,138 @@
package Alien::Role;
use strict;
use warnings;
use 5.008004;
# ABSTRACT: Extend Alien::Base with roles!
our $VERSION = '2.38'; # VERSION
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Role - Extend Alien::Base with roles!
=head1 VERSION
version 2.38
=head1 SYNOPSIS
package Alien::libfoo;
use base qw( Alien::Base );
use Role::Tiny::With qw( with );
with 'Alien::Role::Dino';
with 'Alien::Role::Alt';
1;
=head1 DESCRIPTION
The C<Alien::Role> namespace is intended for writing roles that can be
applied to L<Alien::Base> to extend its functionality. You could of
course write subclasses that extend L<Alien::Base>, but then you have
to either stick with just one subclass or deal with multiple inheritance!
It is recommended that you use L<Role::Tiny> since it can be used on
plain old Perl classes which is good since L<Alien::Base> doesn't use
anything fancy like L<Moose> or L<Moo>. There are two working examples
that use this technique that are worth checking out in the event you
are interested: L<Alien::Role::Dino> and L<Alien::Role::Alt>.
This class itself doesn't do anything, it just documents the technique.
=head1 SEE ALSO
=over 4
=item L<Alien>
=item L<Alien::Base>
=item L<alienfile>
=item L<Alien::Build>
=item L<Alien::Role::Dino>
=item L<Alien::Role::Alt>
=back
=head1 AUTHOR
Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
Contributors:
Diab Jerius (DJERIUS)
Roy Storey (KIWIROY)
Ilya Pavlov
David Mertens (run4flat)
Mark Nunberg (mordy, mnunberg)
Christian Walde (Mithaldu)
Brian Wightman (MidLifeXis)
Zaki Mughal (zmughal)
mohawk (mohawk2, ETJ)
Vikas N Kumar (vikasnkumar)
Flavio Poletti (polettix)
Salvador Fandiño (salva)
Gianni Ceccarelli (dakkar)
Pavel Shaydo (zwon, trinitum)
Kang-min Liu (劉康民, gugod)
Nicholas Shipp (nshp)
Juan Julián Merelo Guervós (JJ)
Joel Berger (JBERGER)
Petr Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
Paul Evans (leonerd, PEVANS)
Håkon Hægland (hakonhagland, HAKONH)
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 by Graham Ollis.
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