#  Copyright (c) 1997-2011
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
#  http://www.polymake.de
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation; either version 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#-------------------------------------------------------------------------------
# $Project: polymake $$Id: configure.pl 10054 2011-03-07 22:47:33Z gawrilow $

BEGIN {
   if ($] < 5.008) {
      print STDERR <<".";
polymake requires perl version not lower than 5.8;
your perl interpreter says it is $].

Please upgrade your perl installation;
if you already have an up-to-date perl interpreter somewhere else,
you can specify its location on the command line:

./configure PERL=/path/to/my/new/perl [other options ...]
.
      exit(1);
   }
}

use Config;
use Cwd;
use File::Path;

use strict 'vars', 'subs';
use lib;

package FakeNoShell;
sub new { bless \(my $dummy) }
sub interactive { 0 }

package Polymake;

my (@export, @noexport);

BEGIN {
   @noexport=qw( CC CXX Cflags CXXflags CsharedFlags CXXOPT CXXDEBUG
                 GCCversion ICCversion CCache
                 LDflags LDsharedFlags LDcallableFlags Libs
                 LIBXML2_CFLAGS LIBXML2_LIBS
                 Arch FinkBase
                 JavaBuild JavaViewPath NativeArchFlags ANT );
   @export=qw( PERL InstallTop InstallArch InstallBin InstallInc InstallLib InstallDoc DirMask ARCHFLAGS JAVACMD JNI_HEADERS);
}
use vars qw($Platform $BuildDir $Shell $filename_re),
         map { "\$$_" } @noexport, @export;

my $TOP=Cwd::getcwd;
my $DeveloperMode=-d ".svn";

my $Wiki="http://polymake.mathematik.tu-darmstadt.de/doku.php";

sub usage {
   my $GMPdef= $^O eq "darwin" ? '${fink}' : '/usr';

   print STDERR <<'.';
This is a script preparing the build and installation of polymake.
It tries to mimic well-known GNU auto-configuration scripts:

./configure [options] [VARIABLE=value ...]

Allowed options (and their default values) are:

  Installation directories:

  --prefix=PATH       ( /usr/local )  root of the installation tree
  --exec-prefix=PATH  ( ${prefix} )   root of the architecture-dependent tree
  --bindir=PATH       ( ${exec-prefix}/bin )           main polymake script
  --includedir=PATH   ( ${prefix}/include )            include files
  --libdir=PATH       ( ${exec-prefix}/lib )           callable library
  --libexecdir=PATH   ( ${exec-prefix}/lib/polymake )  dynamic modules loaded at the runtime
  --datadir=PATH      ( ${prefix}/share/polymake )     rules and other architecture-independent files
  --docdir=PATH       ( ${datadir}/doc )               automatically generated documentation files

  --build=ARCH        abbreviation for the build architecture

  Build dependences:

  --with-java=PATH          ( ${JAVA_HOME} )     where to find Java compiler and runtime environment
  --with-jni-headers=PATH   ( ${java}/include )  where to find jni.h and other headers for native methods
  --with-ant=PATH           ( find via $PATH )   ant executable (Java building tool)
  --with-javaview=PATH      where to find JavaView archives (to recompile the interface)
  --without-javaview        don't recompile the JavaView interface, but all other java modules
  --without-java            don't build any Java components, disable JavaView and jReality interfaces
.
   if ($^O eq "darwin") {
      print STDERR <<'.';
  --with-fink=PATH    ( /sw ) fink installation directory
.
   }
   print STDERR <<".";
  --with-gmp=PATH     ( $GMPdef ) GNU MultiPrecision library installation directory
.
   print STDERR <<'.';
  --with-mpfr=PATH    ( =gmp-path ) GNU Multiple Precision Floating-point Reliable library installation directory

  --with-libxml2=PATH ( find via \$PATH ) GNU XML processing library

  --without-prereq    don't check for availability of required libraries and perl modules
                      (to be used from within package management systems like RPM,
                       having own mechanisms for providing all prerequisits.)

Allowed variables are:

   CC=cc       C compiler executable
   CFLAGS=     C compiler options
   CXX=c++     C++ compiler executable
   CXXFLAGS=   C++ compiler options
   CXXOPT=     C/C++ compiler optimization level (defaults to highest possible)
   LDFLAGS=    linker options
   LIBS=       additional libraries to be linked with
   PERL=perl   perl executable

For detailed installation instructions, please refer to the polymake Wiki site:
  http://wwwopt.mathematik.tu-darmstadt.de/polymake/doku.php/howto/install
.
}

