1import config.package 2 3class Configure(config.package.Package): 4 def __init__(self, framework): 5 config.package.Package.__init__(self, framework) 6 self.download = ['http://www.tetgen.org/1.5/src/tetgen1.6.0.tar.gz', 7 'https://web.cels.anl.gov/projects/petsc/download/externalpackages/tetgen1.6.0.tar.gz'] 8 self.liblist = [['libtet.a']] 9 self.includes = ['tetgen.h'] 10 self.buildLanguage= 'Cxx' 11 return 12 13 def setupHelp(self, help): 14 import nargs 15 config.package.Package.setupHelp(self, help) 16 help.addArgument('TETGEN', '-download-tetgen-build-exec=<bool>', nargs.ArgBool(None, False, 'Build and install the tetgen executable in addition to the library')) 17 return 18 19 def setupDependencies(self, framework): 20 config.package.Package.setupDependencies(self, framework) 21 self.languages = framework.require('PETSc.options.languages', self) 22 self.sharedLibraries = framework.require('PETSc.options.sharedLibraries', self) 23 self.mathlib = framework.require('config.packages.mathlib',self) 24 self.deps = [self.mathlib] 25 return 26 27 def Install(self): 28 import os, sys 29 import config.base 30 import fileinput 31 32 libDir = self.libDir 33 includeDir = os.path.join(self.installDir, 'include') 34 binDir = os.path.join(self.installDir, 'bin') 35 makeinc = os.path.join(self.packageDir, 'make.inc') 36 configheader = os.path.join(self.packageDir, 'configureheader.h') 37 38 # This make.inc stuff is completely unnecessary for compiling TetGen. It is 39 # just here for comparing different PETSC_ARCH's 40 self.pushLanguage('C++') 41 g = open(makeinc,'w') 42 g.write('SHELL = '+self.programs.SHELL+'\n') 43 g.write('CP = '+self.programs.cp+'\n') 44 g.write('RM = '+self.programs.RM+'\n') 45 g.write('MKDIR = '+self.programs.mkdir+'\n') 46 g.write('OMAKE = '+self.make.make+' '+self.make.noprintdirflag+'\n') 47 48 g.write('CLINKER = '+self.getLinker()+'\n') 49 g.write('AR = '+self.setCompilers.AR+'\n') 50 g.write('ARFLAGS = '+self.setCompilers.AR_FLAGS+'\n') 51 g.write('AR_LIB_SUFFIX = '+self.setCompilers.AR_LIB_SUFFIX+'\n') 52 g.write('RANLIB = '+self.setCompilers.RANLIB+'\n') 53 g.write('SL_LINKER_SUFFIX = '+self.setCompilers.sharedLibraryExt+'\n') 54 55 g.write('TETGEN_ROOT = '+self.packageDir+'\n') 56 g.write('PREFIX = '+self.installDir+'\n') 57 g.write('LIBDIR = '+libDir+'\n') 58 g.write('INSTALL_LIB_DIR = '+libDir+'\n') 59 g.write('TETGENLIB = $(LIBDIR)/libtet.$(AR_LIB_SUFFIX)\n') 60 g.write('SHLIB = libtet\n') 61 62 cflags = self.updatePackageCFlags(self.getCompilerFlags()) 63 cflags += ' '+self.headers.toString('.') 64 cflags += ' -fPIC' 65 cflags_exe = cflags 66 cflags += ' -DTETLIBRARY' 67 predcflags = '-O0 -fPIC' # Need to compile without optimization 68 69 g.write('CC = '+self.getCompiler()+'\n') 70 g.write('CFLAGS = '+cflags+'\n') 71 g.write('PREDCXXFLAGS = '+predcflags+'\n') 72 g.close() 73 74 # Now compile & install 75 if self.installNeeded('make.inc'): 76 self.framework.outputHeader(configheader) 77 try: 78 self.logPrintBox('Compiling & installing TetGen; this may take several minutes') 79 output,err,ret = config.package.Package.executeShellCommand('mkdir -p '+os.path.join(self.installDir,'lib'), timeout=2500, log=self.log) 80 output,err,ret = config.package.Package.executeShellCommand('mkdir -p '+os.path.join(self.installDir,'include'), timeout=2500, log=self.log) 81 output1,err1,ret1 = config.package.Package.executeShellCommand('cd '+self.packageDir+' && make CXX="'+ self.getCompiler() + '" CXXFLAGS="' + cflags + '" PREDCXXFLAGS="' + predcflags + '" tetlib && cp *.a ' + libDir + ' && rm *.a *.o', timeout=2500, log = self.log) 82 if self.argDB['download-tetgen-build-exec']: 83 output2,err2,ret2 = config.package.Package.executeShellCommand('cd '+self.packageDir+' && make CXX="'+ self.getCompiler() + '" CXXFLAGS="' + cflags_exe + '" PREDCXXFLAGS="' + predcflags + '" tetgen && cp tetgen ' + binDir + ' && rm tetgen', timeout=2500, log = self.log) 84 except RuntimeError as e: 85 raise RuntimeError('Error running make on TetGen: '+str(e)) 86 output2,err2,ret2 = config.package.Package.executeShellCommand('cp -f '+os.path.join(self.packageDir, 'tetgen.h')+' '+includeDir, timeout=60, log = self.log) 87 self.postInstall(output1+err1+output2+err2,'make.inc') 88 89 self.popLanguage() 90 return self.installDir 91 92 def configureLibrary(self): 93 config.package.Package.configureLibrary(self) 94 include = '#include <tetgen.h>' 95 body = \ 96''' 97 char args[] = ""; 98 tetgenio in,out; 99 tetrahedralize(args, &in, &out); 100''' 101 self.pushLanguage('Cxx') 102 oldFlags = self.compilers.CXXPPFLAGS 103 oldLibs = self.compilers.LIBS 104 self.compilers.CXXPPFLAGS += ' '+self.headers.toString(self.include) 105 self.compilers.LIBS = self.libraries.toString(self.lib)+' '+self.compilers.LIBS 106 if not self.checkCompile(include,body): 107 self.compilers.CXXPPFLAGS += ' -DTETLIBRARY' 108 if self.checkCompile(include,body): 109 self.addDefine('HAVE_TETGEN_TETLIBRARY_NEEDED',1) 110 else: 111 raise RuntimeError('Unable to compile with TetGen') 112 if not self.checkLink(include,body): 113 raise RuntimeError('Unable to link TetGen') 114 self.compilers.CXXPPFLAGS = oldFlags 115 self.compilers.LIBS = oldLibs 116 self.popLanguage() 117