Alien-Xmake
view release on metacpan or search on metacpan
lib/Alien/Xrepo.pm view on Meta::CPAN
use Path::Tiny;
field $includedirs : param : reader;
field $libfiles : param : reader;
field $license : param : reader;
field $linkdirs : param : reader;
field $links : param : reader;
field $shared : param : reader;
field $static : param : reader;
field $version : param : reader;
field $libpath : param : reader //= ();
field $bindirs : param : reader //= [];
# Helper to find a specific header inside the includedirs
method find_header ($filename) {
for my $dir (@$includedirs) {
my $p = path($dir)->child($filename);
return $p->stringify if $p->exists;
}
# Fallback check: sometimes xrepo returns the generic include root,
# and the file is in a subdir (e.g. GL/gl.h)
warn "Header '$filename' not found in package include directories:\n" . join( "\n", @$includedirs ) . "\n";
return;
}
method bin_dir {@$bindirs}
method _data_printer ($ddp) {
{ includedirs => $includedirs,
libfiles => $libfiles,
license => $license,
linkdirs => $linkdirs,
links => $links,
shared => $shared,
static => $static,
version => $version,
libpath => $libpath,
bindirs => $bindirs
}
}
}
#
method install ( $pkg_spec, $version //= (), %opts ) {
my $full_spec = defined $version && length $version ? "$pkg_spec $version" : $pkg_spec;
# Build common arguments for both install and fetch
my @args = $self->_build_args( \%opts );
say "[*] xrepo: ensuring $full_spec is installed..." if $verbose;
lib/Alien/Xrepo.pm view on Meta::CPAN
push @args, '--includes=' . ( ref $i eq 'ARRAY' ? join( ',', @$i ) : $i );
}
return @args;
}
method _process_info ($info) {
return () unless defined $info;
my $libfiles = $info->{libfiles} // [];
my $incdirs = $info->{includedirs} // [];
my $linkdirs = $info->{linkdirs} // [];
my $bindirs = $info->{bindirs} // [];
# 1. Validate that we actually got files back
unless (@$libfiles) {
$self->blah('[!] xrepo returned no library files. Package might be header-only.');
# Return a generic object (likely header-only)
return Alien::Xrepo::PackageInfo->new(
includedirs => $incdirs,
libfiles => [],
libpath => undef,
lib/Alien/Xrepo.pm view on Meta::CPAN
($runtime_lib) = grep {/\.dll$/i} @$libfiles;
# If not, we must hunt for it in the 'bin' directory sibling to the 'lib' directory.
unless ($runtime_lib) {
my ($imp_lib) = grep {/\.lib$/i} @$libfiles;
if ($imp_lib) {
my $lib_path = path($imp_lib);
my $basename = $lib_path->basename(qr/\.lib$/i); # e.g., 'zlib' from 'zlib.lib'
# Construct list of potential directories to search
my @search_dirs = @$bindirs;
# Add standard relative paths: /path/to/lib/../bin
push @search_dirs, $lib_path->parent->parent->child('bin');
push @search_dirs, $lib_path->parent->sibling('bin'); # Some layouts differ
# Search for the DLL
for my $dir (@search_dirs) {
next unless -d $dir;
my $d = path($dir);
lib/Alien/Xrepo.pod view on Meta::CPAN
my $lz4 = $repo->install('lz4');
my $ffi = FFI::Platypus->new;
$ffi->lib( $lz4->libpath );
$ffi->attach( 'LZ4_versionString', [] => 'string' );
say 'LZ4 version: ' . LZ4_versionString();
=head1 DESCRIPTION
This module acts as an intelligent bridge between Perl and the C<xrepo> package manager.
While L<Affix> or L<FFI::Platypus> or L<Inline::C> can handle the binding or linking to native functions, Alien::Xrepo
handles the B<acquisition> of the libraries containing those functions. It automates the entire dependency lifecycle:
=over
=item 1. Provisioning:
Downloads and installs libraries (C<libpng>, C<openssl>, etc.) via C<xrepo>, handling version constraints and custom
repository lookups.
=item 2. Configuration:
lib/Alien/Xrepo.pod view on Meta::CPAN
supports cross-compilation parameters (platform, architecture, toolchains).
=item 3. Introspection:
Parses the build metadata to locate the exact absolute paths to the runtime binaries (C<.dll>, C<.so>, C<.dylib>) and
header files, abstracting away operating system filesystem differences.
=back
This eliminates the need for manual compilation steps or hard coding paths in your Perl scripts, making your FFI
bindings or XS wrappers portable and reproducible.
=head1 CONSTRUCTOR
=head2 C<new>
my $repo = Alien::Xrepo->new( verbose => 1 );
Creates a new instance.
=over
( run in 1.245 second using v1.01-cache-2.11-cpan-2398b32b56e )