Alien-Base-ModuleBuild

 view release on metacpan or  search on metacpan

lib/Alien/Base/ModuleBuild.pm  view on Meta::CPAN


  }

  $self->config_data( install_type => 'share' );
  $self->config_data( original_prefix => $self->alien_library_destination );

  my $pc = $self->alien_load_pkgconfig;
  my $pc_version = (
    $pc->{$self->alien_name} || $pc->{_manual}
  )->keyword('Version');

  unless (defined $version) {
    local $CWD = $self->config_data( 'working_directory' );
    $version = $self->alien_check_built_version
  }

  if (! $version && ! $pc_version) {
    print STDERR "If you are the author of this Alien dist, you may need to provide a an\n";
    print STDERR "alien_check_built_version method for your Alien::Base::ModuleBuild\n";
    print STDERR "class.  See:\n";
    print STDERR "https://metacpan.org/pod/Alien::Base::ModuleBuild#alien_check_built_version\n";
    carp "Library looks like it installed, but no version was determined";
    $self->config_data( version => 0 );
    return
  }

  if ( $version and $pc_version and versioncmp($version, $pc_version)) {
    carp "Version information extracted from the file name and pkgconfig data disagree";
  }

  $self->config_data( version => $pc_version || $version );

  # prevent building multiple times (on M::B::dispatch)
  $self->notes( 'ACTION_alien_completed' => 1 );

  return;
}

sub ACTION_alien_test {
  my $self = shift;
  print "Testing library (if applicable) ... ";
  if ($self->config_data( 'install_type' ) eq 'share') {
    if (defined (my $wdir = $self->config_data( 'working_directory' ))) {
      local $CWD = $wdir;
      $self->alien_do_commands('test') or die "Failed\n";
    }
  }
  print "Done\n";
}

sub ACTION_test {
  my $self = shift;
  $self->depends_on('alien_test');
  $self->SUPER::ACTION_test;
}

sub ACTION_install {
  my $self = shift;
  $self->SUPER::ACTION_install;
  if($self->alien_stage_install) {
    $self->alien_relocation_fixup;
  } else {
    $self->depends_on('alien_install');
  }
}

sub ACTION_alien_install {
  my $self = shift;

  local $| = 1; # don't buffer stdout

  return if $self->config_data( 'install_type' ) eq 'system';

  my $destdir = $self->destdir;
  my $target = $self->alien_library_destination;

  if(defined $destdir && !$self->alien_stage_install)
  {
    # Note: no longer necessary when doing a staged install
    # prefix the target directory with $destdir so that package builds
    # can install into a fake root
    $target = File::Spec->catdir($destdir, $target);
  }

  {
    local $CWD = $target;

    # The only form of introspection that exists is to see that the README file
    # which was placed in the share_dir (default _share) exists where we expect
    # after installation.
    unless ( -e 'README' ) {
      die "share_dir mismatch detected ($target)\n"
    }
  }

  if(!$self->config_data( 'finished_installing' ))
  {
    local $CWD = $self->config_data( 'working_directory' );
    local $ENV{DESTDIR} = $ENV{DESTDIR};
    $ENV{DESTDIR} = $destdir if defined $destdir && !$self->alien_stage_install;
    print "Installing library to $CWD ... ";
    $self->alien_do_commands('install') or die "Failed\n";
    print "Done\n";
  }

  if ( $self->alien_isolate_dynamic ) {
    local $CWD = $target;
    print "Isolating dynamic libraries ... ";
    mkdir 'dynamic' unless -d 'dynamic';
    foreach my $dir (qw( bin lib )) {
      next unless -d $dir;
      opendir(my $dh, $dir);
      my @dlls = grep { /\.so/ || /\.(dylib|bundle|la|dll|dll\.a)$/ } grep !/^\./, readdir $dh;
      closedir $dh;
      foreach my $dll (@dlls) {
        my $from = File::Spec->catfile($dir, $dll);
        my $to   = File::Spec->catfile('dynamic', $dll);
        unlink $to if -e $to;
        move($from, $to);
      }
    }

lib/Alien/Base/ModuleBuild.pm  view on Meta::CPAN

      if ($ext eq '.h') {
        push @inc_paths, $path;
        next;
      }

      $file =~ s/^lib//;

      if (@libs) {
        next unless any { $file eq $_ } @libs;
      }

      next if any { $file eq $_ } @lib_files;

      push @lib_files, $file;
      push @lib_paths, $path;
    }
  }

  @lib_files = uniq @lib_files;
  @lib_files = sort @lib_files;

  @lib_paths = uniq @lib_paths;
  @inc_paths = uniq @inc_paths;

  return { lib => \@lib_paths, inc => \@inc_paths, lib_files => \@lib_files };
}

