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 )