1#  Copyright (c) 1997-2021
2#  Ewgenij Gawrilow, Michael Joswig, and the polymake team
3#  Technische Universität Berlin, Germany
4#  https://polymake.org
5#
6#  This program is free software; you can redistribute it and/or modify it
7#  under the terms of the GNU General Public License as published by the
8#  Free Software Foundation; either version 2, or (at your option) any
9#  later version: http://www.gnu.org/licenses/gpl.txt.
10#
11#  This program is distributed in the hope that it will be useful,
12#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#  GNU General Public License for more details.
15#-------------------------------------------------------------------------------
16
17@conf_vars=qw( UseBundled CXXFLAGS LDFLAGS LIBS );
18
19sub allowed_options {
20   my ($allowed_options, $allowed_with)=@_;
21   @$allowed_with{ qw( sympol sympol-include sympol-lib ) }=();
22}
23
24sub usage {
25   print STDERR "  --with-sympol=PATH   Installation path of sympol, if non-standard.\n",
26                "                       By default, polymake will try to use a system-wide\n",
27                "                       installation or fall back to the bundled sympol\n",
28                "                       (bundled/sympol/external/sympol) if it exists.\n",
29                "                       To force the bundled version, specify 'bundled' as PATH.\n",
30                "  --with-sympol-include=PATH  Path to the folder containing symmetrycomputation.h\n",
31                "  --with-sympol-lib=PATH      Path to the folder containing libsympol.{a,so,dylib}\n";
32
33}
34
35sub check_bundled {
36   -e "bundled/sympol/external/sympol/sympol/symmetrycomputation.h"
37}
38
39sub proceed {
40   my ($options)=@_;
41   my $sympol_path;
42   $UseBundled = 1;
43
44   if (defined ($sympol_path=$options->{sympol}) and $sympol_path ne "bundled") {
45      if (-f "$sympol_path/include/sympol/symmetrycomputation.h") {
46         $CXXFLAGS = "-I$sympol_path/include";
47      }
48      my $sympol_lib=Polymake::Configure::get_libdir($sympol_path, "sympol");
49      if (-f "$sympol_lib/libsympol.$Config::Config{so}" ) {
50         $LDFLAGS = "-L$sympol_lib";
51         $LDFLAGS .= " -Wl,-rpath,$sympol_lib" if $sympol_path ne "/usr";
52      }
53      if (!$CXXFLAGS or !$LDFLAGS) {
54         die "Invalid installation location of sympol: header file symmetrycomputation.h and/or library libsympol.$Config::Config{so} not found.\n",
55             "You might try to use --with-sympol-include and --with-sympol-lib.\n";
56
57      }
58   }
59   if (defined (my $sympol_inc=$options->{'sympol-include'})) {
60      $CXXFLAGS .=" -I$sympol_inc";
61      $sympol_path .= "include: $sympol_inc ";
62   }
63   if (defined ($sympol_lib=$options->{'sympol-lib'})) {
64      $LDFLAGS = " -L$sympol_lib";
65      $LDFLAGS .= " -Wl,-rpath,$sympol_lib" if $sympol_lib !~ m{^/usr/lib};
66      $sympol_path .= "lib: $sympol_lib";
67   }
68
69   if ($Polymake::Bundled::lrs::UseBundled or $Polymake::Bundled::cdd::UseBundled or $Polymake::Configure::ExternalHeaders =~ /permlib/) {
70      if (defined($sympol_path) and $sympol_path ne "bundled") {
71         die "Using a non-bundled sympol configuration requires non-bundled lrs, cdd and PermLib as well.\n",
72             "Please use --with-cdd=PATH, --with-lrs=PATH and --with-permlib=PATH or remove the --with-sympol option.\n";
73      }
74      $sympol_path = "bundled";
75   }
76
77   if ($sympol_path ne "bundled") {
78      my $testcode = <<"---";
79#include <cstddef>
80#include <iostream>
81#include <gmpxx.h>
82#include <sympol/polyhedron.h>
83
84int main() {
85   boost::shared_ptr<sympol::PermutationGroup> pg;
86   return 0;
87}
88---
89      my $error=Polymake::Configure::build_test_program($testcode, LIBS => "-lsympol", CXXFLAGS => "$CXXFLAGS", LDFLAGS => "$LDFLAGS");
90      if ($?==0) {
91         my $message=Polymake::Configure::run_test_program();
92         if ($?) {
93            check_bundled() and !defined($sympol_path) or
94               die "Could not run a test program checking for sympol library.\n",
95                   "The complete error log follows:\n\n$message\n",
96                   "Please investigate the reasons and fix the installation.\n";
97         } else {
98            $UseBundled = 0;
99         }
100      } else {
101         check_bundled() and !defined($sympol_path) or
102            die "Could not compile a test program checking for sympol.\n",
103                "The most probable reasons are that the library is installed at a non-standard location,\n",
104                "is not configured to build a shared module, or missing at all.\n",
105                "The complete error log follows:\n\n$error\n",
106                "Please install the library and specify its location using --with-sympol option, if needed.\n",
107      }
108   }
109
110
111   if ($UseBundled) {
112      # check GMP C++ bindings (only for bundled sympol)
113      my $build_error=Polymake::Configure::build_test_program(<<'---', LIBS => "$Polymake::Configure::ARCHFLAGS -lgmpxx -lgmp");
114#include <cstddef>
115#include <gmpxx.h>
116#include <iostream>
117int main() {
118   mpq_class x(7,3);
119   std::cout << __GNU_MP_VERSION << '.' << __GNU_MP_VERSION_MINOR << '.' << __GNU_MP_VERSION_PATCHLEVEL << std::flush;
120   return 0;
121}
122---
123      if ($?==0) {
124         my $is_version=Polymake::Configure::run_test_program();
125         if ($?==0) {
126            if (Polymake::Configure::v_cmp($is_version,"4.2.0")<0) {
127               die "The GNU Multiprecision Library (GMP) C++ bindings installed at your site are of version $is_version\n",
128                   "while 4.2.0 is the minimal required version.\n",
129                   "Since a more recent GMP installation was found, it was probably configured without --enable-cxx .\n";
130            }
131         } else {
132            die "Could not run a test program linked to the C++ version of the GNU Multiprecision Library (GMP).\n",
133                "Probably the shared library libgmpxx.$Config::Config{dlext} is missing or of an incompatible machine type.\n";
134         }
135      } else {
136         die "Could not compile a test program checking for C++ bindings of the GNU Multiprecision Library (GMP).\n",
137             "The most probable reasons are that a gmpxx package is missing, lacking the developer's subpackage \n",
138             "or GMP was configured without C++ support (--enable-cxx).\n",
139             "Please refer to the installation instructions at $Wiki/howto/install.\n",
140             "The complete error log follows:\n", $build_error;
141      }
142   }
143
144   if ($UseBundled) {
145      die "bundled sympol requested but it cannot be found"
146         unless check_bundled();
147      undef $LIBS;
148      $CXXFLAGS = '-I${root}/bundled/sympol/external/sympol';
149   } else {
150      $LIBS="-lsympol";
151   }
152
153   if ($Polymake::Bundled::ppl::LIBS) {
154      $CXXFLAGS .= " -DPOLYMAKE_WITH_PPL";
155   }
156
157   return $UseBundled ? "bundled" : ($sympol_path//"system");
158
159}
160