sub alien_refresh_packlist {
  my $self = shift;
  my $dir = shift || croak "Must specify a directory to include in packlist";

  return unless $self->create_packlist;

  my %installed_args;
  $installed_args{extra_libs} = [map { File::Spec->catdir($self->destdir, $_) } @INC]
    if defined $self->destdir;

  my $inst = ExtUtils::Installed->new( %installed_args );
  my $packlist = $inst->packlist( $self->module_name );
  print "Using " .  $packlist->packlist_file . "\n";

  my $changed = 0;
  my $files = $self->_rscan_destdir($dir);
  # This is kind of strange, but MB puts the destdir paths in the
  # packfile, when arguably it should not.  Usually you will want
  # to turn off packlists when you you are building an rpm anyway,
  # but for the sake of maximum compat with MB we add the destdir
  # back in after _rscan_destdir has stripped it out.
  $files = [ map { File::Spec->catdir($self->destdir, $_) } @$files ]
    if defined $self->destdir;
  for my $file (@$files) {
    next if $packlist->{$file};
    print "Adding $file to packlist\n";
    $changed++;
    $packlist->{$file}++;
  };

  $packlist->write if $changed;
}

sub alien_relocation_fixup {
  my($self) = @_;

  # so far relocation fixup is only needed on OS X
  return unless $^O eq 'darwin';

  my $dist_name = $self->dist_name;
  my $share = _catdir( $self->install_destination($self->alien_arch ? 'arch' : 'lib'), qw/auto share dist/, $dist_name );

  require File::Find;
  File::Find::find(sub {
    if(/\.dylib$/)
    {
      # save the original mode and make it writable
      my $mode = (stat $File::Find::name)[2];
      chmod 0755, $File::Find::name unless -w $File::Find::name;

      my @cmd = (
        'install_name_tool',
        '-id' => $File::Find::name,
        $File::Find::name,
      );
      print "+ @cmd\n";
      system @cmd;

      # restore the original permission mode
      chmod $mode, $File::Find::name;
    }
  }, $share);
}

sub _rscan_destdir {
  my($self, $dir, $pattern) = @_;
  my $destdir = $self->destdir;
  $dir = _catdir($destdir, $dir) if defined $destdir;
  my $files = $self->rscan_dir($dir, $pattern);
  $files = [ map { my $dir = $_; $dir =~ s/^$destdir//; $dir } @$files ] if defined $destdir;
  $files;
}

# File::Spec uses \ as the file separator on MSWin32, which makes sense
# since it is the default "native" file separator, but in practice / is
# supported everywhere that matters and is significantly less problematic
# in a number of common use cases (e.g. shell quoting).  This is a short
# cut _catdir for this rather common pattern where you want catdir with
# / as the file separator on Windows.
sub _catdir {
  my $dir = File::Spec->catdir(@_);
  $dir =~ s{\\}{/}g if $^O eq 'MSWin32';
  $dir;
}

sub alien_install_network {
  defined $ENV{ALIEN_INSTALL_NETWORK} ? !!$ENV{ALIEN_INSTALL_NETWORK} : 1;
}

sub alien_download_rule {

  if(defined $ENV{ALIEN_DOWNLOAD_RULE}) {
    return 'warn' if $ENV{ALIEN_DOWNLOAD_RULE} eq 'default';
    return $ENV{ALIEN_DOWNLOAD_RULE} if $ENV{ALIEN_DOWNLOAD_RULE} =~ /^(warn|digest|encrypt|digest_or_encrypt|digest_and_encrypt)$/;
    warn "unknown ALIEN_DOWNLOAD_RULE \"ALIEN_DOWNLOAD_RULE\", using \"warn\" instead";
  }



( run in 1.452 second using v1.01-cache-2.11-cpan-71847e10f99 )