Alien-SWIProlog

 view release on metacpan or  search on metacpan

alienfile  view on Meta::CPAN

use alienfile;

use Env qw(@CMAKE_INCLUDE_PATH @CMAKE_LIBRARY_PATH);
use Config;
use DynaLoader ();
use Data::Dumper;
use File::Basename qw(dirname);

# Also need Alien::SWIProlog::Util
use lib dirname(__FILE__) . "/lib";

requires 'Path::Tiny';
requires 'File::Which';

# For system probe
requires 'List::Util', '1.33';
requires 'ExtUtils::CBuilder';

my @SWIPL_BIN_NAMES = (
	( exists $ENV{PL} ? $ENV{PL} : () ),
	( $^O =~ /Win32/ ? 'plcon' : () ),
	qw(swipl swi-prolog),
	( $^O !~ /darwin/ ? 'pl' : () ),
);

# Check for conflicting symbol PL_version.
# See <https://github.com/salva/p5-Language-Prolog-Yaswi/issues/3>,
# <https://github.com/SWI-Prolog/swipl-devel/issues/900>.
my $test_program = <<EOF;
/* checking for conflicting symbol */
extern int PL_version;

#include <SWI-Prolog.h>

int main(int argc, char *argv[]) {
	return 0;
}
EOF

my $PLVARS;
my $PL;
my $PL_path;

sub find_PL {
	my $build = shift;

	for $PL (@SWIPL_BIN_NAMES) {
		$PL_path = File::Which::which($PL) or next;
		$build->log("Trying SWI-Prolog binary $PL ($PL_path)");
		$PLVARS = Alien::SWIProlog::Util::get_plvars($PL);
		keys %$PLVARS and last;
	};
}

probe sub {
	my $build = shift;
	eval 'require Alien::SWIProlog::Util';

	local $Data::Dumper::Terse = 1;
	local $Data::Dumper::Sortkeys = 1;

	find_PL($build);

	# when not found
	return 'share' unless keys %$PLVARS;

	$build->log( Dumper($PLVARS) );

	my %threads_support = (
		swipl_threads => $PLVARS->{PLTHREADS} eq 'yes',
		perl_usethreads => defined($Config::Config{usethreads}),
		perl_useithreads => defined($Config::Config{useithreads}),
	);

	my $all_threads = List::Util::all(
		sub { $threads_support{$_} },
		keys %threads_support );
	my $all_nonthreads = List::Util::all(
		sub { ! $threads_support{$_} },
		keys %threads_support );

	unless( $all_threads || $all_nonthreads ) {
		$build->log(
			"Threading models of SWI-Prolog and Perl do not match: "
			. Dumper(\%threads_support)
		);
		return 'share';
	}

	my $prop = Alien::SWIProlog::Util::plvars_to_props($PL_path, $PLVARS);

	eval {
		require ExtUtils::CBuilder;
		my $b = ExtUtils::CBuilder->new();
		my $src = Path::Tiny->tempfile( SUFFIX => '.c' );
		$src->spew_utf8($test_program);
		$build->log('Compiling/linking test program');
		my $obj = $b->compile(
			source => "$src",
			extra_compiler_flags => $prop->{cflags},
		);
		my $exe = $b->link_executable(
			objects => $obj,
			extra_linker_flags   => $prop->{libs},
		);
		$build->log('Compiling/linking successful');
		1;
	} and return 'system';

	$build->log('Compiling/linking unsuccessful');
	return 'share';
};

sys {
	gather sub {
		my ($build) = @_;
		eval 'require Alien::SWIProlog::Util';
		find_PL($build);
		my $prop = Alien::SWIProlog::Util::plvars_to_props($PL_path, $PLVARS);
		$build->runtime_prop->{$_} = $prop->{$_} for keys %$prop;



( run in 0.493 second using v1.01-cache-2.11-cpan-13bb782fe5a )