# import some utilities and prepare the fake environment for them

require "perllib/Polymake/config_utils.pl";
require "apps/common/perllib/JavaConfigure.pm";
*Java::Configure::find_program=\&find_program;
$Shell=new FakeNoShell;
$filename_re=qr{ ([^/]+) $ }x;

sub check_program {
   if ($_[0] =~ m{^[/.]}) {
      if (-x $_[0] && -f _) {
         Cwd::abs_path($_[0])
      } else {
         die "$_[0] ", -e _ ? "is not an executable program" : "does not exist", "\n";
      }
   } elsif (defined $_[0]) {
      find_program($_[0], $_[0])
         or
      die "$_[0] could not be found along your PATH, please check the spelling or provide a full path\n";
   } else {
      find_program(@_)
   }
}

# parse the command line
my (%options, %vars, %took_from_env);

my (%allowed_options, %allowed_with, %allowed_vars);
my $check_prereq=1;
@allowed_options{ qw( prefix exec-prefix bindir includedir libdir libexecdir datadir docdir build ) }=();
@allowed_with{ qw( java jni-headers ant javaview fink gmp mpfr libxml2 ) }=();
@allowed_vars{ qw( CC CFLAGS CXX CXXFLAGS CXXOPT LDFLAGS LIBS PERL ) }=();

while (defined (my $arg=shift @ARGV)) {
   if ($arg eq "--help") {
      usage();
      exit(0);
   } elsif ($arg eq '--without-prereq') {
      $check_prereq=0;
      next;
   } elsif ($arg =~ /--without-(java|javaview)/) {
      $options{$1}=".none.";
      next;
   } elsif (my ($with, $name, $value)= $arg =~ /^--(with-)?([-\w]+)(?:=(.*))?$/) {
      if ($with ? exists $allowed_with{$name} : exists $allowed_options{$name} and
          defined($value) || @ARGV) {
         $value=shift(@ARGV) unless defined($value);
         $value =~ s{^~/}{$ENV{HOME}/};
         $value =~ s{/+$}{};
         $options{$name}=$value;
         next;
      }
   } elsif ($arg =~ /^([A-Z]+)=(.*)/) {
      if (exists $allowed_vars{$1}) {
         $vars{$1}=$2;
         next;
      }
   }
   print STDERR "Unrecognized option $arg;\nTry ./configure --help for detailed information\n";
   exit(1);
}

# construct paths

my $prefix=$options{prefix} || "/usr/local";
my $exec_prefix=$options{'exec-prefix'} || $prefix;

$InstallBin=$options{bindir} || "$exec_prefix/bin";
$InstallLib=$options{libdir} || "$exec_prefix/lib";
$InstallTop=$options{datadir} || "$prefix/share/polymake";
$InstallArch=$options{libexecdir} || "$exec_prefix/lib/polymake";
$InstallInc=$options{includedir} || "$prefix/include";
$InstallDoc=$options{docdir} || ($DeveloperMode ? "doc_build" : "$InstallTop/doc");

$DirMask="0755";

# check the compiler

sub compile {
   open C, ">polymake_configure.cc" or die "$0: can't create a temporary file: $!\n";
   print C @_;
   close C;
   `$CXX $CXXflags -c polymake_configure.cc 2>&1`
}

sub build {
   open C, ">polymake_configure.cc" or die "$0: can't create a temporary file: $!\n";
   print C @_;
   close C;
   `$CXX $CXXflags -o polymake_configure polymake_configure.cc $LDflags $Libs 2>&1`
}

