Alien-Xmake

 view release on metacpan or  search on metacpan

builder/Alien/Xmake/Builder.pm  view on Meta::CPAN

            use v5.40;
            use JSON::PP qw[decode_json];
            use File::Spec;
            use File::Basename qw[dirname basename];
            my $DIST = 'Alien-Xmake';

            my $config = decode_json('%s');

            sub config ($s, $key //= ()) { defined $key ? $config->{$key} : $config }
            sub config_names { sort keys %%$config }

            # Cribbed from File::ShareDir
            sub bin {
                my $bin = $config->{bin};
                return unless defined $bin;
                return $bin                                     if $config->{install_type} eq 'system';
                my $abs = File::Spec->rel2abs( $bin, dirname(__FILE__) );
                return $config->{bin} = $abs if -e $abs;
                my $dist_bin = dist_dir();
                $dist_bin = File::Spec->catdir( $dist_bin, 'bin' ) unless $^O eq 'MSWin32';
                return $config->{bin} = File::Spec->catfile( $dist_bin, basename($bin) );
            }

            sub firstres ( $test, @opts ) {
                for (@opts) {
                    my $testval = $test->();
                    return $testval if $testval;
                }
                return undef;
            }

            sub dist_dir {
                my $dir = _search_inc_path( File::Spec->catdir( 'auto', 'share', 'dist', $DIST ) ) ||
                    _search_inc_path( File::Spec->catdir( 'auto', split( /-/, $DIST ) ) );
                return $dir if defined $dir;
                require Carp;
                Carp::croak("Failed to find share dir for dist '$DIST'");
            }

            sub _search_inc_path ($path) {
                my $dir = firstres(
                    sub {
                        my $d;
                        $d = File::Spec->catdir( $_, $path ) if defined _STRING($_);
                        defined $d and -d $d ? $d : 0;
                    },
                    @INC
                    ) or
                    return;
                require Carp;
                Carp::croak("Found directory '$dir', but no read permissions") unless -r $dir;
                return $dir;
            }

            sub _STRING (@parts) {
                ( defined $parts[0] and !ref $parts[0] and length( $parts[0] ) ) ? $parts[0] : undef;
            }
        };
        1;
        PERL
        $dest->spew_utf8($content);
        say "Generated $dest";
    }

    method _install_windows ($installdir) {
        my $temppath = path('_build_xmake');
        $temppath->mkpath;
        my $arch_env   = $ENV{PROCESSOR_ARCHITECTURE} // '';
        my $arch64_env = $ENV{PROCESSOR_ARCHITEW6432} // '';
        my $target     = $self->_desired_version;
        my $filename;
        if ( $arch_env eq 'ARM64' || $arch64_env eq 'ARM64' ) {    # Check for ARM64
            $filename = "xmake-bundle-$target.arm64.exe";          # ARM64 releases use the 'bundle' naming convention
        }
        elsif ( $arch_env eq 'AMD64' || $arch_env eq 'IA64' || $arch64_env eq 'AMD64' || $arch64_env eq 'IA64' ) {    # Check for x64 (AMD64/IA64)
            $filename = "xmake-$target.win64.exe";
        }
        else {                                                                                                        # Fallback to x86
            $filename = "xmake-$target.win32.exe";
        }

        # Preferred: the exact asset URL reported by the GitHub API. Fall back to
        # the canonical hardcoded URL if the release metadata is unavailable.
        my $asset   = $self->_find_asset(qr/\Q$filename\E\z/i);
        my $url     = $asset ? $asset->{browser_download_url} : "https://github.com/$owner/$repo/releases/download/$target/$filename";
        my $outfile = $temppath->child('xmake-installer.exe');
        die 'Download failed for ' . $url unless $self->_download_file( $url, $outfile );
        $self->_verify_download( $outfile, $asset );
        my $install_str = $installdir->stringify;
        $install_str =~ s{/}{\\}g;
        my $outfile_str = $outfile->stringify;
        $outfile_str =~ s{/}{\\}g;
        say "Installing to $install_str..." if $verbose;

        # /NOADMIN: Avoid UAC prompt if possible (installs to local user path if allowed)
        # /S: Silent
        # /D: Destination directory
        my $ret = system( $outfile_str, '/NOADMIN', '/S', "/D=$install_str" );
        die "Installer failed with code $ret" if $ret != 0;

        # Ensure all extracted files/templates are writable (NSIS on Windows may set read-only attributes)
        my $iter = $installdir->iterator( { recurse => 1 } );
        while ( my $p = $iter->() ) {
            next unless $p->is_file;
            $p->chmod(0666);
        }

        # Cleanup
        path('_build_xmake')->remove_tree;
    }

    method _install_unix ($installdir) {
        my $build_dir = path('_build_xmake');
        $build_dir->remove_tree;
        $build_dir->mkpath;
        my $sudo = '';
        if ( $> != 0 && $self->_cmd_exists( 'sudo', '-n', '--version' ) ) {
            $sudo = 'sudo';
        }
        unless ( $self->_test_tools() ) {



( run in 1.681 second using v1.01-cache-2.11-cpan-364913b4093 )