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