sub v_cmp($$) {
   eval "v$_[0] cmp v$_[1]";
}

sub take_from_env {
   my $varname=shift;
   if (defined (my $value=$ENV{$varname})) {
      $took_from_env{$varname}=$value;
   } else {
      undef
   }
}

$CXX=$vars{CXX} || take_from_env('CXX');
$CC=$vars{CC} || take_from_env('CC');

my $absCXX=check_program($CXX, "g++", "c++", "icpc")
  or die "no supported C++ compiler found; please reconfigure with CXX=name\n";

while (-l $absCXX) {
   $absCXX=readlink $absCXX;
}
$CCache= $absCXX =~ /\bccache$/;

if (defined $CC) {
   check_program($CC);
} else {
   unless (($CC=$CXX) =~ s{\b([ei])cp?c$}{${1}cc}
             ||
           $CC =~ s{g\+\+(?=[^/]*)$}{gcc}
             ||
           $CC =~ s{(?:c\+\+|CC)(?=[^/]*)$}{cc}
             and
           eval { check_program($CC) }) {
      $CC=$Config::Config{cc};
   }
}

if ($CXX =~ m/\b[ei]cpc$/) {
   local $CXXflags="-V";
   $_=compile 'int main() { return 0; }';
   ($ICCversion)= /Version\s+([\d.]+)/
      or
   die "Can't determine the version of C++ compiler $CXX\n";

   if (v_cmp($ICCversion,"10.0")<0) {
      die "C++ compiler $CXX says its version is $ICCversion, while the minimal required version is 10.0\n";
   }

} else {
   ($GCCversion)= `$CXX -dumpspecs` =~ /\*version:\n([\d.]+)/s
   or die "Can't determine the version of C++ compiler $CXX\n";
   if (v_cmp($GCCversion,"4.0")<0) {
      die "C++ compiler $CXX says its version is $GCCversion, which is rather out-of-date.\n";
   }
}

$PERL     =$vars{PERL}     || $^X;
$CXXOPT   =$vars{CXXOPT}   || take_from_env('CXXOPT') || "-O3";
$Cflags   =$vars{CFLAGS}   || take_from_env('CFLAGS');
$CXXflags =$vars{CXXFLAGS} || take_from_env('CXXFLAGS') || $Cflags;
$LDflags  =$vars{LDFLAGS}  || take_from_env('LDFLAGS') || "";
$Libs     =$vars{LIBS}     || take_from_env('LIBS') || "";

$LDsharedFlags=$Config::Config{lddlflags};
$LDcallableFlags="$LDsharedFlags $Config::Config{ldflags}";

my $GMP=$options{gmp};

do "support/locate_build_dir";

