Alien-CPython3

 view release on metacpan or  search on metacpan

alienfile  view on Meta::CPAN

    ) or die;


    my @lines = split /\n/, join "", @$stdout_buff;

    # Output is a single line:
    #   - ": is not an object file"
    #   - ": object is not a Mach-O file type."
    die "Not an object file: @lines" if @lines < 2;
    # Output:
    #   - "Archive : [...]"
    die "No libs: $lines[0]" if $lines[0] =~ /^Archive\s+:\s+/;

    # first line is $file
    shift @lines;
    grep { defined } map {
      $_ =~ m%[[:blank:]]+(.*/(Python|[^/]*\.dylib))[[:blank:]]+\(compatibility version%;
      my $path = $1;
      $path;
    } @lines;
  };

  \@libs;
}

use constant PYTHON_FRAMEWORK_PREFIX => '/Library/Frameworks/Python.framework';

sub macos_relocatable_python {
  my ($build, $base) = @_;

  $base = path($base);

  die "Not a directory: $base" unless -d $base;

  my ($version_base) = $base->child( qw(Python.framework Versions) )->children( qr/^3\./ );

  my @paths_to_check;

  File::Find::find(
    sub { push @paths_to_check, path($File::Find::name) if -f && -B },
    $version_base );

  my %paths_changed;

  # Turn paths from PYTHON_FRAMEWORK_PREFIX to @rpath/Python.framework.
  my $frameworks_path = path(PYTHON_FRAMEWORK_PREFIX)->parent;
  my $rpathify = sub {
    my ($path) = @_;
    return unless index($path, PYTHON_FRAMEWORK_PREFIX . '/') == 0;
    return File::Spec->catfile(
      '@rpath',
      File::Spec->abs2rel($path, $frameworks_path)
    );
  };
  for my $change_path (@paths_to_check) {
    next if exists $paths_changed{$change_path};
    my $libs;
    $build->log("Skipping $change_path\n"), next unless eval { $libs = _otool_libs( $change_path ); 1 };
    $paths_changed{$change_path} = 1;

    $change_path->chmod('u+w');

    my $path_rel_ver = $change_path->relative( $version_base );
    if( $path_rel_ver->parent eq 'bin' || $path_rel_ver eq 'Resources/Python.app/Contents/MacOS/Python' ) {
      my $exec_path_rpath = File::Spec->catfile(
        '@executable_path',
        $base->relative($change_path->parent),
      );
      $build->log("-add_rpath for $change_path: $exec_path_rpath\n");
      IPC::Cmd::run( command => [
        qw(install_name_tool -add_rpath),
          $exec_path_rpath,
          $change_path
      ]); # no or die to avoid duplicate rpath bits
    }

    if( $change_path->basename =~ /\.dylib$|^Python$/ ) {
      my $to_python_framework_path = File::Spec->catfile(
        $frameworks_path,
        File::Spec->abs2rel($change_path, $base)
      );
      my $id_with_rpath = $rpathify->($to_python_framework_path);
      $build->log("-id for $change_path: $id_with_rpath\n");
      IPC::Cmd::run( command => [
        qw(install_name_tool -id),
          $id_with_rpath,
          $change_path
      ]) or die;
    }

    $build->log("Processing libs for $change_path\n");
    for my $lib (@$libs) {
      my $lib_with_rpath_framework = $rpathify->($lib) or next;
      $build->log("-change: $lib -> $lib_with_rpath_framework\n");
      IPC::Cmd::run( command => [
        qw(install_name_tool -change),
          $lib,
          $lib_with_rpath_framework,
          $change_path
      ]) or die;
    }
  }

  # python3 -c 'import sys; print( "\n".join(sys.path) )'
}


sub do_binary_macos {
  requires 'Alien::Build::CommandSequence';

  start_url 'https://www.python.org/downloads/macos/';
  # Using universal2 installer.
  plugin Download => (
    filter  => qr/python-([0-9\.]+)-macos11.pkg/,
    version => qr/([0-9\.]+)/,
  );
  extract sub {
    my ($build) = @_;

    Alien::Build::CommandSequence->new([
      qw(pkgutil --expand-full),



( run in 0.943 second using v1.01-cache-2.11-cpan-efa8479b9fe )