The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# -*- cperl -*-
require 5.00404;
my $path = "$Config{'archlibexp'}/CORE/perl.h";
die "Cannot find '$path' have you installed $^X?\n" unless (-r $path);
print "$^X is installed in $Config{'archlibexp'} okay\n";
use Config;
use Cwd;
use Tk::MMtry;
warn "No VERSION" unless (defined $VERSION);

my %define = ();

$inc    = "";
$xlib   = "";
$define = '';
$gccopt = "";
@macro = ( macro => {} );
$is_maintainer = 0;
eval{
    $is_maintainer = (getpwuid($<))[6]
        =~ /(Nick\s+Ing-Simmons|Slaven\s+Rezic)/;
};
if (defined $Config{'gccversion'})
 {
  $ver = $Config{'gccversion'};
  if ($ver ge "2.8")
   {
    # retain author's favourite warnings if using gcc
    $gccopt .= " -Wall -Wno-implicit-int -Wno-comment -Wno-unused -D__USE_FIXED_PROTOTYPES__";
    eval
     {
      if (0 && $is_maintainer)
       {
        # This is the author - catch as many bugs as possible
        # XXX libpng causes some warnings, so this is not enabled anymore
        $gccopt .= "  -MMD -Werror -Wno-format";
       }
     }
   }
 }

if ($] >= 5.005)
 {
  # Add PPM support stuff
  push(@macro,
       ABSTRACT => 'Tk - a Graphical User Interface Toolkit',
       AUTHOR   => 'nick@ing-simmons.net (Nick Ing-Simmons)'
      );
  my $arch = ($^O eq 'MSWin32') ? $ENV{'PROCESSOR_ARCHITECTURE'} : $Config{'archname'};
  my $binloc = "BINARY_LOCATION=$arch/Tk$VERSION-PPM.tar.gz";
  if (!grep { $binloc eq $_ } @ARGV)
   {
    push(@ARGV,$binloc);
   }
  warn "PPM for perl$]\n";
 }
else
 {
  warn "No PPM for perl$]\n";
 }

$macro[1]->{WINARCH} = $win_arch;

#
# Convert perls Config info into -DXXXX for Tk
#

$define{'USE_PROTOTYPE'} = 1     if ($Config{'prototype'});
$define{'HAVE_UNISTD_H'} = 1     if ($Config{'i_unistd'});
$define{'HAVE_SYS_SELECT_H'} = 1 if ($Config{'i_sysselct'});
$define{'NO_STDLIB_H'} = 1       unless ($Config{'i_stdlib'});
if ($Config{'i_systime'})
 {
  $define{'HAVE_SYS_TIME_H'} = 1;
  if ($Config{'i_time'})
   {
    $define{'TIME_WITH_SYS_TIME'} = 1;
   }
 }
$define{'HAVE_LIMITS_H'} = 1     if ($Config{'i_limits'});
$define{'HAS_STDARG'} = 1        if ($Config{'i_stdarg'});
$define{'USE_BCOPY'} = 1         if (!$Config{'d_memmove'} && $Config{'d_bcopy'});

if (defined $Config{'selecttype'})
 {
   my $type = $Config{'selecttype'};
   $type =~ s/\s*\*\s*$//;
   $define{'SELECT_MASK'} = $type;
 }

if (!$Config{'i_unistd'} && defined $Config{'lseektype'})
 {
   my $type = $Config{'lseektype'};
   $type =~ s/\s*\*\s*$//;
   $define{'LSEEK_TYPE'} =$type;
 }

my $voidflags = $Config{'voidflags'};
my $voidused  = $Config{'defvoidused'}+0;

$define{'NOVOID'}  = 1 if (($voidflags & $voidused) != $voidused);
$define{'NOCONST'} = 1 unless ($Config{'d_const'});

#
# Hunt down X Library - first a function
#
sub lX11
{
 my $user = shift;
 foreach (@_)
  {
   # allow any of libX11.a libX11.so.* etc.
   if (-d $_)
    {
     local ($lib);
     my $pattern = "$_/libX11.*";
     $pattern .= " $_/X11$Config::Config{lib_ext}"
       if $Config::Config{osname} eq 'os2';
     foreach $lib (reverse(<$ {pattern}>))
      {
       if (-r $lib)
        {
         print "Using -L$_ to find $lib\n";
         return "-L$_"
        }
      }
    }
  }
 print "No -lX11 in ",join(' ',@_),"\n" if (@_ && $user);
 return undef;
}