if ($^O eq "darwin") {
   if (defined ($FinkBase=$options{fink})) {
      if (-d $FinkBase) {
         unless (-f "$FinkBase/etc/fink.conf") {
            die "option --with-fink does not point to the fink installation tree: $FinkBase/etc/fink.conf not found\n";
         }
      } elsif (-x $FinkBase && $FinkBase =~ s|/bin/fink$||) {
         unless (-f "$FinkBase/etc/fink.conf") {
            die "option -with-fink points to a broken fink installation: $FinkBase/etc/fink.conf not found\n";
         }
      } else {
         die "option -with-fink points to a wrong program: something like /path/bin/fink expected.\n",
             "If you have renamed the main fink program, please specify the top directory: --with-fink=/path\n";
      }
   } else {
      (undef, my ($fink, $error))=find_program_in_path("fink", sub {
                                                                  !(($FinkBase=$_[0]) =~ s|/bin/fink$|| && -f "$FinkBase/etc/fink.conf") && "!"
                                                               });
      if ($fink) {
         if ($error) {
            die "found the fink program at $fink, but the corresponding configuration file is missing;\n",
                "Please specify the top installation directory using option --with-fink\n";
         }
      } elsif (-f "/sw/etc/fink.conf") {
         $FinkBase="/sw";
      } else {
         die "The Fink package system is a mandatory prerequisite to build and use polymake under MacOS.\n",
             "Please refer to $Wiki/mac for details and installation instructions.\n",
             "If you already have Fink installed at a non-standard location, please specify it using option --with-fink\n";
      }
   }

   if (-f "$FinkBase/lib/libgmp.dylib") {
      ($Platform)= `lipo -info $FinkBase/lib/libgmp.dylib` =~ /architecture: (\S+)/;
   } else {
      die "Fink package gmp-shlibs seems to be missing.  Further configuration is not possible.\n",
          "Please install the packages gmp and gmp-shlibs and repeat the configure run.\n";
   }
   $ARCHFLAGS="-arch $Platform";
   $Arch="darwin.$Platform";
   $GMP ||= $FinkBase;

} else {
   $Platform=platform_name();
   unless ($CXXflags) {
      if (v_cmp($GCCversion, "4.2")>=0) {
         $CXXflags="-march=native";
      } elsif ($Platform eq "sun4u") {
         $CXXflags="-mcpu=ultrasparc";
      } elsif ($Platform eq "i86pc") {
         $CXXflags="-march=pentiumpro";
      }
      $Cflags=$CXXflags;
   }
   $Arch=$options{build} || $Platform;

   if ($^O eq "freebsd" && !$GMP) {
      if (-f "/usr/local/include/gmp.h") {
         $GMP="/usr/local";
      }
   }
}

$BuildDir="build.$Arch";

# add compiler-specific options

if ($GCCversion) {
   $CsharedFlags="-fPIC";
   $CXXDEBUG="-g";
   $CXXflags .= " -ftemplate-depth-200 -Wall -Wno-strict-aliasing";
   $Cflags .= " -Wall -Wno-uninitialized -Wno-unused";
   if (v_cmp($GCCversion, "4.2")>=0) {
      $Cflags .= " -Wno-parentheses";
      $CXXflags .= " -Wno-parentheses -fno-inline-functions-called-once";
   }
   if (v_cmp($GCCversion, "4.3")<0) {
      $CXXflags .= " -Wno-uninitialized";
   }
   if ($ARCHFLAGS) {
      # MacOS magic again
      my $allarch=qr/ -arch \s+ \S+ (?: \s+ -arch \s+ \S+)* /x;
      $Cflags =~ s/$allarch//o;
      $Cflags .= ' ${ARCHFLAGS}';
      $CXXflags =~ s/$allarch//o;
      $CXXflags .= ' ${ARCHFLAGS}';
      $LDsharedFlags =~ s/$allarch/\${ARCHFLAGS}/o;
      ($LDcallableFlags = $Config::Config{ldflags}) =~ s/$allarch//o;
      $LDcallableFlags = "$LDsharedFlags $LDcallableFlags";
      $LDcallableFlags =~ s{-bundle}{-dynamiclib -install_name $InstallLib/libpolymake.dylib};
   } elsif ($^O eq "solaris") {
      $CXXflags .= " -D__C99FEATURES__ -D_GLIBCXX_USE_C99_MATH";
   }
} elsif ($ICCversion) {
   $CsharedFlags="-fPIC";
   $CXXDEBUG="-g -Ob0";
   $CXXflags .= " -Wall -wd193,383,304,981,1419,279,810,171,1418,488,1572,561";
   $Cflags .= " -Wall -wd193,1572,561";
}

# detect whether socket functions reside in a separate library

if ($Config::Config{libs} =~ "-lsocket") {
   $Libs="-lsocket $Libs";
}

# locate GMP and MPFR libraries

sub get_libdir {
   my ($prefix, $name)=@_;
   if ($Config::Config{longsize}==8 && $CXXflags !~ /-m32/ && $Arch =~ /i?86/ && -f "$prefix/lib64/lib$name.$Config::Config{dlext}") {
      "$prefix/lib64"
   } else {
      "$prefix/lib";
   }
}

