Alien-Xmake
view release on metacpan or search on metacpan
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,
linkdirs => $linkdirs,
links => $info->{links} // [],
license => $info->{license} // (),
shared => $info->{shared} // 0,
static => $info->{static} // 0,
version => $info->{version} // ()
);
}
# 2. Heuristic to find the Runtime Library (DLL/SO/DyLib) for FFI
my $runtime_lib;
if ( $^O eq 'MSWin32' ) {
# Check if the DLL is already in libfiles (MinGW often does this)
($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);
# Exact match: zlib.lib -> zlib.dll
my $try = $d->child("$basename.dll");
if ( $try->exists ) { $runtime_lib = $try->stringify; last; }
# MSVC vs MinGW naming: libpng.lib -> libpng16.dll or png.dll
# Scan directory for anything starting with the basename
my ($fuzzy) = grep { /^$basename/i && /\.dll$/i } map { $_->basename } $d->children;
if ($fuzzy) { $runtime_lib = $d->child($fuzzy)->stringify; last; }
}
}
}
}
elsif ( $^O eq 'darwin' ) {
# macOS: Prefer .dylib, then .so
($runtime_lib) = grep {/\.dylib$/i} @$libfiles;
($runtime_lib) //= grep {/\.so$/i} @$libfiles;
}
else {
# Linux/BSD: Prefer .so, .so.x.y, .so.x
($runtime_lib) = grep {/\.so(\.|-|\d|$)/} @$libfiles;
}
# Fallback and Logging
unless ($runtime_lib) {
# If we asked for shared but couldn't find a runtime binary, log a warning.
# We fall back to the first file (likely a static .a/.lib) so that
# XS builds might still work, even if Affix or FFI::Platypus will fail.
if ( $info->{shared} // 0 ) {
$self->blah('[!] Warning: Package is marked "shared" but no Runtime Binary (dll/so/dylib) was detected.');
$self->blah( '[!] Libfiles returned: ' . join( ', ', @$libfiles ) );
}
$runtime_lib = $libfiles->[0];
}
$self->blah( '[*] Identified runtime library: ' . $runtime_lib ) if $runtime_lib;
return Alien::Xrepo::PackageInfo->new(
includedirs => $incdirs,
libfiles => $libfiles,
libpath => $runtime_lib,
linkdirs => $linkdirs,
links => $info->{links} // [],
license => $info->{license} // (),
shared => $info->{shared} // 0,
static => $info->{static} // 0,
version => $info->{version} // ()
);
}
};
1;
( run in 0.727 second using v1.01-cache-2.11-cpan-df04353d9ac )