Alien-Libarchive-Installer
view release on metacpan or search on metacpan
lib/Alien/Libarchive/Installer.pm view on Meta::CPAN
sub system_install
{
my($class, %options) = @_;
$options{alien} = 1 unless defined $options{alien};
$options{test} ||= 'compile';
die "test must be one of compile, ffi or both"
unless $options{test} =~ /^(compile|ffi|both)$/;
if($options{alien} && eval q{ use Alien::Libarchive 0.21; 1 })
{
my $alien = Alien::Libarchive->new;
require File::Spec;
my $dir;
my(@dlls) = map {
my($v,$d,$f) = File::Spec->splitpath($_);
$dir = [$v,File::Spec->splitdir($d)];
$f;
} $alien->dlls;
my $build = bless {
cflags => [$alien->cflags],
libs => [$alien->libs],
dll_dir => $dir,
dlls => \@dlls,
prefix => File::Spec->rootdir,
}, $class;
eval {
$build->test_compile_run || die $build->error if $options{test} =~ /^(compile|both)$/;
$build->test_ffi || die $build->error if $options{test} =~ /^(ffi|both)$/;
};
return $build unless $@;
}
my $build = bless {
cflags => _try_pkg_config(undef, 'cflags', '', ''),
libs => _try_pkg_config(undef, 'libs', '-larchive', ''),
}, $class;
if($options{test} =~ /^(ffi|both)$/)
{
my @dir_search_list;
if($^O eq 'MSWin32')
{
# On MSWin32 the entire path is not included in dl_library_path
# but that is the most likely place that we will find dlls.
@dir_search_list = grep { -d $_ } split /;/, $ENV{PATH};
}
else
{
require DynaLoader;
@dir_search_list = grep { -d $_ } @DynaLoader::dl_library_path
}
found_dll: foreach my $dir (@dir_search_list)
{
my $dh;
opendir($dh, $dir) || next;
# sort by filename length so that libarchive.so.12.0.4
# is preferred over libarchive.so.12 or libarchive.so
# if only to make diagnostics point to the more specific
# version.
foreach my $file (sort { length $b <=> length $a } readdir $dh)
{
if($^O eq 'MSWin32')
{
next unless $file =~ /^libarchive-[0-9]+\.dll$/i;
}
elsif($^O eq 'cygwin')
{
next unless $file =~ /^cygarchive-[0-9]+\.dll$/i;
}
else
{
next unless $file =~ /^libarchive\.(dylib|so(\.[0-9]+)*)$/;
}
require File::Spec;
my($v,$d) = File::Spec->splitpath($dir, 1);
$build->{dll_dir} = [File::Spec->splitdir($d)];
$build->{prefix} = $v;
$build->{dlls} = [$file];
closedir $dh;
last found_dll;
}
closedir $dh;
}
}
$build->test_compile_run || die $build->error if $options{test} =~ /^(compile|both)$/;
$build->test_ffi || die $build->error if $options{test} =~ /^(ffi|both)$/;
$build;
}
sub _try_pkg_config
{
my($dir, $field, $guess, $extra) = @_;
unless(defined $dir)
{
require File::Temp;
$dir = File::Temp::tempdir(CLEANUP => 1);
}
require Config;
local $ENV{PKG_CONFIG_PATH} = join $Config::Config{path_sep}, $dir, split /$Config::Config{path_sep}/, ($ENV{PKG_CONFIG_PATH}||'');
my $value = eval {
# you probably think I am crazy...
eval q{ use PkgConfig 0.07620 };
die $@ if $@;
my $value = `$^X $INC{'PkgConfig.pm'} --silence-errors libarchive $extra --$field`;
die if $?;
$value;
};
unless(defined $value) {
no warnings;
$value = `pkg-config --silence-errors libarchive $extra --$field`;
return $guess if $?;
}
chomp $value;
( run in 0.713 second using v1.01-cache-2.11-cpan-140bd7fdf52 )