sub IX11
{
 foreach (@_)
  {
   if (-d $_ && -d "$_/X11" && -r "$_/X11/Xlib.h")
    {
     print "Using -I$_ to find $_/X11/Xlib.h\n";
     return "-I$_";
    }
  }
 return undef;
}

sub Ift
{
 foreach (map { "$_/freetype2" } @_)
  {
   if (-d $_ && -d "$_/freetype" && -r "$_/freetype/freetype.h")
    {
     print "Using -I$_ to find $_/freetype/freetype.h\n";
     return "-I$_";
    }
  }
 return undef;
}

my @args = ();
my $arg;
foreach $arg (@ARGV)
 {
  if ($arg =~ /^(X11\w*|XFT)=(.*)$/)
   {
    ${"$1"} = $2;
    # Pushing these args to @ARGV will generate MakeMaker warnings
    # ("... is not a known MakeMaker parameter name") but
    # will asure that the parameters are reused when automatically
    # re-building Makefiles.
   }
  elsif ($arg eq 'VERBOSE=1')
   {
    $Tk::MMtry::VERBOSE = 1;
   }
  else
   {
    $MakefileName = $1 if ($arg =~ /^MAKEFILE=(.*)$/);
   }
  push(@args,$arg);
 }
@ARGV = @args;

# Now we have possibly $Tk::MMtry::VERBOSE set, we can
# use the try_compile stuff
if (try_compile("config/perlrx.c", ["-I$Config{'archlibexp'}/CORE"], undef, ["-c"]))
 {
  $define{'USE_NEWSTYLE_REGEXP_STRUCT'} = 1;
 }

if (try_compile("config/pmop.c", ["-I$Config{'archlibexp'}/CORE"]))
 {
  $define{'HAS_PMOP_EXTRA_FLAGS'} = 1;
 }

if (try_compile("config/pregcomp2.c",  ["-I$Config{'archlibexp'}/CORE"], undef, ["-c"]))
 {
  $define{'USE_PREGCOMP_31027'} = 1; # pregcomp after perl change 31027
 }

if (try_compile("config/regexp511.c",  ["-I$Config{'archlibexp'}/CORE"], undef, ["-c"]))
 {
  $define{'USE_REGEXP_511'} = 1; # REGEXP in perl 5.11.x
 }

if (try_compile("config/signedchar.c"))
 {
  $define{'ANSI_SIGNED_CHAR'} = 1;
 }
else
 {
  if (try_run("config/unsigned.c"))
   {
    $define{'CHAR_UNSIGNED'} = 1;
   }
 }

if (!try_compile("config/Ksprintf.c") &&
     try_compile("-DSPRINTF_RETURN_CHAR config/Ksprintf.c"))
 {
  $define{'SPRINTF_RETURN_CHAR'} = 1;
 }

if (try_compile("config/svtrv.c",  ["-I$Config{'archlibexp'}/CORE"], undef, ["-c"]))
 {
  $define{'HAS_REAL_SVT_RV'} = 1; # changed in perl 5.11.0, SVt_RV is since then defined as SVt_IV 
 }

if (try_compile("config/copstashset.c",  ["-I$Config{'archlibexp'}/CORE"], undef, ["-c"]))
 {
  $define{'CAN_COPSTASH_SET_NULL'} = 1; # this seems to work since 5.17.x, and fails with older threaded perls
 }

if ($] > 5.013002) # SvNV_nomg available
 {
  $define{'HAS_SVNV_NOMG'} = 1;
 }
if ($] >= 5.009001 || ($] >= 5.008009 && $] < 5.009)) # SvIV_nomg available
 {
  $define{'HAS_SVIV_NOMG'} = 1;
 }

if (!$IsWin32)
 {
  if (!try_compile("config/tod.c"))
   {
    my $d;
    my $def;
    foreach $d (qw(TZ NO_TZ DOTS))
     {
      if (try_compile("-DTIMEOFDAY_$d config/tod.c"))
       {
        $def = "TIMEOFDAY_$d";
        print STDERR "$d gettimeofday()\n";
        last;
       }
     }
    if (defined $def)
     {
      $define{$def} = 1;
     }
    else
     {
      print STDERR "Problem gettimeofday()\n";
     }
   }
  else
   {
    print STDERR "Generic gettimeofday()\n";
   }
 }

$win_arch or die '$win_arch not set in myConfig';

