Alien-geos-af

 view release on metacpan or  search on metacpan

alienfile  view on Meta::CPAN

        $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 => sub {
      my ($orig, $build, @args) = @_;
      $build->log("Setting CCACHE_BASEDIR to " . getcwd());
      local $ENV{CCACHE_BASEDIR} = getcwd();
      $orig->($build, @args);
    }
  );


  #  might fix some rpath issues?
  #  https://github.com/OSGeo/gdal/issues/5413#issuecomment-1060286925
  my @rpath =
    $on_windows ? ()
    : $^O =~ /darwin/
      ? q{-DCMAKE_INSTALL_RPATH='@loader_path'}
      : q{-DCMAKE_INSTALL_RPATH='\$ORIGIN'};

  my $cmake_cmd = [
    '%{cmake}',
    -G => '%{cmake_generator}',
    '-DCMAKE_MAKE_PROGRAM=%{make}',
    '-DBUILD_DOCUMENTATION=NO',
    #"-DGEOS_ENABLE_TESTS=$run_tests_bool_text", #  seems not be in the source tree?
    "-DBUILD_TESTING:BOOL=$run_tests_bool_text",
    #'-DCMAKE_BUILD_TYPE=Release',
    '-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true',
    '-DCMAKE_INSTALL_PREFIX:PATH=%{.install.prefix}',
    @rpath,
    '-DBUILD_GEOSOP=OFF',
    '..'
  ];
  
  #say join ' ', @$cmake_cmd;

  build [
    #\&set_rectangle_intersection,  #  disable
    #"%{configure} $with_local $with_cpp11 $build_static",
    #'echo %{make}',
    #\&pause,
    \&update_hilbert_encoder_h,
    'mkdir _build',
    'cd _build',
    $cmake_cmd,
    $make_cmd,
    ($run_tests ? '%{make} test' : ()),
    #\&pause,
    \&update_geos_config,
    $make_inst_cmd,
    \&rename_la_files,
  ];

};


gather [
  \&copy_geos_c_dll,
  #\&pause,
  #  get all the geos-config fields
  \&set_runtime_props_from_config,
];

#  needed for gcc-13
sub update_hilbert_encoder_h {
  my $build = shift;

  my @files
    = File::Find::Rule->file()
                      ->name( 'HilbertEncoder.h' )
                      ->in( '.' );

  log ("Updating " . path ($files[0])->absolute);
  my $replace = '#include <cstdint>';
  path($files[0])->edit (
    sub {
      s{(\Qinclude <vector>\E)([\r\n]+)}{$1\n$replace$2}xms;
    }
  );

}

#  a bit brute force
sub copy_geos_c_dll {
  my $build = shift;
  
  return unless $^O eq 'MSWin32';
  
  log 'Searching for libgeos_c.dll';

  my @files
    = File::Find::Rule->file()
                      ->name( 'libgeos_c.dll' )
                      ->in( '.' );

  foreach my $from (@files) {
    my $to = Path::Tiny->new($from)->parent->child('libgeos_c-1.dll');
    if (!$to->exists) {
      log "copying $from to $to";
      eval {File::Copy::copy ("$from", "$to")};
      log $@ if $@;
    }
  }
}


