Alien-bz2-Installer

 view release on metacpan or  search on metacpan

lib/Alien/bz2/Installer.pm  view on Meta::CPAN

  my $fn       = _catfile($dir, 'bzip2-1.0.6.tar.gz');
  my($version) = $class->versions_available;
  if($^O eq 'MSWin32')
  {
    $url = 'http://gnuwin32.sourceforge.net/downlinks/bzip2-src-zip.php';
    $fn  = _catfile($dir, 'bzip2-1.0.5-src.zip');
  }
  
  require HTTP::Tiny;
  my $response = HTTP::Tiny->new->get($url);
  
  die sprintf("%s %s %s", $response->{status}, $response->{reason}, $url)
    unless $response->{success};

  open my $fh, '>', $fn;
  binmode $fh;
  print $fh $response->{content};
  close $fh;
  
  wantarray ? ($fn, $version) : $fn;
}


sub build_requires
{
  my %prereqs = (
    'HTTP::Tiny' => 0,
  );
  
  if($^O eq 'MSWin32')
  {
    $prereqs{'Archive::Zip'} = 0;
    $prereqs{'Alien::o2dll'} = 0;
    $prereqs{'Alien::MSYS'}  = 0;
  }
  else
  {
    $prereqs{'Archive::Tar'} = 0;
  }
  
  \%prereqs;
}


sub system_requires
{
  my %prereqs;
  \%prereqs;
}


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)$/;
   
  my $build = bless {
    cflags => [],
    libs   => ['-lbz2'],
  }, $class;
  
  $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 _msys
{
  my($sub) = @_;
  require Config;
  if($^O eq 'MSWin32')
  {
    if($Config::Config{cc} !~ /cl(\.exe)?$/i)
    {
      require Alien::MSYS;
      return Alien::MSYS::msys(sub{ $sub->('make') });
    }
  }
  $sub->($Config::Config{make});
}

sub build_install
{
  my($class, $prefix, %options) = @_;
  
  $options{test} ||= 'compile';
  die "test must be one of compile, ffi or both"
    unless $options{test} =~ /^(compile|ffi|both)$/;
  die "need an install prefix" unless $prefix;
  
  $prefix =~ s{\\}{/}g;
  
  my $dir = $options{dir} || do { require File::Temp; File::Temp::tempdir( CLEANUP => 1 ) };
  
  require Cwd;
  require File::Spec;
  my $save = Cwd::getcwd();
  
  my $build = eval {
    if($^O eq 'MSWin32')
    {
      require Archive::Zip;
      my $zip = Archive::Zip->new;
      $zip->read(scalar $options{tar} || $class->fetch);
      chdir $dir;
      mkdir 'bzip2-1.0.5';
      chdir 'bzip2-1.0.5';
      $zip->extractTree;
      chdir(_catdir(qw( src bzip2 1.0.5 bzip2-1.0.5 )));
    }
    else
    {
      require Archive::Tar;
      my $tar = Archive::Tar->new;
      $tar->read($options{tar} || $class->fetch);
      chdir $dir;
      $tar->extract;
      chdir do {
      opendir my $dh, '.';
        my(@list) = grep !/^\./,readdir $dh;
        close $dh;
        die "unable to find source in build root" if @list == 0;
        die "confused by multiple entries in the build root" if @list > 1;
        $list[0];
      };
    }
      
    if($^O eq 'MSWin32')
    {
      open my $fh, '<', 'Makefile';
      my $makefile = do { local $/; <$fh> }; 
      close $fh;
      
      $makefile =~ s/\to2dll/\t$^X -MAlien::o2dll=o2dll o2dll.pl/g;
      
      open $fh, '>', 'Makefile';
      print $fh $makefile;
      close $fh;
      
      open $fh, '>', 'o2dll.pl';
      print $fh "use Alien::o2dll qw( o2dll );\n";
      print $fh "o2dll(\@ARGV)\n";
      close $fh;
      
      _msys(sub {
        system 'make', 'all';
        die "make all failed" if $?;
        system 'make', 'install', "PREFIX=$prefix";
        die "make install failed" if $?;
      });
      mkdir(_catdir($prefix, 'dll'));
      File::Copy::copy('bzip2.dll', _catfile($prefix, 'dll', 'bzip2.dll'));
      File::Copy::copy('libbz2.dll.a', _catfile($prefix, 'dll', 'libbz2.dll.a'));
    }
    else
    {
      require Config;
      require File::Copy;
      my $make = $Config::Config{make};
      system $make, -f => 'Makefile-libbz2_so';
      die "make -f Makefile-libbz2_so failed" if $?;
      system $make, 'all';
      die "make all failed" if $?;
      system $make, 'install', "PREFIX=$prefix";
      die "make install failed" if $?;
      mkdir(_catdir($prefix, 'dll'));
      File::Copy::copy('libbz2.so.1.0.6', _catfile($prefix, 'dll', 'libbz2.so.1.0.6'));
      eval { chmod 0755, _catfile($prefix, 'dll', 'libbz2.so.1.0.6') };
    }
    
    my $build = bless {
      cflags  => [ "-I" . _catdir($prefix, 'include') ],
      libs    => [ "-L" . _catdir($prefix, 'lib'), '-lbz2' ],
      prefix  => $prefix,
      dll_dir => [ 'dll' ],
      dlls    => do {
        opendir(my $dh, File::Spec->catdir($prefix, 'dll'));
        [grep { ! -l File::Spec->catfile($prefix, 'dll', $_) } grep { /\.so/ || /\.(dll|dylib)$/ } grep !/^\./, readdir $dh];
      },
    }, $class;
    
    $build->test_compile_run || die $build->error if $options{test} =~ /^(compile|both)$/;
    $build->test_ffi         || die $build->error if $options{test} =~ /^(ffi|both)$/;
    
    $build;
  };
  
  my $error = $@;
  chdir $save;
  die $error if $error;
  $build;
}



sub cflags  { shift->{cflags}  }
sub libs    { shift->{libs}    }
sub version { shift->{version} }

sub dlls
{
  my($self, $prefix) = @_;
  
  $prefix = $self->{prefix} unless defined $prefix;
  
  require File::Spec;
  
  unless(defined $self->{dlls} && defined $self->{dll_dir})
  {
    if($^O eq 'cygwin')
    {
      opendir my $dh, '/usr/bin';
      $self->{dlls}    = [grep /^cygbz2-[0-9]+\.dll$/i, readdir $dh];
      $self->{dll_dir} = [];
      $prefix = '/usr/bin';
      closedir $dh;
    }
    else
    {
      require DynaLoader;
      my $path = DynaLoader::dl_findfile(grep /^-l/, @{ $self->libs});
      die "unable to find dynamic library" unless defined $path;
      my($vol, $dirs, $file) = File::Spec->splitpath($path);
      if($^O eq 'openbsd')
      {
        # on openbsd we get the .a file back, so have to scan
        # for .so.#.# as there is no .so symlink
        opendir(my $dh, $dirs);
        $self->{dlls} = [grep /^libbz2.so/, readdir $dh];
        closedir $dh;
      }



( run in 1.453 second using v1.01-cache-2.11-cpan-13bb782fe5a )