The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# This Makefile.PL for MarpaX-ESLIF was generated by
# Dist::Zilla::Plugin::MakeMaker::Awesome 0.39.
# Don't edit it but the dist.ini and plugins used to construct it.

use strict;
use warnings;

use 5.008;
use ExtUtils::MakeMaker 7.20;

BEGIN {
  use File::Spec;                     # Formally it is not necessary I believe to do it here
  # Make sure we have our 'inc' directory in the perl search path
  my $inc_dir = File::Spec->catdir(File::Spec->curdir, 'inc');
  push(@INC, $inc_dir);
  #
  # ExtUtils::CppGuess does not install everywhere.
  # This is why we provide it explicitely, we are ok if it fails at run-time
  # (eg. on solaris).
  #
  eval 'use ExtUtils::CppGuess; 1;' || die "$@";
}
use Config;
use Config::AutoConf;
use ExtUtils::CBuilder;
use ExtUtils::Constant qw /constant_types C_constant XS_constant autoload/;
use File::Basename;
use File::Find;
use IO::Handle;
use IPC::Run qw/run/;
use Perl::OSType qw/is_os_type/;
use Try::Tiny;

autoflush STDOUT 1;

#
# Our distribution have both C and CPP files, and we want to make sure that modifying
# CFLAGS will not affect cpp files. Since we require a version of ExtUtils::CBuilder
# that support the environment variables, explicitely setting the environment variables
# from default ExtUtils::Cbuilder will ensure cc and cpp settings will become independant
# if we are doing to modify any of them.
# We do that for linker settings as well for coherency although we will NEVER touch them.
# OTHERLDFLAGS will be specific to this makefile.
#
# Take care: with ExtUtils::CBuilder, $ENV{CFLAGS} and $ENV{LDFLAGS} are appended to default perl compile flags, not the others
#
#
my %cbuilder_config = ExtUtils::CBuilder->new()->get_config;
$ENV{CC} = $cbuilder_config{cc} // 'cc';
$ENV{CFLAGS} //= '';
$ENV{CXX} = $cbuilder_config{cxx} // $ENV{CC};
$ENV{CXXFLAGS} = $cbuilder_config{cxxflags} // $cbuilder_config{ccflags} // '';
$ENV{LD} = $cbuilder_config{ld} // $ENV{CC};
$ENV{LDFLAGS} //= '';
# OTHERLDFLAGS remains local and must affect ONLY this process, not sub-processes
my @OTHERLDFLAGS = ();
#
print "\n";
print "==========================================\n";
print "Original compilers and linker settings as per ExtUtils::CBuilder\n";
print "\n";
print "\$ENV{CC}       (overwrite) " . ($ENV{CC} // '') . "\n";
print "\$ENV{CFLAGS}   (   append) " . ($ENV{CFLAGS} // '') . "\n";
print "\$ENV{CXX}      (overwrite) " . ($ENV{CXX} // '') . "\n";
print "\$ENV{CXXFLAGS} (overwrite) " . ($ENV{CXXFLAGS} // '') . "\n";
print "\$ENV{LD}       (overwrite) " . ($ENV{LD} // '') . "\n";
print "\$ENV{LDFLAGS}  (   append) " . ($ENV{LDFLAGS} // '') . "\n";
print "==========================================\n";
print "\n";

my $ac = Config::AutoConf->new();
$ac->check_cc;

# -------------
# CC and CFLAGS
# --------------
#
if (is_os_type('Windows')) {
  print "# Windows platform: in case of MINGW headers, force -D__NO_INLINE__\n";
  $ENV{CFLAGS} .= ' -D__NO_INLINE__';
  $ENV{CXXFLAGS} .= ' -D__NO_INLINE__';
}

#
# When the compiler is clang, there is a bug with inlining, c.f. for example
# https://sourceforge.net/p/resil/tickets/6/
#
# if (is_os_type('Unix', 'darwin'))
{
  $ac->msg_checking(sprintf "if this is clang compiler");
  if ($ac->link_if_else("#ifndef __clang__\n#error \"this is not clang compiler\"\n#endif\nint main() { return 0; }")) {
      $ac->msg_result('yes');
      #
      # C.f. http://clang.llvm.org/compatibility.html#inline
      #      https://bugzilla.mozilla.org/show_bug.cgi?id=917526
      #
      $ac->msg_notice("Adding -std=gnu89 to CFLAGS for inline semantics");
      $ENV{CFLAGS} .= ' -std=gnu89';
  } else {
      $ac->msg_result('no');
  }
}

# ----------------
# CXX and CXXFLAGS
# ----------------
try {
   my ($cxx_guess, $extra_cxxflags_guess, $extra_ldflags_guess) = guess_compiler();
   $ENV{CXX} = $cxx_guess;
   $ENV{CXXFLAGS} = ($cbuilder_config{ccflags} // '') . " $extra_cxxflags_guess";
   push(@OTHERLDFLAGS, $extra_ldflags_guess) if $extra_ldflags_guess;
} catch {
   $ac->msg_checking(sprintf "if this is solaris compiler");
   if ($ac->link_if_else("#if defined(__sun) && defined(__SVR4)\n#else\n#error \"this is not solaris compiler\"\n#endif\nint main() { return 0; }")) {
      $ac->msg_result('yes');
      $ac->msg_notice("Forcing CXX to CC");
      $ENV{CXX} = 'CC';
      # We know that ExtUtils::CBuilder will get that wrong...
      # Since a cpp compiler can always compile c code, it is quite safe to assume that the cpp compiler shipped by the same c compiler vendor will accept all CFLAGS
      $ac->msg_notice("Forcing CXXFLAGS to original perl CFLAGS");
      $ENV{CXXFLAGS} = $cbuilder_config{ccflags} // '';
      $ac->msg_notice("Adding -lCrun to OTHERLDFLAGS");
      push(@OTHERLDFLAGS, '-lCrun');
  } else {
      $ac->msg_result('no');
  }
};

# ---------------
# iconv location
# ---------------
#
# On non-Windows platforms we have to check if iconv is in libc or not -;
# On windows it is using dlfcn-win32 that will imply a dependency on psapi. We verify this library is available
#
if (! is_os_type('Windows')) {
  foreach my $this_lib ('', 'iconv', 'iconv-2') {
    $ac->msg_checking(sprintf "if iconv is in %s library", $this_lib || 'standard');
    my $conftest = $ac->lang_build_program("#include <stdlib.h>\n#include <iconv.h>", "{iconv_t cd; iconv(cd, NULL, NULL, NULL, NULL);}");
    $ac->push_libraries($this_lib) if $this_lib;
    if ($ac->link_if_else($conftest)) {
      $ac->msg_result('yes');
      if ($this_lib) {
        my $found_lib = "-l${this_lib}";
        $ac->msg_notice("Adding $found_lib to OTHERLDFLAGS");
        push(@OTHERLDFLAGS, $found_lib);
      }
      last;
    } else {
      $ac->msg_result('no');
    }
  }
} else {
  print "# Determining the need for -lpsapi\n";
  $ac->push_libraries('psapi');
  if ($ac->link_if_else("#include <windows.h>\n#include <psapi.h>\nint main() { EnumProcessModules(NULL, NULL, 0, NULL); }")) {
    if (basename($Config{cc}) =~ /^cl/i) {
      $ac->msg_notice("Adding psapi.lib to OTHERLDFLAGS");
      push(@OTHERLDFLAGS, "psapi.lib");
    } else {
      $ac->msg_notice("Adding -lpsapi to OTHERLDFLAGS");
      push(@OTHERLDFLAGS, "-lpsapi");
    }
  }
}

my $OTHERLDFLAGS = join(' ', @OTHERLDFLAGS);
print "\n";
print "==========================================\n";
print "Tweaked compilers and linker settings\n";
print "\n";
print "\$ENV{CC}       (overwrite) " . ($ENV{CC} // '') . "\n";
print "\$ENV{CFLAGS}   (   append) " . ($ENV{CFLAGS} // '') . "\n";
print "\$ENV{CXX}      (overwrite) " . ($ENV{CXX} // '') . "\n";
print "\$ENV{CXXFLAGS} (overwrite) " . ($ENV{CXXFLAGS} // '') . "\n";
print "\$ENV{LD}       (overwrite) " . ($ENV{LD} // '') . "\n";
print "\$ENV{LDFLAGS}  (   append) " . ($ENV{LDFLAGS} // '') . "\n";
print "OTHERLDFLAGS               $OTHERLDFLAGS\n";
print "==========================================\n";
print "\n";

my $fh;
print "Generating constant types\n";
open($fh, '>', 'c-constant-types.inc') || die "Cannot open c-constant-types.inc, $!";
print $fh constant_types();
close($fh) || warn "Failed to close c-constant-types.inc, $!";

my %types = ( 'event' => { pkg => 'MarpaX::ESLIF::Event::Type', constants => [qw/MARPAESLIF_EVENTTYPE_NONE MARPAESLIF_EVENTTYPE_COMPLETED MARPAESLIF_EVENTTYPE_NULLED MARPAESLIF_EVENTTYPE_PREDICTED MARPAESLIF_EVENTTYPE_BEFORE MARPAESLIF_EVENTTYPE_AFTER MARPAESLIF_EVENTTYPE_EXHAUSTED MARPAESLIF_EVENTTYPE_DISCARD/] }, 'value' => { pkg => 'MarpaX::ESLIF::Value::Type', constants => [qw/MARPAESLIF_VALUE_TYPE_UNDEF MARPAESLIF_VALUE_TYPE_CHAR MARPAESLIF_VALUE_TYPE_SHORT MARPAESLIF_VALUE_TYPE_INT MARPAESLIF_VALUE_TYPE_LONG MARPAESLIF_VALUE_TYPE_FLOAT MARPAESLIF_VALUE_TYPE_DOUBLE MARPAESLIF_VALUE_TYPE_PTR MARPAESLIF_VALUE_TYPE_ARRAY/] }, 'loggerLevel' => { pkg => 'MarpaX::ESLIF::Logger::Level', constants => [qw/GENERICLOGGER_LOGLEVEL_TRACE GENERICLOGGER_LOGLEVEL_DEBUG GENERICLOGGER_LOGLEVEL_INFO GENERICLOGGER_LOGLEVEL_NOTICE GENERICLOGGER_LOGLEVEL_WARNING GENERICLOGGER_LOGLEVEL_ERROR GENERICLOGGER_LOGLEVEL_CRITICAL GENERICLOGGER_LOGLEVEL_ALERT GENERICLOGGER_LOGLEVEL_EMERGENCY/] }, 'rulePropertyBitSet' => { pkg => 'MarpaX::ESLIF::Rule::PropertyBitSet', constants => [qw/MARPAESLIF_RULE_IS_ACCESSIBLE MARPAESLIF_RULE_IS_NULLABLE MARPAESLIF_RULE_IS_NULLING MARPAESLIF_RULE_IS_LOOP MARPAESLIF_RULE_IS_PRODUCTIVE/] }, 'symbolPropertyBitSet' => { pkg => 'MarpaX::ESLIF::Symbol::PropertyBitSet', constants => [qw/MARPAESLIF_SYMBOL_IS_ACCESSIBLE MARPAESLIF_SYMBOL_IS_NULLABLE MARPAESLIF_SYMBOL_IS_NULLING MARPAESLIF_SYMBOL_IS_PRODUCTIVE MARPAESLIF_SYMBOL_IS_START MARPAESLIF_SYMBOL_IS_TERMINAL/] }, 'symbol' => { pkg => 'MarpaX::ESLIF::Symbol::Type', constants => [qw/MARPAESLIF_SYMBOLTYPE_TERMINAL MARPAESLIF_SYMBOLTYPE_META/] });

foreach (sort keys %types) {
  my $pkg = $types{$_}->{pkg};
  print "Generating $pkg C $_ types\n";
  open($fh, '>', "c-$_-types.inc") || die "Cannot open c-$_-types.inc, $!";
  print $fh C_constant($pkg, "${_}_constant", undef, undef, undef, undef, @{$types{$_}->{constants}});
  close($fh) || warn "Failed to close c-$_-types.inc, $!";

  # This is a bit vicious but in our case these are NOT macros but ENUMS !
  # We know what were are doing and replace all #ifdef MARPAESLIF_xxx and #ifdef GENERICLOGGER_xxx by #if 1

  print "Tweaking $pkg C $_ types to work with enums\n";
  open($fh, '<', "c-$_-types.inc") || die "Failed to open c-$_-types.inc, $!";
  my $content = do { local $/; <$fh> };
  close($fh) || warn "Failed to close c-$_-types.inc, $!";
  $content =~ s/^#\s*ifdef\s+(?:MARPAESLIF_|GENERICLOGGER_).*?$/#if 1/smg;
  open($fh, '>', "c-$_-types.inc") || die "Failed to open c-$_-types.inc, $!";
  print $fh $content;
  close($fh) || warn "Failed to close c-$_-types.inc, $!";

  print "Generating $pkg XS $_ types\n";
  open($fh, '>', "xs-$_-types.inc") || die "Cannot open xs-$_-types.inc, $!";
  print $fh XS_constant($pkg, 'IV', 'constant', "${_}_constant");
  close($fh) || warn "Failed to close xs-$_-types.inc, $!";

  print "Generating $pkg AUTOLOAD\n";
  my $autoload = autoload($pkg, '5.10', 1);

  my @pkg = split(/::/, $pkg);
  $pkg[-1] .= '.pm';
  my $pkgfile = File::Spec->catfile('lib', @pkg);
  print "Pushing AUTOLOAD into $pkgfile\n";
  open($fh, '<', $pkgfile) || die "Failed to open $pkgfile, $!";
  $content = do { local $/; <$fh> };
  close($fh) || warn "Failed to close $pkgfile, $!";
  $content =~ s/^#\s*AUTOLOAD.*?$/\n$autoload\n/sm;
  open($fh, '>', $pkgfile) || die "Failed to open $pkgfile, $!";
  print $fh $content;
  close($fh) || warn "Failed to close $pkgfile, $!";
}

run([$^X, File::Spec->catfile('src', 'CMakeObjects.PL')]) or die "src/CMakeObjects.PL: $?";
my @ldfrom = ();
my %unique = ();

find({ wanted => sub {
                       if (-f $_) {
                         my $cpath = File::Spec->canonpath($_);
                         if (basename(dirname($cpath)) eq 'obj4perl') {
                           if (! ${unique}{basename($cpath)}++) {
                             push(@ldfrom, $cpath);
                           }
                         }
                       }
                     },
      no_chdir => 1 }, File::Spec->curdir);

print "Linking ESLIF\$(OBJ_EXT) using: @ldfrom\n";

#
# Inspired by Inline-CPP-0.74/inc/ILCPPConfig/CompilerGuess.pm
#
sub guess_compiler {

  my ($cxx_guess, $extra_cxxflags_guess, $extra_ldflags_guess, $guesser, %configuration);

  if( $Config::Config{osname} eq 'freebsd'
    && $Config::Config{osvers} =~ /^(\d+)/
    && $1 >= 10
  ){
    if( $ENV{CC} =~ /\bclang\b/ ) {
      $cxx_guess = $ENV{CC};
      $cxx_guess =~ s/\bclang\b/clang++/;
    } else {
      $cxx_guess = 'clang++';
    }
    $extra_cxxflags_guess = '';     # Extra compile flag moved to compiler command -;
    $extra_ldflags_guess = '-lc++'; # Extra linker flag
  }
  else {
    $guesser = ExtUtils::CppGuess->new(cc => $ENV{CC});
    %configuration = $guesser->module_build_options;
    $extra_cxxflags_guess = $configuration{extra_compiler_flags};
    $extra_ldflags_guess = $configuration{extra_linker_flags};
    if( $guesser->is_gcc ) {
      if( $ENV{CC} =~ /\bclang\b/ ) {
        $cxx_guess = $ENV{CC};
        $cxx_guess =~ s/\bclang\b/clang++/;
      } else {
        if( $ENV{CC} =~ /\bgcc\b/ ) {
          $cxx_guess = $ENV{CC};
          $cxx_guess =~ s/\bgcc\b/g++/;
        } else {
          $cxx_guess = 'g++';
        }
      }
      $extra_cxxflags_guess = '';    # Extra compile flag moved to compiler command, extra linker flag untouched -;
    }

    ( $cxx_guess, $extra_cxxflags_guess, $extra_ldflags_guess ) = map { _trim_whitespace($_) } ( $cxx_guess, $extra_cxxflags_guess, $extra_ldflags_guess );
  }
  return ( $cxx_guess, $extra_cxxflags_guess, $extra_ldflags_guess );
}

sub _trim_whitespace {
  my $string = shift;
  $string =~ s/^\s+|\s+$//g;
  return $string;
}

my %WriteMakefileArgs = (
  "ABSTRACT" => "ESLIF is Extended ScanLess InterFace",
  "AUTHOR" => "Jean-Damien Durand <jeandamiendurand\@free.fr>",
  "CONFIGURE_REQUIRES" => {
    "Archive::Tar" => 0,
    "Capture::Tiny" => 0,
    "Config" => 0,
    "Config::AutoConf" => 0,
    "Config::AutoConf::INI" => 0,
    "ExtUtils::CBuilder" => "0.280224",
    "ExtUtils::Constant" => 0,
    "ExtUtils::MakeMaker" => "7.20",
    "File::Basename" => 0,
    "File::Copy" => 0,
    "File::Copy::Recursive" => 0,
    "File::Find" => 0,
    "File::Path" => 0,
    "File::Spec" => 0,
    "File::chdir" => 0,
    "IO::Handle" => 0,
    "IPC::Run" => 0,
    "POSIX" => 0,
    "Perl::OSType" => 0,
    "Try::Tiny" => 0,
    "diagnostics" => 0,
    "strict" => 0
  },
  "DISTNAME" => "MarpaX-ESLIF",
  "LICENSE" => "perl",
  "MIN_PERL_VERSION" => "5.008",
  "NAME" => "MarpaX::ESLIF",
  "PREREQ_PM" => {
    "Carp" => 0,
    "XSLoader" => 0,
    "strict" => 0,
    "vars" => 0,
    "warnings" => 0
  },
  "TEST_REQUIRES" => {
    "Encode" => 0,
    "ExtUtils::MakeMaker" => 0,
    "File::Spec" => 0,
    "File::Temp" => 0,
    "IO::Handle" => 0,
    "IPC::Open3" => 0,
    "Log::Any" => 0,
    "Log::Any::Adapter" => 0,
    "Log::Any::Adapter::Log4perl" => 0,
    "Log::Any::Adapter::Util" => "1.03",
    "Log::Log4perl" => "1.32",
    "Test::Deep::NoTest" => 0,
    "Test::More" => 0,
    "Test::More::UTF8" => 0,
    "Try::Tiny" => 0,
    "diagnostics" => 0,
    "open" => 0,
    "threads" => 0,
    "utf8" => 0
  },
  "VERSION" => "2.0.31",
  "test" => {
    "TESTS" => "t/*.t"
  }
);

%WriteMakefileArgs = (
    %WriteMakefileArgs,
    OBJECT => 'ESLIF$(OBJ_EXT)',
    LDFROM => join(' ', '$(OBJECT)', @ldfrom),
    dynamic_lib => { OTHERLDFLAGS => join(' ', @OTHERLDFLAGS) },
    INC => join(' ', map { "-I$_ " } (File::Spec->catdir('src', 'output', 'include'), File::Spec->catdir('src', 'include'), File::Spec->catdir('src', 'output', '3rdparty', 'genericLogger', 'output', 'include'), File::Spec->catdir('src', 'output', '3rdparty', 'genericLogger', 'include'), File::Spec->catdir('src', 'output', '3rdparty', 'genericStack', 'include'), File::Spec->catdir('src', 'output', '3rdparty', 'genericHash', 'include') ) ),
);

my %FallbackPrereqs = (
  "Carp" => 0,
  "Encode" => 0,
  "ExtUtils::MakeMaker" => 0,
  "File::Spec" => 0,
  "File::Temp" => 0,
  "IO::Handle" => 0,
  "IPC::Open3" => 0,
  "Log::Any" => 0,
  "Log::Any::Adapter" => 0,
  "Log::Any::Adapter::Log4perl" => 0,
  "Log::Any::Adapter::Util" => "1.03",
  "Log::Log4perl" => "1.32",
  "Test::Deep::NoTest" => 0,
  "Test::More" => 0,
  "Test::More::UTF8" => 0,
  "Try::Tiny" => 0,
  "XSLoader" => 0,
  "diagnostics" => 0,
  "open" => 0,
  "strict" => 0,
  "threads" => 0,
  "utf8" => 0,
  "vars" => 0,
  "warnings" => 0
);

# inserted by Dist::Zilla::Plugin::DynamicPrereqs 0.033
use Config;
if (! $Config{usethreads}) {
  foreach (qw/PREREQ_PM BUILD_REQUIRES TEST_REQUIRES/) {
    delete($WriteMakefileArgs{$_}{Thread}) if (exists($WriteMakefileArgs{$_}));
    delete($FallbackPrereqs{$_}{Thread})   if (exists($FallbackPrereqs{$_}));
  }
}

unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
  delete $WriteMakefileArgs{TEST_REQUIRES};
  delete $WriteMakefileArgs{BUILD_REQUIRES};
  $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
}

delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
  unless eval { ExtUtils::MakeMaker->VERSION(6.52) };

WriteMakefile(%WriteMakefileArgs);