sub set_rectangle_intersection {
    my ($build) = @_;
    
    #  disable as we get test failures in Biodiverse,
    #  which is probably for the same reasons this is
    #  disabled in GEOS in the first place
    return;  
    
    return if $build->install_type ne 'share';

    say 'set_rectangle_intersection: Currently in ' . getcwd();
    
    use File::Find::Rule;
    use Path::Tiny qw /path/;
    my (@files)
      = File::Find::Rule
                ->file()
                ->name( 'Geometry.cpp' )
                ->in( $base_dir );
    #  loop is brute force
    foreach my $file (@files) {
        say "Modifying file $file";
        path($file)->edit (
            sub {
              s{^//(#define USE_RECTANGLE_INTERSECTION 1)}{$1}ms;
            }
        );
    }
}

sub update_geos_config {
    my ($build) = @_;

    $build->log ('updating geos-config to use dynamic base dir');
    use File::Find::Rule;
    my ($geos_config)
      = $build->install_type eq 'share'
          ? File::Find::Rule
                ->file()
                ->name( 'geos-config' )
                ->in( getcwd() )
          : 'geos-config';

    $build->log("Updating $geos_config");

    open my $fh , '<', $geos_config
      or die "Could not open $geos_config for reading, $!";
    my $file_contents;

    while (defined (my $line = <$fh>)) {
        if ($line =~ /^\s*prefix=/) {
            #  MSYS1 does not have realpath
            my $part1
              = q{BASEPATH=`perl -MCwd -MFile::Basename -e"print File::Basename::dirname(Cwd::abs_path (qq{$0}))"`};
            #  some variants use an escape function
            my $part2 = $line =~ /`escape/
              ? 'prefix=`escape "${BASEPATH}"`'
              : 'prefix="${BASEPATH}"';
            my $part3 = 'prefix=$(dirname ${prefix})';
            $line = "$part1\n$part2\n$part3\n";
        }
        $file_contents .= $line;
    }
    $fh->close;
    my $permissions = (stat ($geos_config))[2];
    rename $geos_config, "$geos_config.bak";
    open my $ofh, '>', $geos_config
      or die "Could not open $geos_config for writing, $!";
    print {$ofh} $file_contents;
    $ofh->close or die $!;
    #  make sure we get the same permissions
    chmod $permissions, $geos_config or die $!;
    return;
}

sub set_runtime_props_from_config {
    my ($build) = @_;

    $build->log ('set_runtime_props_from_config: Currently in ' . getcwd());

    $build->log("UPDATING PKG_CONFIG_PATH");
    
    use Env qw /@PKG_CONFIG_PATH @PATH/;
    use Capture::Tiny;
    use Path::Tiny;

    # should use proper Alien::Build methods to get location of file     
    use File::Find::Rule;
    my ($pk_config)
      = $build->install_type eq 'share'
          ? File::Find::Rule
                ->file()
                ->name( 'geos.pc' )
                ->in( getcwd() )
          : 'geos.pc';
    
    my $pk_path = path($pk_config)->parent->stringify;
    unshift @PKG_CONFIG_PATH, $pk_path;
    $build->log("PKG_CONFIG_PATH is $ENV{PKG_CONFIG_PATH}");

    #  should use perl package api?
    my $pkgconf = File::Which::which ('pkg-config') || File::Which::which ('ppkg-config');
    foreach my $flag (qw /cflags libs static/) {
        my @cmd = ($pkgconf, "--$flag", 'geos');
        $build->log("Calling: " . join ' ', @cmd);
        my ($stdout, $stderr, @result) = Capture::Tiny::capture {system @cmd};
        $build->log("ERROR: $stderr") if $stderr;
        $build->runtime_prop->{$flag} = $stdout;
        $build->runtime_prop->{$flag} =~ s/[\r\n]+$//;  #  generic chomp
        if ($on_windows) {
            #  windowsify the paths
            $build->runtime_prop->{$flag} =~ s|(?<=-[IL])/C/|C:/|i;
        }
        if ($^O =~ /bsd/i) {
            #  maybe will help?
            $build->runtime_prop->{$flag} =~ s/-\d+$//;
        }
        $build->log ("Runtime prop $flag is " . $build->runtime_prop->{$flag});
    }
}

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) {
        say "Renaming $file so it will not interfere with gdal compilation";
        rename $file, $file . '.bak';
    }

}

sub pause {
    #return;  #  disable
    #return if !$on_windows || $on_automated_rig;

    say "CONTINUE?";
    my $response = <>;
    while (not $response =~ /yes/) {
        $response = <>;
    }
}

sub get_geos_version {
    my $h = get_alien_state_hash();
    return $h->{runtime}{version};
}

sub get_stage_dir {
    my $h = get_alien_state_hash();
    return $h->{install}{stage};
}

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;
}



( run in 0.930 second using v1.01-cache-2.11-cpan-39bf76dae61 )