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 CFLAGS LDFLAGS LIBS ); 18 19sub allowed_options { 20 my ($allowed_options, $allowed_with)=@_; 21 @$allowed_with{ qw( cdd cdd-include cdd-lib) }=(); 22} 23 24 25sub usage { 26 print STDERR " --with-cdd=PATH Installation path of cddlib, if non-standard.\n", 27 " By default, polymake will try to use a system-wide\n", 28 " installation or fall back to the bundled cddlib\n", 29 " (bundled/cdd/external/cdd) if it exists.\n", 30 " To force the bundled version, specify 'bundled' as PATH.\n", 31 " --with-cdd-include=PATH Path to the folder containing cdd.h\n", 32 " --with-cdd-lib=PATH Path to the folder containing libcddgmp.{a,so,dylib} \n"; 33} 34 35sub check_bundled { 36 -e "bundled/cdd/external/cdd/lib-src-gmp/cdd.h" 37} 38 39sub proceed { 40 my ($options)=@_; 41 my $cdd_path; 42 my $cddversion; 43 $UseBundled = 1; 44 45 if (defined ($cdd_path=$options->{cdd}) and $cdd_path ne "bundled") { 46 my $cdd_inc="$cdd_path/include"; 47 if (-f "$cdd_inc/cdd.h") { 48 $CFLAGS = "-I$cdd_inc"; 49 } elsif (-f "$cdd_inc/cdd/cdd.h") { 50 # This is for debian where the includes are moved to a subdirectory 51 $CFLAGS = "-I$cdd_inc/cdd"; 52 } elsif (-f "$cdd_inc/cddlib/cdd.h") { 53 # This is for fedora where the includes are moved to a subdirectory 54 $CFLAGS = "-I$cdd_inc/cddlib"; 55 } 56 my $cdd_lib=Polymake::Configure::get_libdir($cdd_path, "cddgmp"); 57 if (-f "$cdd_lib/libcddgmp.$Config::Config{so}" ) { 58 $LDFLAGS = "-L$cdd_lib"; 59 $LDFLAGS .= " -Wl,-rpath,$cdd_lib" if $cdd_path ne "/usr"; 60 } 61 if (!$CFLAGS or !$LDFLAGS) { 62 die "Invalid installation location of cddlib: header file cdd.h and/or library libcddgmp.$Config::Config{so} not found.\n", 63 "You might try to use --with-cdd-include and --with-cdd-lib.\n"; 64 } 65 } 66 67 if (defined (my $cdd_inc=$options->{'cdd-include'})) { 68 $CFLAGS = "-I$cdd_inc"; 69 $cdd_path .= "include: $cdd_inc "; 70 } 71 if (defined ($cdd_lib=$options->{'cdd-lib'})) { 72 $LDFLAGS = "-L$cdd_lib -Wl,-rpath,$cdd_lib"; 73 $cdd_path .= "lib: $cdd_lib"; 74 } 75 76 77 if ($cdd_path ne "bundled") { 78 my $testcode = <<"---"; 79#include <cstddef> 80#include <iostream> 81#include <gmp.h> 82 83#define GMPRATIONAL 84extern "C" { 85 #include <setoper.h> 86 #include <cdd.h> 87} 88 89int main() { 90 std::cout << "dd " << dd_DDVERSION << std::endl; 91 std::cout << "ddf " << ddf_DDVERSION << std::endl; 92 dd_set_global_constants(); 93 dd_free_global_constants(); 94 ddf_set_global_constants(); 95 ddf_free_global_constants(); 96 return 0; 97} 98--- 99 my $error=Polymake::Configure::build_test_program($testcode, LIBS => "-lcddgmp -lgmp", CXXFLAGS => "$CFLAGS", LDFLAGS => "$LDFLAGS"); 100 if ($? != 0) { 101 # if this failed then we try to determine whether the includes from cdd are in a subfolder 102 # (like on debian or fedora) 103 my $newcode; 104 foreach my $subdir (qw(cdd cddlib)) { 105 ($newcode = $testcode) =~ s{setoper\.h|cdd\.h}{$subdir/$&}g; 106 $error = Polymake::Configure::build_test_program($newcode, CXXFLAGS => "$CFLAGS", LIBS => "-lcddgmp -lgmp", LDFLAGS => "$LDFLAGS"); 107 last if $? == 0; 108 } 109 if ($? == 0) { 110 # run just the preprocessor and parse the output to find the path of cdd.h 111 open my $source, "echo '$newcode' | $Polymake::Configure::CXX $CFLAGS -xc++ -E - 2>/dev/null |" 112 or die "This looks like debian or fedora with cdd.h in a subfolder but we could not\n", 113 "run the preprocessor to find the cdd include path '$Polymake::Configure::CXX $CFLAGS -xc++ -E -': $!\n", 114 "You can try specifying --with-cdd-include and --with-cdd-lib"; 115 while (<$source>) { 116 if (m{\# \d+ "(\S+)/cdd\.h"}) { 117 $CFLAGS .= " -I$1"; 118 last; 119 } 120 } 121 close $source; 122 } 123 } 124 $error=Polymake::Configure::build_test_program($testcode, LIBS => "-lcddgmp -lgmp", CXXFLAGS => "$CFLAGS", LDFLAGS => "$LDFLAGS"); 125 if ($?==0) { 126 my $message=Polymake::Configure::run_test_program(); 127 if ($?) { 128 check_bundled() and !defined($cdd_path) or 129 die "Could not run a test program checking for cdd library.\n", 130 "The complete error log follows:\n\n$message\n", 131 "Please investigate the reasons and fix the installation.\n"; 132 } else { 133 my ($ddver,$ddfver) = $message =~ /dd Version ([0-9a-z.]+).*\nddf Version ([0-9a-z.]+)/; 134 if ($ddver ne $ddfver) { 135 check_bundled() and !defined($cdd_path) or 136 die "Your cddlib installation does not seem to contain the floating-point arithmetic version.\n", 137 "Reported versions: dd_DDVERSION=$ddver and ddf_DDVERSION=$ddfver\n"; 138 } elsif (($ddver cmp "0.94f") >= 0) { 139 $UseBundled = 0; 140 $cddversion = $ddver; 141 } else { 142 check_bundled() and !defined($cdd_path) or 143 die "Your cddlib version $ddver is too old, at least version 0.94f is required.\n"; 144 } 145 } 146 } else { 147 check_bundled() and !defined($cdd_path) or 148 die "Could not compile a test program checking for cdd library.\n", 149 "The most probable reasons are that the library is installed at a non-standard location,\n", 150 "is not configured to build a shared module, or missing at all.\n", 151 "The complete error log follows:\n\n$error\n", 152 "Please install the library and specify its location using --with-cdd option, if needed.\n", 153 "Please remember to enable shared modules when configuring the cdd library!\n"; 154 } 155 } 156 157 if ($UseBundled) { 158 die "bundled cdd requested but it cannot be found" 159 unless (-e "bundled/cdd/external/cdd/lib-src-gmp/cdd.h"); 160 undef $LIBS; 161 $CFLAGS='-I${root}/bundled/cdd/external/cdd/lib-src-gmp'; 162 } else { 163 $LIBS="-lcddgmp"; 164 } 165 166 return $UseBundled ? "bundled" : ("$cddversion @ ".($cdd_path//"system")); 167} 168 169