use 5.010;
use alienfile;
use Sort::Versions;
use Path::Tiny qw /path/;
my $on_windows = $^O =~ /mswin/i;
my $on_automated_rig
= $ENV{PERL_CPAN_REPORTER_DIR}
|| $ENV{PERL_CPAN_REPORTER_CONFIG}
|| $ENV{AUTOMATED_TESTING}
|| $ENV{TRAVIS}
|| $ENV{APPVEYOR}
|| $ENV{CI};
use Cwd;
my $base_dir = getcwd();
use Alien::proj;
use Alien::sqlite;
use Alien::freexl;
use Alien::geos::af;
my @alien_deps = qw( Alien::sqlite Alien::proj Alien::freexl Alien::geos::af );
my $sep_char = $on_windows ? ';' : ':';
$ENV{PATH} .= $sep_char
. join ($sep_char,
Alien::sqlite->bin_dir,
Alien::proj->bin_dir,
Alien::freexl->bin_dir,
Alien::geos::af->bin_dir,
);
plugin 'Build::SearchDep' => (
aliens => [@alien_deps],
public_I => 1,
public_l => 1,
);
# make libtool noisy for debug purposes
#$ENV{LTFLAGS} = "--debug --verbose" if $on_windows;
my $min_target_version = '5.0.0';
plugin 'PkgConfig' => (
pkg_name => 'spatialite',
minimum_version => $min_target_version,
);
share {
my $with_local = '';
my $with_cpp11 = '';
start_url 'http://www.gaia-gis.it/gaia-sins/libspatialite-sources/';
#start_url "file://$base_dir"; # debug
plugin Download => (
filter => qr/^libspatialite-([0-9\.]+[a-z]?)\.tar\.gz$/,
version => qr/^libspatialite-([0-9\.]+[a-z]?)\.tar\.gz$/,
);
my $lib_version = get_lib_version() // 'not yet defined';
say "Downloaded spatialite version is $lib_version";
plugin Extract => (format => 'tar.gz');
plugin 'Build::Autoconf' => ();
plugin 'PkgConfig::PPWrapper';
my $build_static = ($^O =~ /mswin/i) ? '' : '--disable-shared';
#$build_static = '';
#$build_static = '--enable-static=no'; # override - needed? leftover from gdal
$build_static = '--enable-shared=yes';
#$build_static = '' if $ENV{FORCE_DYNAMIC};
# most of these are crude
# we can enable librttopo when we have an alien for it
my $extra_build_args
= ($on_windows ? '--target=mingw32 ' : '')
. join ' ', (qw /
--enable-libxml2=no
--enable-examples=no
--enable-minizip=no
--disable-rttopo
--disable-gcp
/);
# see if this helps with cirrus bsd builds
#$ENV{SQLITE3_CFLAGS} = Alien::sqlite->cflags;
#$ENV{SQLITE3_LIBS} = Alien::sqlite->libs;
#say "sqlite cflags: " . Alien::sqlite->cflags;
#say "sqlite libs: " . Alien::sqlite->libs;
if ($^O =~ /bsd/) {
plugin 'Build::Make' => 'gmake';
if (-d '/usr/local') {
$with_local = ' --with-local=/usr/local ';
}
if (!-e '/usr/local/include/sqlite3.h' && Alien::sqlite->install_type eq 'system') {
warn '/usr/local/include/sqlite3.h does not exist, '
. 'you might need to install the sqlite package for your system, '
. 'or install a share version of Alien::sqlite';
}
}
elsif ($^O =~ /dragonfly/) {
# might need to be combined with bsd check above
# but not sure if /usr/local is needed yet
plugin 'Build::Make' => 'gmake';
}
my $make_cmd = '%{make}';
my $make_inst_cmd = '%{make} install';
my @make_clean;
# try not to exceed the cpan-testers log limits
if ($on_automated_rig) {
say "Running under CI or automated testing";
$make_cmd .= q/ | perl -ne "BEGIN {$|=1; open our $log, q|>|, q|build.log|}; print qq|\n| if 0 == ($. %% 100); print q|.|; print {$log} $_;" || type build.log/;
$make_inst_cmd .= q/ | perl -ne "BEGIN {$|=1; open our $log, q|>|, q|install.log|}; print qq|\n| if 0 == ($. %% 100); print q|.|; print {$log} $_;" || type install.log/;
if (!$on_windows) {
$make_cmd =~ s/%%/%/;
$make_cmd =~ s/type/cat/;
$make_cmd =~ s/"/'/g;
$make_inst_cmd =~ s/%%/%/;
$make_inst_cmd =~ s/type/cat/;
$make_inst_cmd =~ s/"/'/g;
}
# clean up the build dir on cpan testers etc
plugin 'Cleanse::BuildDir';
}
meta->around_hook( build => \&set_compiler_flags );
meta->around_hook(
build => sub {
my ($orig, $build, @args) = @_;
$build->log("Setting CCACHE_BASEDIR to " . getcwd());
local $ENV{CCACHE_BASEDIR} = getcwd();
$orig->($build, @args);
}
);
build [
"%{configure} $with_local $with_cpp11 $build_static $extra_build_args",
\&pause,
$make_cmd,
\&patch_rpaths,
\&rename_la_files,
$make_inst_cmd,
#@make_clean
];
};
sub rename_la_files {
# need to return if not share
return if !$on_windows;
use File::Find::Rule;
my @la_files
= File::Find::Rule->file()
->name( '*.la' )
->in( '.' );
foreach my $file (@la_files) {
Alien::Build->log("Renaming $file so it will not interfere with gdal compilation");
rename $file, $file . '.bak';
}
}
# should be a gather hook working on the stage dir
sub patch_rpaths {
my ($build) = @_;
# only run on unices - incomplete check but
# I don't think aliens work on VMS or zOS
return if ($on_windows or $^O =~ /darwin/i);
my $h = get_alien_state_hash();
my $install_path = $h->{install}{prefix};
return if !defined $install_path;
my @alien_rpaths;
for my $alien (@alien_deps) {
next if not $alien->install_type('share');
push @alien_rpaths, $alien->dist_dir . '/lib';
}
if (!@alien_rpaths) {
$build->log('No shared alien deps found, not updating rpaths');
return;
}
my $origin_string = $^O =~ /darwin/ ? '@loader_path' : '${ORIGIN}';
my $alien_rpath_text
= join ':', (
(map {$origin_string . '/../' . path ($_)->relative($install_path)->stringify} @alien_rpaths),
@alien_rpaths
);
$build->log ("Prepending rpaths with $alien_rpath_text");
use File::Find::Rule;
my (@so_files)
= grep {not -l $_}
File::Find::Rule
->file()
->name( qr/^(lib|mod_)spatialite.so.?/ )
->in( getcwd() );
eval 'require Alien::patchelf'
or do {
warn 'Unable to load Alien::patchelf ($@), cannot update rpaths';
return;
};
my $pe = Alien::patchelf->new;
foreach my $so_file (@so_files) {
my ($old_rpath, $result, $stderr, @errors);
($old_rpath, $stderr, @errors)
= $pe->patchelf ('--print-rpath', $so_file);
$old_rpath //= '';
# prepend our paths
my $rpath = $alien_rpath_text . ($old_rpath ? (':' . $old_rpath) : '');
$build->log("Updating rpath for $so_file to $rpath, was $old_rpath");
($result, $stderr, @errors)
= $pe->patchelf ('--set-rpath', $rpath, $so_file);
warn $stderr if $stderr;
}
return;
}
sub set_compiler_flags {
my ($orig, $build, @args) = @_;
local $ENV{CFLAGS} = "-O2 " . ($ENV{CFLAGS} // '');
local $ENV{CXXFLAGS} = '-O2 ' . ($ENV{CXXFLAGS} // '');
$build->log ("Setting compiler flag env vars to -O2");
$orig->($build, @args);
}
sub pause {
return; # re-enable in case of debug
return if $on_automated_rig;
return if !$on_windows;
say "CONTINUE?";
my $response = <>;
while (not $response =~ /yes/) {
$response = <>;
}
}
sub get_lib_version {
my $h = get_alien_state_hash();
return $h->{runtime}{version};
}
sub get_alien_state_hash {
use JSON::PP;
my $root = "$base_dir/_alien";
my $f = "$root/state.json";
my $h = {};
if (-e $f) {
open my $fh, '<', $f or die $!;
my $d = do {
local $/ = undef;
<$fh>;
};
$h = JSON::PP::decode_json($d);
}
return $h;
}