if ($win_arch eq 'x') {
  @xdirs = ();

  if (defined $X11)
    {
      my $dir = $X11;
      if (-d $dir)
	{
	  print "Looking for X in $dir\n";
	  push(@xdirs,$dir);
	}
      else
	{
	  die "X11=$dir is not a directory";
	}
    }
  else
    {
      # Find the X Library through xmkmf!
      $xmkmf = undef;
      my @exts = ("", ".cmd", ".bat");
    LOOK:
      foreach $dir (split($Config::Config{path_sep},$ENV{'PATH'})) {
	foreach $ext (@exts) {
	  if (-x "$dir/xmkmf$ext" && -r "$dir/xmkmf$ext") {
	    $xmkmf = "$dir/xmkmf$ext";
	    last LOOK;
	  }
	}
      }
      $uiline = undef;
      if (defined $xmkmf) {
	open(XMKMF,$xmkmf) || die("Can't open $xmkmf: $!\n");
	while(<XMKMF>) {
	  next unless /UseInstalled/o;
	  warn ("Odd, two lines in the $xmkmf file that have UseInstalled on them:\n$uidir$_") if defined $uiline;
	  $uidir = $_;
	}
	close(XMKMF);
	while (defined $uidir) {
	  last unless ($uidir =~ s!^.*-I(\S+)/lib/X11/config!!o);
	  $try = $1;
	  $try =~ s/'x11root'/$ENV{X11ROOT}/;
	  push(@xdirs,$try);
	}
      }
      print "$xmkmf suggests ",join(' ',@xdirs),"\n" if (@xdirs);
    }

  undef $xlib;			# Make sure

  if (defined $X11LIB)
    {
      $xlib = &lX11(1,$X11LIB)
    }
  if (!defined($xlib) && defined($X11))
    {
      $xlib = &lX11(1,"$X11/lib")
    }
  $xlib = &lX11(0,map("$_/lib",@xdirs)) unless (defined $xlib);

  # Special case for sun-machines
  unless (defined $xlib)
    {
      if ($Config{'osname'} eq 'solaris' || $Config{'osname'} eq 'sunos')
	{
	  $xlib = &lX11(0,'/usr/openwin/lib');
	}
    }

  sub chooseX11
    {
      # Aim to prefer X11R5 over X11R4 over X11
      (reverse(sort(@_)));
    }

  #
  # Prefer 64bit libraries on certain architectures
  #
  unless (defined $xlib and $Config{'archname'} =~ m/x86_64/)
    {
      $xlib = &lX11(0, chooseX11(</usr/X11*/lib64>));
    }

  #
  # If no luck there try "common" places
  #
  unless (defined $xlib)
    {
      $xlib = &lX11(0,chooseX11(</usr/X11*/lib>),chooseX11(</usr/lib/X11*>),</usr/Xfree*/lib>,'/usr/X386/lib')
    }

  #
  # Try places perl looks for libraries
  # This is now "last resort" as /lib and /usr/local/lib are so often
  # full of dubious links
  #
  unless (defined $xlib)
    {
      $xlib = &lX11(0,split(/\s+/,$Config{'libpth'}))
    }

  unless(defined $xlib)
    {
      warn "Cannot find -lX11 anywhere --- cannot build Perl/Tk\n";
      exit 0;
    }

  ($base) = $xlib =~ m#-L(.*)(?:/lib)$#x;
  if (defined $X11INC)
    {
      $xinc = &IX11("$X11INC");
    }

  $xinc = &IX11("$base/include") unless (defined $xinc);

  unless (defined $xinc)
    {
      warn "Cannot find X include files via $base/include\n";
      $xinc = &IX11(map("$_/include",@xdirs),
		    '/usr/openwin/include',
		    chooseX11(</usr/X11*/include>),
		    chooseX11(</usr/include/X11*>),
		    </usr/Xfree*/include>,
		    '/usr/X386/include',
		    $Config{'usrinc'});
    }

  unless (defined $xinc)
    {
      warn <<EOF;
Cannot find X include files anywhere.
EOF
      if ($^O eq 'linux')
        {
          warn <<EOF;
You probably need to install the X11 development package first.
On Debian or Ubuntu, this is the package libx11-dev.
On CentOS, RedHat, or Fedora, this is the package libX11-devel.
Please see README.linux for more information.
EOF
        }
      exit 0;
    }

  if (defined($Config{'gccversion'}) &&
      $Config{'gccversion'} =~ /\S/  &&
      $xinc =~ /^-I(.*openwin.*)$/)
   {
    $gccopt .= " -isystem $1";
   }

  $inc = ($xinc eq "-I/usr/include") ? "" : $xinc;

  if (!defined $XFT)
   {
    $XFT = 1;
   }
  if ($XFT)
   {
    # Found basic X libraries now see if we can find -lXft

    my $ftinc = Ift("/usr/include","/usr/local/include",$X11INC||());
    if ($ftinc)
     {
      print "xlib='$xlib' xinc='$xinc'\n";
      my $success = 0;
      # Including ft2build.h additionally seems to be necessary
      # on an old RedHat 8.0 system
      for my $def ([], ["-DNEED_FT2BUILD_H"])
       {
	my $ftlib = '-L/usr/local/lib'; # XXX needed if freetype and xlibs are in different lib directories, but should probably check if this is necessary
	if (try_run("config/xft.c",[$xinc,$ftinc],[$xlib,$ftlib,'-lXft','-lfontconfig'],$def))
         {
          $inc .= " $ftinc";
          warn "Seem to have -lXft\n";
          $define{USE_XFT_FONTS} = 1;
          $xlib .= " -lXft";
          $xtra = " $ftlib -lfontconfig";
	  if (@$def)
	   {
	    for my $d (@$def)
	     {
	      $d =~ s{-D}{};
	      $define{$d} = 1;
	     }
	   }
	  $success = 1;
	  last;
         }
       }
      if (!$success)
       {
	warn "Xft and/or fontconfig libraries and/or includes are missing" .
	     (!$Tk::MMtry::VERBOSE ? ",\ntry perl Makefile.PL VERBOSE=1 for more information" : "") .
	     ".\n";
       }
     }
    else
     {
      warn "Cannot find freetype.h include file\n";
     }
   }
  else
   {
    warn "XFT not requested\n";
   }
} elsif ($win_arch eq 'open32') {
  unless (defined $toolkit) {
    my @path = split /;/, $ENV{PATH};
    foreach (@path) {
      next unless m:[\\/]toolkit[\\/]bin:i;
      my $tlk = "$`/toolkit";
      next unless -d "$tlk/H" and -f "$tlk/H/os2win.h";
      $toolkit = $tlk;
      $toolkit =~ s:\\:/:g ;
      last;
    }
  }
  die "Cannot find OS/2 toolkit" unless $toolkit;
  $inc = "-I../pTk/mTk/xlib -I../../pTk/mTk/xlib -IpTk/mTk/xlib";
  $inc .= " -I$toolkit/H -I../pTk/mTk/open32/h -IpTk/mTk/open32/h -ImTk/os2_rc";
  $define .= " -D__WIN32__";
  $xlib = "-L$toolkit/LIB -lpmwinx";
} elsif ($win_arch eq 'pm') {
  $define .= " -D__PM__";
  $inc = "-I../pTk/mTk/xlib -I../../pTk/mTk/xlib -IpTk/mTk/xlib -ImTk/os2_rc";
  $xlib = "";                          # No library is needed
} elsif ($IsWin32 or $^O eq 'cygwin') {
  $inc = '-I$(TKDIR) -I$(TKDIR)/pTk/mTk/xlib';
}