if (defined $GMP) {
   $Cflags .= " -I$GMP/include";
   $CXXflags .= " -I$GMP/include";
   my $libdir=get_libdir($GMP, "gmp");
   $LDflags .= " -L$libdir";
   if ($^O ne "darwin" && exists $options{gmp}) {
      # non-standard location
      $LDflags .= " -Wl,-rpath,$libdir";
   }
}

my $MPFR=$options{mpfr};
if (defined($MPFR) && $MPFR ne $GMP) {
   $Cflags .= " -I$MPFR/include";
   $CXXflags .= " -I$MPFR/include";
   my $libdir=get_libdir($MPFR, "mpfr");
   $LDflags .= " -L$libdir";
   if ($^O ne "darwin") {
      # non-standard location
      $LDflags .= " -Wl,-rpath,$libdir";
   }
}

if ($check_prereq) {
   # check GMP installation
   local $Libs="$ARCHFLAGS -lgmp $Libs";
   my $build_error=build <<'---';
#include <gmp.h>
#include <iostream>
int main() {
   mpz_t a;
   mpz_init(a);
   std::cout << __GNU_MP_VERSION << '.' << __GNU_MP_VERSION_MINOR << '.' << __GNU_MP_VERSION_PATCHLEVEL << std::flush;
   return 0;
}
---
   if ($?==0) {
      my $is_version=`./polymake_configure`;
      if ($?==0) {
         if (v_cmp($is_version,"4.0.0")<0) {
            die "The GNU Multiprecision Library (GMP) installed at your site is of version $is_version\n",
                "while 4.0.0 is the minimal required version.\n";
         }
      } else {
         die "Could not run a test program linked to the GNU Multiprecision Library (GMP).\n",
             "Probably the shared library libgmp.$Config::Config{dlext} is missing or of an incompatible machine type.\n";
      }
   } else {
      die "Could not compile a test program checking for the GNU Multiprecision Library (GMP).\n",
          "The most probable reasons are that the library is installed at a non-standard location,\n",
          "lacking developer's subpackage or missing at all.\n",
          "Please refer to the installation instructions at $Wiki/howto/install.\n",
          "The complete error log follows:\n", $build_error;
   }

   $Libs =~ s/(?=-lgmp)/-lmpfr /;
   my $build_error=build <<'---';
#include <mpfr.h>
#include <iostream>
int main() {
   mpfr_t a;
   mpfr_init(a);
   std::cout << MPFR_VERSION_MAJOR << '.' << MPFR_VERSION_MINOR << '.' << MPFR_VERSION_PATCHLEVEL << std::flush;
   return 0;
}
---
   if ($?==0) {
      my $is_version=`./polymake_configure`;
      if ($?==0) {
         if (v_cmp($is_version,"3.0.0")<0) {
            die "The Multiple Precision Floating-Point Reliable Library (MPFR) installed at your site is of version $is_version\n",
                "while 3.0.0 is the minimal required version.\n";
         }
      } else {
         die "Could not run a test program linked to the Multiple Precision Floating-Point Reliable Library (MPFR).\n",
             "Probably the shared library libmpfr.$Config::Config{dlext} is missing or of an incompatible machine type.\n";
      }
   } else {
      die <<".", $build_error;
Could not compile a test program checking for the Multiple Precision Floating-Point Reliable Library (MPFR).
The most probable reasons are that the library is installed at a non-standard location,
lacking developer's subpackage or missing at all.
Please refer to the installation instructions at $Wiki/howto/install.
The complete error log follows:
.
   }

   if ($^O eq "darwin") {
      lib->import("$FinkBase/lib/perl5");
   }
   my $warned;
   foreach (qw(XML::Writer XML::LibXML XML::LibXSLT Term::ReadLine)) {
      my $pkg=$_;
      eval "require $pkg;";
      if (/^Term/) {
         $pkg.="::Gnu";
         unless ($@) {
            eval "new $pkg('polymake');";
         }
      }
      if ($@) {
         if ($@ =~ /\ACan't locate /) {
            print STDERR <<".";
WARNING: perl module $pkg required for polymake not found on your machine.
         Please be sure to install it prior to starting to use polymake.
.
         } else {
            $@ =~ / at .*? line \d+/m;
            print STDERR <<".";
WARNING: perl module $pkg required for polymake seems to be unusable.
         An attempt to load it has failed because of the following:
         $`
         Please be sure to rectify the problem prior to starting to use polymake.
.
         }
         $warned=1;
      }
   }
   if ($warned) {
      print STDERR "\nConfiguration goes on, nevertheless.\n";
   }
}

# configure Java unless disabled

if ($options{java} eq ".none.") {
   $JavaBuild="n";

} else {
   if (defined (my $java=$options{java})) {
      if (-d $java) {
         if (-x "$java/bin/java") {
            $JAVACMD=$ENV{JAVACMD}="$java/bin/java";
         } else {
            die "Value of --with-java option does not look like a JDK top directory: $java/bin/java does not exist.\n";
         }
      } elsif (-x $java) {
         $JAVACMD=$ENV{JAVACMD}=$java;
      } else {
         die "Invalid value of --with-java option: path does not exist.\n";
      }
   }

   if (defined ($ANT=$options{ant})) {
      check_program($ANT);
      $JavaBuild="y";
   } elsif ($DeveloperMode || defined($options{java})) {
      find_program($ANT, "ant")
         or die "ant utility not found; please install it (together with optional targets, if packaged sepaartely),\n",
                "specify its location in --with-ant option if it is installed at a non-standard location,\n",
                "or disable recompilation of java modules (pass --without-java to the configure script).\n";
      $JavaBuild="y" if $DeveloperMode;
   } else {
      find_program($ANT, "ant");
   }

   if (defined $ANT) {
      my ($ant_version)= `$ANT -version` =~ /version ([\d.]+)/;
      if (v_cmp($ant_version,"1.7.1")<0) {
         if ($JavaBuild eq "y") {
            die "$ANT says its version is $ant_version, while minimal required version is 1.7.1\n";
         } else {
            undef $ANT;
         }
      }
   }

   if ($JavaBuild eq "y" && defined ($JavaViewPath=$options{javaview}) && $JavaViewPath ne ".none.") {
      if (-d $JavaViewPath) {
         -x "$JavaViewPath/bin/javaview"
            or die "Value of --with-javaview option does not look like the top installation directory: $JavaViewPath/bin/javaview does not exist.\n";
      } else {
         die "Invalid value of --with-javaview option: directory does not exist.\n";
      }
   }

   if ($JavaBuild ne "n") {
      if (defined($JNI_HEADERS=$options{'jni-headers'})) {
         -f "$JNI_HEADERS/jni.h"
            or die "Value of --with-jni-headers option does not look like JNI include path: $JNI_HEADERS/jni.h does not exist.\n";
      }

      if (!$DeveloperMode) {
         $JAVACMD ||= Java::Configure::find_java_cmd(my $java_cmd)
                  || die <<'.';
No Java VM found on your machine.
Please specify a JDK location in --with-java option
or disable building Java native libraries by passing --without-java
to the configure script.
In the latter case interfaces to JavaView and JReality will be disabled,
but the users will be able to reconfigure them on individual basis.
.
         $JNI_HEADERS ||= Java::Configure::find_jni_headers($JAVACMD)
                      || die <<".";
$JAVACMD seems to belong to a pure Java runtime installation:
JNI headers (most prominently jni.h) were not found.
If they happen to reside at a different location, please specify it using
--with-jni-headers option (but double-check upfront whether they really
suit the chosen Java environment).
Otherwise, please install a complete JDK or disable building Java native
libraries by passing --without-java to the configure script.
In the latter case interfaces to JavaView and JReality will be deactivated,
but the users will be able to reconfigure them on individual basis.
.
         if ($^O eq "darwin") {
            ( $NativeArchFlags=`lipo -info $JAVACMD` ) =~ s/.* are: (.*)$/$1/m;
            $NativeArchFlags =~ s/(\S+)/-arch $1/g;
         }
      }

      File::Path::mkpath("java_build") if $DeveloperMode;
   }
}

# gather build options for libxml2
my $xml2=$options{xml2};
if (defined($xml2)) {
   if (-x "$xml2/bin/xml2-config") {
      $xml2="$xml2/bin/xml2-config";
   } elsif (-x "$xml2/xml2-config") {
      $xml2="$xml2/xml2-config";
   } elsif ($xml2 !~ /-config$/ || !-x $xml2) {
      die "Could not derive the location of the configuration program xml2-config from the option --with-libxml2\n";
   }
} else {
   $xml2="xml2-config";
}
$LIBXML2_CFLAGS=`xml2-config --cflags`;
if ($?) {
   die <<".";
Could not find configuration program xml2-config for library libxml2.
Probably you need to install development package for it;
usually it is called libxml2-devel or similarly.
If the library is installed at a non-standard location,
please specify it in option --with-libxml2
.
}
chomp $LIBXML2_CFLAGS;
$LIBXML2_LIBS=`xml2-config --libs`;
chomp $LIBXML2_LIBS;

# create the build directories and Makefiles

sub make_build_dir {
   local $_=shift if @_;
   File::Path::mkpath("$BuildDir/$_");
   open M, ">$BuildDir/$_/Makefile" or die "can't create $BuildDir/$_/Makefile: $!\n";
   s:[^/]+:..:g;
   print M <<".";
BuildDir := $_
ProjectTop := \${BuildDir}/..
include \${ProjectTop}/support/build.make
.
   close M;
}

make_build_dir "lib";
/jreality/ || make_build_dir for glob("external/*");

if ($DeveloperMode) {
   my %filter_out;
   foreach (`svn propget noexport apps/*`) {
      if (/(\w+) - (\w+)/ && ($2 eq "broken" || $2 eq "test")) {
         $filter_out{$1}=1;
      }
   }
   m{apps/(\w+)} && $filter_out{$1} || make_build_dir for glob("apps/*");
} else {
   make_build_dir for glob("apps/*");
}

# write the conf file
open CONF, ">$BuildDir/conf.make";

print CONF "# configured with:\n", "# $TOP/configure";
if (defined (my $with_perl=delete $options{perl})) {
   print CONF " PERL=$with_perl";
}
foreach (\%vars, \%took_from_env) {
   while (my ($item, $value)=each %$_) {
      $value="'$value'" if $value =~ /[\s(){}\[\]\$]/;
      print CONF " $item=$value";
   }
}
while (my ($item, $value)=each %options) {
   $value="'$value'" if $value =~ /[\s(){}\[\]\$]/;
   print CONF $value eq ".none."
              ? " --without-$item" :
              exists $allowed_with{$item}
              ? " --with-$item=$value"
              : " --$item=$value";
}
print CONF "\n\n";

foreach my $var (@noexport, @export) {
   print CONF "$var=$$var\n" if defined($$var);
}

print CONF "export ", join(" ", grep { defined($$_) } @export), "\n";

print CONF <<".";
RANLIB=$Config::Config{ranlib}
SO=$Config::Config{dlext}
export INSTALL_PL=$TOP/support/install.pl
DESTDIR=
export FinalInstallTop := \${InstallTop}
export FinalInstallArch := \${InstallArch}
InstallTop := \${DESTDIR}\${InstallTop}
InstallArch := \${DESTDIR}\${InstallArch}
InstallBin := \${DESTDIR}\${InstallBin}
InstallInc := \${DESTDIR}\${InstallInc}
InstallLib := \${DESTDIR}\${InstallLib}
InstallDoc := \${DESTDIR}\${InstallDoc}
InSourceTree := y
.
close CONF;

END {
   unlink glob "polymake_configure*";
   unlink glob "core*";
}

# Local Variables:
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