if ($Config{'osname'} eq 'solaris' && $xlib =~ /\bopenwin\b/ )
 {
  $define{'NEED_PRELOAD'} = 1;
 }

sub WriteIfChanged
{
 my ($file,$string) = @_;
 my ($dir) = $file =~ m#^(.*)/[^/]+$#;
 if (defined($dir) && !-d $dir)
  {
   mkdir($dir,0777) || die "Cannot mkdir $dir:$!";
  }
 my $ok = -f $file;
 if ($ok = open(IN,"$file"))
  {
   my $old = join('',<IN>);
   close(IN);
   $ok = $old eq $string;
   print STDERR "$file has changed\n" unless ($ok);
  }
 unless ($ok)
  {
   open(OUT,">$file") || die "Cannot open $file:$!";
   print STDERR "Writing $file\n";
   print OUT $string;
   close(OUT);
  }
}

if (!defined($MakefileName) || $MakefileName eq 'Makefile')
 {
  my $config = "# DO NOT EDIT. CREATED AUTOMATICALLY BY myConfig\npackage Tk::Config;\nrequire Exporter;\nuse base qw(Exporter);\n";
  my $sym;
  my @export = ();
  foreach $sym (qw(VERSION inc define xlib xinc gccopt win_arch))
   {
    my $val = ${$sym};
    $val =~ s/([\\\'])/\\$1/g;
    $config .= "\$$sym = '$val';\n";
    push(@export,"\$$sym");
   }
  $config .= "\@EXPORT = qw(".join(' ',@export).");\n1;\n";
  WriteIfChanged("Tk/Config.pm",$config);
  $config = "#ifndef _TKCONFIG\n#define _TKCONFIG\n";
  foreach $sym (sort keys %define)
   {
    $config .= "#define $sym $define{$sym}\n";
   }
  $config .= "#endif\n";
  WriteIfChanged("pTk/tkConfig.h",$config);
 }

1;