xref: /petsc/config/PETSc/Configure.py (revision b296d7d5e56c8ec0efc88d498b1fb2f68b8c6a3d)
1import config.base
2
3import os
4import re
5
6# The sorted() builtin is not available with python-2.3
7try: sorted
8except NameError:
9  def sorted(lst):
10    lst.sort()
11    return lst
12
13class Configure(config.base.Configure):
14  def __init__(self, framework):
15    config.base.Configure.__init__(self, framework)
16    self.headerPrefix = 'PETSC'
17    self.substPrefix  = 'PETSC'
18    return
19
20  def __str2__(self):
21    desc = []
22    desc.append('xxx=========================================================================xxx')
23    if self.getMakeMacro('PETSC_BUILD_USING_CMAKE'):
24      build_type = 'cmake build'
25    else:
26      build_type = 'legacy build'
27    desc.append(' Configure stage complete. Now build PETSc libraries with (%s):' % build_type)
28    desc.append('   make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all')
29    desc.append(' or (experimental with python):')
30    desc.append('   PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' ./config/builder.py')
31    desc.append('xxx=========================================================================xxx')
32    return '\n'.join(desc)+'\n'
33
34  def setupHelp(self, help):
35    import nargs
36    help.addArgument('PETSc',  '-prefix=<dir>',                  nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)'))
37    help.addArgument('Windows','-with-windows-graphics=<bool>',   nargs.ArgBool(None, 1,'Enable check for Windows Graphics'))
38    help.addArgument('PETSc', '-with-default-arch=<bool>',        nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH'))
39    help.addArgument('PETSc','-with-single-library=<bool>',       nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library'))
40    help.addArgument('PETSc', '-with-ios=<bool>',              nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library'))
41    return
42
43  def setupDependencies(self, framework):
44    config.base.Configure.setupDependencies(self, framework)
45    self.setCompilers  = framework.require('config.setCompilers',       self)
46    self.arch          = framework.require('PETSc.utilities.arch',      self.setCompilers)
47    self.petscdir      = framework.require('PETSc.utilities.petscdir',  self.setCompilers)
48    self.languages     = framework.require('PETSc.utilities.languages', self.setCompilers)
49    self.debugging     = framework.require('PETSc.utilities.debugging', self.setCompilers)
50    self.CHUD          = framework.require('PETSc.utilities.CHUD',      self)
51    self.compilers     = framework.require('config.compilers',          self)
52    self.types         = framework.require('config.types',              self)
53    self.headers       = framework.require('config.headers',            self)
54    self.functions     = framework.require('config.functions',          self)
55    self.libraries     = framework.require('config.libraries',          self)
56    self.atomics       = framework.require('config.atomics',            self)
57    self.blasLapack    = framework.require('config.packages.BlasLapack',self)
58    if os.path.isdir(os.path.join('config', 'PETSc')):
59      for d in ['utilities', 'packages']:
60        for utility in os.listdir(os.path.join('config', 'PETSc', d)):
61          (utilityName, ext) = os.path.splitext(utility)
62          if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__':
63            utilityObj                    = self.framework.require('PETSc.'+d+'.'+utilityName, self)
64            utilityObj.headerPrefix       = self.headerPrefix
65            utilityObj.archProvider       = self.arch
66            utilityObj.languageProvider   = self.languages
67            utilityObj.installDirProvider = self.petscdir
68            setattr(self, utilityName.lower(), utilityObj)
69
70    for package in config.packages.all:
71      if not package == 'PETSc':
72        packageObj                    = framework.require('config.packages.'+package, self)
73        packageObj.archProvider       = self.arch
74        packageObj.languageProvider   = self.languages
75        packageObj.installDirProvider = self.petscdir
76        setattr(self, package.lower(), packageObj)
77    # Force blaslapack to depend on scalarType so precision is set before BlasLapack is built
78    framework.require('PETSc.utilities.scalarTypes', self.f2cblaslapack)
79    self.f2cblaslapack.precisionProvider = self.scalartypes
80    framework.require('PETSc.utilities.scalarTypes', self.blaslapack)
81    self.blaslapack.precisionProvider = self.scalartypes
82
83    self.compilers.headerPrefix  = self.headerPrefix
84    self.types.headerPrefix      = self.headerPrefix
85    self.headers.headerPrefix    = self.headerPrefix
86    self.functions.headerPrefix  = self.headerPrefix
87    self.libraries.headerPrefix  = self.headerPrefix
88    self.blaslapack.headerPrefix = self.headerPrefix
89    self.mpi.headerPrefix        = self.headerPrefix
90    headersC = map(lambda name: name+'.h', ['setjmp','dos', 'endian', 'fcntl', 'float', 'io', 'limits', 'malloc', 'pwd', 'search', 'strings',
91                                            'unistd', 'sys/sysinfo', 'machine/endian', 'sys/param', 'sys/procfs', 'sys/resource',
92                                            'sys/systeminfo', 'sys/times', 'sys/utsname','string', 'stdlib','memory',
93                                            'sys/socket','sys/wait','netinet/in','netdb','Direct','time','Ws2tcpip','sys/types',
94                                            'WindowsX', 'cxxabi','float','ieeefp','stdint','fenv','sched','pthread'])
95    functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 'getpwuid',
96                 'gettimeofday', 'getwd', 'memalign', 'memmove', 'mkstemp', 'popen', 'PXFGETARG', 'rand', 'getpagesize',
97                 'readlink', 'realpath',  'sigaction', 'signal', 'sigset', 'usleep', 'sleep', '_sleep', 'socket',
98                 'times', 'gethostbyname', 'uname','snprintf','_snprintf','_fullpath','lseek','_lseek','time','fork','stricmp',
99                 'strcasecmp', 'bzero', 'dlopen', 'dlsym', 'dlclose', 'dlerror',
100                 '_intel_fast_memcpy','_intel_fast_memset']
101    libraries1 = [(['socket', 'nsl'], 'socket'), (['fpe'], 'handle_sigfpes')]
102    self.headers.headers.extend(headersC)
103    self.functions.functions.extend(functions)
104    self.libraries.libraries.extend(libraries1)
105
106    return
107
108  def DumpPkgconfig(self):
109    ''' Create a pkg-config file '''
110    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')):
111      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig'))
112    fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig','PETSc.pc'),'w')
113    if self.framework.argDB['prefix']:
114      installdir = self.framework.argDB['prefix']
115      fd.write('prefix='+installdir+'\n')
116      fd.write('exec_prefix=${prefix}\n')
117      fd.write('includedir=${prefix}/include\n')
118      fd.write('libdir='+os.path.join(installdir,'lib')+'\n')
119    else:
120      fd.write('prefix='+self.petscdir.dir+'\n')
121      fd.write('exec_prefix=${prefix}\n')
122      fd.write('includedir=${prefix}/include\n')
123      fd.write('libdir='+os.path.join(self.petscdir.dir,self.arch.arch,'lib')+'\n')
124
125    self.setCompilers.pushLanguage('C')
126    fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n')
127    self.setCompilers.popLanguage()
128    if hasattr(self.compilers, 'C++'):
129      self.setCompilers.pushLanguage('C++')
130      fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n')
131      self.setCompilers.popLanguage()
132    if hasattr(self.compilers, 'FC'):
133      self.setCompilers.pushLanguage('FC')
134      fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n')
135      self.setCompilers.popLanguage()
136    fd.write('blaslapacklibs='+self.libraries.toStringNoDupes(self.blaslapack.lib)+'\n')
137
138    fd.write('\n')
139    fd.write('Name: PETSc\n')
140    fd.write('Description: Library to solve ODEs and algebraic equations\n')
141    fd.write('Version: 3.3\n')  # should figure this out from petscversion.h file
142
143    fd.write('Cflags: '+self.allincludes+'\n')
144
145    if self.framework.argDB['prefix']:
146      fd.write('Libs: '+self.alllibs.replace(os.path.join(self.petscdir.dir,self.arch.arch),self.framework.argDB['prefix'])+'\n')
147    else:
148      fd.write('Libs: '+self.alllibs+'\n')
149    fd.close()
150    return
151
152  def Dump(self):
153    ''' Actually put the values into the configuration files '''
154    # eventually everything between -- should be gone
155#-----------------------------------------------------------------------------------------------------
156
157    # Sometimes we need C compiler, even if built with C++
158    self.setCompilers.pushLanguage('C')
159    self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags())
160    self.setCompilers.popLanguage()
161
162    # C preprocessor values
163    self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS+self.CHUD.CPPFLAGS)
164
165    # compiler values
166    self.setCompilers.pushLanguage(self.languages.clanguage)
167    self.addMakeMacro('PCC',self.setCompilers.getCompiler())
168    self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags())
169    self.setCompilers.popLanguage()
170    # .o or .obj
171    self.addMakeMacro('CC_SUFFIX','o')
172
173    # executable linker values
174    self.setCompilers.pushLanguage(self.languages.clanguage)
175    pcc_linker = self.setCompilers.getLinker()
176    self.addMakeMacro('PCC_LINKER',pcc_linker)
177    self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
178    self.setCompilers.popLanguage()
179    # '' for Unix, .exe for Windows
180    self.addMakeMacro('CC_LINKER_SUFFIX','')
181
182    if hasattr(self.compilers, 'FC'):
183      self.setCompilers.pushLanguage('FC')
184      # need FPPFLAGS in config/setCompilers
185      self.addDefine('HAVE_FORTRAN','1')
186      self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS)
187
188      # compiler values
189      self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags())
190      self.setCompilers.popLanguage()
191      # .o or .obj
192      self.addMakeMacro('FC_SUFFIX','o')
193
194      # executable linker values
195      self.setCompilers.pushLanguage('FC')
196      # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker
197      fc_linker = self.setCompilers.getLinker()
198      if config.setCompilers.Configure.isNAG(fc_linker):
199        self.addMakeMacro('FC_LINKER',pcc_linker)
200      else:
201        self.addMakeMacro('FC_LINKER',fc_linker)
202      self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
203      # apple requires this shared library linker flag on SOME versions of the os
204      if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1:
205        self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ')
206      self.setCompilers.popLanguage()
207
208      # F90 Modules
209      if self.setCompilers.fortranModuleIncludeFlag:
210        self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag)
211      else: # for non-f90 compilers like g77
212        self.addMakeMacro('FC_MODULE_FLAG', '-I')
213      if self.setCompilers.fortranModuleIncludeFlag:
214        self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag)
215    else:
216      self.addMakeMacro('FC','')
217
218    if hasattr(self.compilers, 'CUDAC'):
219      self.setCompilers.pushLanguage('CUDA')
220      self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags())
221      self.setCompilers.popLanguage()
222
223    # shared library linker values
224    self.setCompilers.pushLanguage(self.languages.clanguage)
225    # need to fix BuildSystem to collect these separately
226    self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker())
227    self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}')
228    self.setCompilers.popLanguage()
229    # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture
230    # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX
231    if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX:
232      self.addMakeMacro('SL_LINKER_SUFFIX', '')
233      self.addDefine('SLSUFFIX','""')
234    else:
235      self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt)
236      self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"')
237
238    self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}')
239
240#-----------------------------------------------------------------------------------------------------
241
242    # CONLY or CPP. We should change the PETSc makefiles to do this better
243    if self.languages.clanguage == 'C': lang = 'CONLY'
244    else: lang = 'CXXONLY'
245    self.addMakeMacro('PETSC_LANGUAGE',lang)
246
247    # real or complex
248    self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype)
249    # double or float
250    self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision)
251
252    if self.framework.argDB['with-batch']:
253      self.addMakeMacro('PETSC_WITH_BATCH','1')
254
255    # Test for compiler-specific macros that need to be defined.
256    if self.setCompilers.isCrayVector('CC'):
257      self.addDefine('HAVE_CRAY_VECTOR','1')
258
259#-----------------------------------------------------------------------------------------------------
260    if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'):
261      self.addDefine('USE_SOCKET_VIEWER','1')
262      if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'):
263        self.addDefine('HAVE_SO_REUSEADDR','1')
264
265#-----------------------------------------------------------------------------------------------------
266    # print include and lib for makefiles
267    self.framework.packages.reverse()
268    includes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')]
269    libs = []
270    for i in self.framework.packages:
271      if i.useddirectly:
272        self.addDefine('HAVE_'+i.PACKAGE, 1)  # ONLY list package if it is used directly by PETSc (and not only by another package)
273      if not isinstance(i.lib, list):
274        i.lib = [i.lib]
275      libs.extend(i.lib)
276      self.addMakeMacro(i.PACKAGE+'_LIB', self.libraries.toStringNoDupes(i.lib))
277      if hasattr(i,'include'):
278        if not isinstance(i.include,list):
279          i.include = [i.include]
280        includes.extend(i.include)
281        self.addMakeMacro(i.PACKAGE+'_INCLUDE',self.headers.toStringNoDupes(i.include))
282    if self.framework.argDB['with-single-library']:
283      self.alllibs = self.libraries.toStringNoDupes(['-L'+os.path.join(self.petscdir.dir,self.arch.arch,'lib'),' -lpetsc']+libs+self.libraries.math+self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split(' '))+self.CHUD.LIBS
284      self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.alllibs)
285    self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.libraries.toStringNoDupes(libs+self.libraries.math+self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split(' '))+self.CHUD.LIBS)
286    self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(libs+self.libraries.math+self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split(' '))+self.CHUD.LIBS
287    self.allincludes = self.headers.toStringNoDupes(includes)
288    self.addMakeMacro('PETSC_CC_INCLUDES',self.allincludes)
289    self.PETSC_CC_INCLUDES = self.allincludes
290    if hasattr(self.compilers, 'FC'):
291      if self.compilers.fortranIsF90:
292        self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes,includes))
293      else:
294        self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes))
295
296    self.addMakeMacro('DESTDIR',self.installdir)
297    self.addDefine('LIB_DIR','"'+os.path.join(self.installdir,'lib')+'"')
298
299    if self.framework.argDB['with-single-library']:
300      # overrides the values set in conf/variables
301      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}')
302      self.addMakeMacro('SHLIBS','libpetsc')
303      self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc')
304      self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc')
305      self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc')
306      self.addDefine('USE_SINGLE_LIBRARY', '1')
307      if self.sharedlibraries.useShared:
308        self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
309        self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
310        self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
311        self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
312        self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
313        self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
314        self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
315        self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
316        self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
317        self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
318      else:
319        self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}')
320        self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
321        self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}')
322        self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}')
323        self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}')
324        self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}')
325        self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}')
326        self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
327        self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
328        self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}')
329
330    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')):
331      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib'))
332
333    # add a makefile entry for configure options
334    self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"'))
335    return
336
337  def dumpConfigInfo(self):
338    import time
339    fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w')
340    fd.write('static const char *petscconfigureruntime = "'+time.ctime(time.time())+'";\n')
341    fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n')
342    fd.close()
343    return
344
345  def dumpMachineInfo(self):
346    import platform
347    import time
348    import script
349    fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w')
350    fd.write('static const char *petscmachineinfo = \"\\n\"\n')
351    fd.write('\"-----------------------------------------\\n\"\n')
352    fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (time.ctime(time.time()), platform.node()))
353    fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform()))
354    fd.write('\"Using PETSc directory: %s\\n\"\n' % (self.petscdir.dir))
355    fd.write('\"Using PETSc arch: %s\\n\"\n' % (self.arch.arch))
356    fd.write('\"-----------------------------------------\\n\";\n')
357    fd.write('static const char *petsccompilerinfo = \"\\n\"\n')
358    self.setCompilers.pushLanguage(self.languages.clanguage)
359    fd.write('\"Using C compiler: %s %s ${COPTFLAGS} ${CFLAGS}\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags()))
360    self.setCompilers.popLanguage()
361    if hasattr(self.compilers, 'FC'):
362      self.setCompilers.pushLanguage('FC')
363      fd.write('\"Using Fortran compiler: %s %s ${FOPTFLAGS} ${FFLAGS} %s\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags(), self.setCompilers.CPPFLAGS))
364      self.setCompilers.popLanguage()
365    fd.write('\"-----------------------------------------\\n\";\n')
366    fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n')
367    fd.write('\"Using include paths: %s %s %s\\n\"\n' % ('-I'+os.path.join(self.petscdir.dir, self.arch.arch, 'include'), '-I'+os.path.join(self.petscdir.dir, 'include'), self.PETSC_CC_INCLUDES.replace('\\ ','\\\\ ')))
368    fd.write('\"-----------------------------------------\\n\";\n')
369    fd.write('static const char *petsclinkerinfo = \"\\n\"\n')
370    self.setCompilers.pushLanguage(self.languages.clanguage)
371    fd.write('\"Using C linker: %s\\n\"\n' % (self.setCompilers.getLinker()))
372    self.setCompilers.popLanguage()
373    if hasattr(self.compilers, 'FC'):
374      self.setCompilers.pushLanguage('FC')
375      fd.write('\"Using Fortran linker: %s\\n\"\n' % (self.setCompilers.getLinker()))
376      self.setCompilers.popLanguage()
377    if self.framework.argDB['with-single-library']:
378      petsclib = '-lpetsc'
379    else:
380      petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys'
381    fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (self.setCompilers.CSharedLinkerFlag, os.path.join(self.petscdir.dir, self.arch.arch, 'lib'), os.path.join(self.petscdir.dir, self.arch.arch, 'lib'), petsclib, self.PETSC_EXTERNAL_LIB_BASIC.replace('\\ ','\\\\ ')))
382    fd.write('\"-----------------------------------------\\n\";\n')
383    fd.close()
384    return
385
386  def dumpCMakeConfig(self):
387    '''
388    Writes configuration-specific values to ${PETSC_ARCH}/conf/PETScConfig.cmake.
389    This file is private to PETSc and should not be included by third parties
390    (a suitable file can be produced later by CMake, but this is not it).
391    '''
392    def cmakeset(fd,key,val=True):
393      if val == True: val = 'YES'
394      if val == False: val = 'NO'
395      fd.write('set (' + key + ' ' + val + ')\n')
396    def ensurelist(a):
397      if isinstance(a,list):
398        return a
399      else:
400        return [a]
401    def libpath(lib):
402      'Returns a search path if that is what this item provides, else "" which will be cleaned out later'
403      if not isinstance(lib,str): return ''
404      if lib.startswith('-L'): return lib[2:]
405      if lib.startswith('-R'): return lib[2:]
406      if lib.startswith('-Wl,-rpath,'):
407        # This case occurs when an external package needs a specific system library that is normally provided by the compiler.
408        # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the
409        # corresponding library.
410        return lib[len('-Wl,-rpath,'):]
411      if lib.startswith('-'): return ''
412      return os.path.dirname(lib)
413    def cleanlib(lib):
414      'Returns a library name if that is what this item provides, else "" which will be cleaned out later'
415      if not isinstance(lib,str): return ''
416      if lib.startswith('-l'):  return lib[2:]
417      if lib.startswith('-Wl') or lib.startswith('-L'): return ''
418      lib = os.path.splitext(os.path.basename(lib))[0]
419      if lib.startswith('lib'): return lib[3:]
420      return lib
421    def nub(lst):
422      'Return a list containing the first occurrence of each unique element'
423      unique = []
424      for elem in lst:
425        if elem not in unique and elem != '':
426          unique.append(elem)
427      return unique
428    try: reversed # reversed was added in Python-2.4
429    except NameError:
430      def reversed(lst): return lst[::-1]
431    def nublast(lst):
432      'Return a list containing the last occurrence of each unique entry in a list'
433      return reversed(nub(reversed(lst)))
434    def cmakeexpand(varname):
435      return r'"${' + varname + r'}"'
436    def uniqextend(lst,new):
437      for x in ensurelist(new):
438        if x not in lst:
439          lst.append(x)
440    def notstandardinclude(path):
441      return path not in '/usr/include'.split() # /usr/local/include is not automatically included on FreeBSD
442    def writeMacroDefinitions(fd):
443      if self.mpi.usingMPIUni:
444        cmakeset(fd,'PETSC_HAVE_MPIUNI')
445      for pkg in self.framework.packages:
446        if pkg.useddirectly:
447          cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE)
448        for pair in pkg.defines.items():
449          if pair[0].startswith('HAVE_') and pair[1]:
450            cmakeset(fd, self.framework.getFullDefineName(pkg, pair[0]), pair[1])
451      for name,val in self.functions.defines.items():
452        cmakeset(fd,'PETSC_'+name,val)
453      for dct in [self.defines, self.libraryoptions.defines]:
454        for k,v in dct.items():
455          if k.startswith('USE_'):
456            cmakeset(fd,'PETSC_' + k, v)
457      cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex')
458      cmakeset(fd,'PETSC_USE_REAL_' + self.scalartypes.precision.upper())
459      cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage)
460      if hasattr(self.compilers, 'FC'):
461        cmakeset(fd,'PETSC_HAVE_FORTRAN')
462        if self.compilers.fortranIsF90:
463          cmakeset(fd,'PETSC_USING_F90')
464        if self.compilers.fortranIsF2003:
465          cmakeset(fd,'PETSC_USING_F2003')
466      if hasattr(self.compilers, 'CXX'):
467        cmakeset(fd,'PETSC_HAVE_CXX')
468      if self.sharedlibraries.useShared:
469        cmakeset(fd,'BUILD_SHARED_LIBS')
470    def writeBuildFlags(fd):
471      def extendby(lib):
472        libs = ensurelist(lib)
473        lib_paths.extend(map(libpath,libs))
474        lib_libs.extend(map(cleanlib,libs))
475      lib_paths = []
476      lib_libs  = []
477      includes  = []
478      libvars   = []
479      for pkg in self.framework.packages:
480        extendby(pkg.lib)
481        uniqextend(includes,pkg.include)
482      extendby(self.libraries.math)
483      extendby(self.libraries.rt)
484      extendby(self.compilers.flibs)
485      extendby(self.compilers.cxxlibs)
486      extendby(self.compilers.LIBS.split())
487      for libname in nublast(lib_libs):
488        libvar = 'PETSC_' + libname.upper() + '_LIB'
489        addpath = ''
490        for lpath in nublast(lib_paths):
491          addpath += '"' + str(lpath) + '" '
492        fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n')
493        libvars.append(libvar)
494      fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n')
495      fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n')
496      includes = filter(notstandardinclude,includes)
497      fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',includes)) + ')\n')
498    fd = open(os.path.join(self.arch.arch,'conf','PETScConfig.cmake'), 'w')
499    writeMacroDefinitions(fd)
500    writeBuildFlags(fd)
501    fd.close()
502    return
503
504  def dumpCMakeLists(self):
505    import sys
506    if sys.version_info >= (2,5):
507      import cmakegen
508      try:
509        cmakegen.main(self.petscdir.dir, log=self.framework.log)
510      except (OSError), e:
511        self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e))
512    else:
513      self.framework.logPrint('Skipping cmakegen due to old python version: ' +str(sys.version_info) )
514
515  def cmakeBoot(self):
516    import sys
517    self.cmakeboot_success = False
518    if sys.version_info >= (2,5) and hasattr(self.cmake,'cmake'):
519      try:
520        import cmakeboot
521        self.cmakeboot_success = cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,log=self.framework.log)
522      except (OSError), e:
523        self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e))
524      except (ImportError, KeyError), e:
525        self.framework.logPrint('Importing cmakeboot failed:\n' + str(e))
526      if self.cmakeboot_success:
527        if self.framework.argDB['with-cuda']: # Our CMake build does not support CUDA at this time
528          self.framework.logPrint('CMake configured successfully, but could not be used by default because --with-cuda was used\n')
529        elif hasattr(self.compilers, 'FC') and self.compilers.fortranIsF90 and not self.setCompilers.fortranModuleOutputFlag:
530          self.framework.logPrint('CMake configured successfully, but could not be used by default because of missing fortranModuleOutputFlag\n')
531        else:
532          self.framework.logPrint('CMake configured successfully, using as default build\n')
533          self.addMakeMacro('PETSC_BUILD_USING_CMAKE',1)
534      else:
535        self.framework.logPrint('CMake configuration was unsuccessful\n')
536    else:
537      self.framework.logPrint('Skipping cmakeboot due to old python version: ' +str(sys.version_info) )
538    return
539
540  def configurePrefetch(self):
541    '''Sees if there are any prefetch functions supported'''
542    if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-ios']:
543      self.addDefine('Prefetch(a,b,c)', ' ')
544      return
545    self.pushLanguage(self.languages.clanguage)
546    if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'):
547      # The Intel Intrinsics manual [1] specifies the prototype
548      #
549      #   void _mm_prefetch(char const *a, int sel);
550      #
551      # but other vendors seem to insist on using subtly different
552      # prototypes, including void* for the pointer, and an enum for
553      # sel.  These are both reasonable changes, but negatively impact
554      # portability.
555      #
556      # [1] http://software.intel.com/file/6373
557      self.addDefine('HAVE_XMMINTRIN_H', 1)
558      self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))')
559      self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA')
560      self.addDefine('PREFETCH_HINT_T0',  '_MM_HINT_T0')
561      self.addDefine('PREFETCH_HINT_T1',  '_MM_HINT_T1')
562      self.addDefine('PREFETCH_HINT_T2',  '_MM_HINT_T2')
563    elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'):
564      self.addDefine('HAVE_XMMINTRIN_H', 1)
565      self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))')
566      self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA')
567      self.addDefine('PREFETCH_HINT_T0',  '_MM_HINT_T0')
568      self.addDefine('PREFETCH_HINT_T1',  '_MM_HINT_T1')
569      self.addDefine('PREFETCH_HINT_T2',  '_MM_HINT_T2')
570    elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'):
571      # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality)
572      #
573      #   The value of rw is a compile-time constant one or zero; one
574      #   means that the prefetch is preparing for a write to the memory
575      #   address and zero, the default, means that the prefetch is
576      #   preparing for a read. The value locality must be a compile-time
577      #   constant integer between zero and three. A value of zero means
578      #   that the data has no temporal locality, so it need not be left
579      #   in the cache after the access. A value of three means that the
580      #   data has a high degree of temporal locality and should be left
581      #   in all levels of cache possible. Values of one and two mean,
582      #   respectively, a low or moderate degree of temporal locality.
583      #
584      # Here we adopt Intel's x86/x86-64 naming scheme for the locality
585      # hints.  Using macros for these values in necessary since some
586      # compilers require an enum.
587      self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))')
588      self.addDefine('PREFETCH_HINT_NTA', '0')
589      self.addDefine('PREFETCH_HINT_T0',  '3')
590      self.addDefine('PREFETCH_HINT_T1',  '2')
591      self.addDefine('PREFETCH_HINT_T2',  '1')
592    else:
593      self.addDefine('Prefetch(a,b,c)', ' ')
594    self.popLanguage()
595
596  def configureFeatureTestMacros(self):
597    '''Checks if certain feature test macros are support'''
598    if self.checkCompile('#define _POSIX_C_SOURCE 200112L\n#include <sysctl.h>',''):
599       self.addDefine('_POSIX_C_SOURCE_200112L', '1')
600    if self.checkCompile('#define _BSD_SOURCE\n#include<stdlib.h>',''):
601       self.addDefine('_BSD_SOURCE', '1')
602    if self.checkCompile('#define _GNU_SOURCE\n#include <sched.h>','cpu_set_t mset;\nCPU_ZERO(&mset);'):
603       self.addDefine('_GNU_SOURCE', '1')
604
605  def configureAtoll(self):
606    '''Checks if atoll exists'''
607    if self.checkCompile('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25")') or self.checkCompile ('#include <stdlib.h>','long v = atoll("25")'):
608       self.addDefine('HAVE_ATOLL', '1')
609
610  def configureUnused(self):
611    '''Sees if __attribute((unused)) is supported'''
612    if self.framework.argDB['with-ios']:
613      self.addDefine('UNUSED', ' ')
614      return
615    self.pushLanguage(self.languages.clanguage)
616    if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\ntypedef void* atype;\n__attribute((unused))  atype a;\n'):
617      self.addDefine('UNUSED', '__attribute((unused))')
618    else:
619      self.addDefine('UNUSED', ' ')
620    self.popLanguage()
621
622  def configureExpect(self):
623    '''Sees if the __builtin_expect directive is supported'''
624    self.pushLanguage(self.languages.clanguage)
625    if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'):
626      self.addDefine('HAVE_BUILTIN_EXPECT', 1)
627    self.popLanguage()
628
629  def configureFunctionName(self):
630    '''Sees if the compiler supports __func__ or a variant.  Falls back
631    on __FUNCT__ which PETSc source defines, but most users do not, thus
632    stack traces through user code are better when the compiler's
633    variant is used.'''
634    def getFunctionName(lang):
635      name = '__FUNCT__'
636      self.pushLanguage(lang)
637      if self.checkLink('', "if (__func__[0] != 'm') return 1;"):
638        name = '__func__'
639      elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"):
640        name = '__FUNCTION__'
641      self.popLanguage()
642      return name
643    langs = []
644
645    self.addDefine('FUNCTION_NAME_C', getFunctionName('C'))
646    if hasattr(self.compilers, 'CXX'):
647      self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx'))
648    else:
649      self.addDefine('FUNCTION_NAME_CXX', '__FUNCT__')
650
651  def configureIntptrt(self):
652    '''Determine what to use for uintptr_t'''
653    def staticAssertSizeMatchesVoidStar(inc,typename):
654      # The declaration is an error if either array size is negative.
655      # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case
656      return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n'
657                                     + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename))
658    self.pushLanguage(self.languages.clanguage)
659    if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'):
660      self.addDefine('UINTPTR_T', 'uintptr_t')
661    elif staticAssertSizeMatchesVoidStar('','unsigned long long'):
662      self.addDefine('UINTPTR_T', 'unsigned long long')
663    elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'):
664      self.addDefine('UINTPTR_T', 'size_t')
665    elif staticAssertSizeMatchesVoidStar('','unsigned long'):
666      self.addDefine('UINTPTR_T', 'unsigned long')
667    elif staticAssertSizeMatchesVoidStar('','unsigned'):
668      self.addDefine('UINTPTR_T', 'unsigned')
669    else:
670      raise RuntimeError('Could not find any unsigned integer type matching void*')
671    self.popLanguage()
672
673  def configureInline(self):
674    '''Get a generic inline keyword, depending on the language'''
675    if self.languages.clanguage == 'C':
676      self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword)
677      self.addDefine('RESTRICT', self.compilers.cRestrict)
678    elif self.languages.clanguage == 'Cxx':
679      self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword)
680      self.addDefine('RESTRICT', self.compilers.cxxRestrict)
681
682    if self.checkCompile('#include <dlfcn.h>\n void *ptr =  RTLD_DEFAULT;'):
683      self.addDefine('RTLD_DEFAULT','1')
684    return
685
686  def configureSolaris(self):
687    '''Solaris specific stuff'''
688    if os.path.isdir(os.path.join('/usr','ucblib')):
689      try:
690        flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag')
691      except AttributeError:
692        flag = None
693      if flag is None:
694        self.compilers.LIBS += ' -L/usr/ucblib'
695      else:
696        self.compilers.LIBS += ' '+flag+'/usr/ucblib'
697    return
698
699  def configureLinux(self):
700    '''Linux specific stuff'''
701    # TODO: Test for this by mallocing an odd number of floats and checking the address
702    self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1)
703    return
704
705  def configureWin32(self):
706    '''Win32 non-cygwin specific stuff'''
707    kernel32=0
708    if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'):
709      self.addDefine('HAVE_WINDOWS_H',1)
710      self.addDefine('HAVE_GETCOMPUTERNAME',1)
711      kernel32=1
712    elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'):
713      self.addDefine('HAVE_WINDOWS_H',1)
714      self.addDefine('HAVE_GETCOMPUTERNAME',1)
715      kernel32=1
716    if kernel32:
717      if self.framework.argDB['with-windows-graphics']:
718        self.addDefine('USE_WINDOWS_GRAPHICS',1)
719      if self.checkLink('#include <Windows.h>','LoadLibrary(0)'):
720        self.addDefine('HAVE_LOADLIBRARY',1)
721      if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'):
722        self.addDefine('HAVE_GETPROCADDRESS',1)
723      if self.checkLink('#include <Windows.h>','FreeLibrary(0)'):
724        self.addDefine('HAVE_FREELIBRARY',1)
725      if self.checkLink('#include <Windows.h>','GetLastError()'):
726        self.addDefine('HAVE_GETLASTERROR',1)
727      if self.checkLink('#include <Windows.h>','SetLastError(0)'):
728        self.addDefine('HAVE_SETLASTERROR',1)
729      if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'):
730        self.addDefine('USE_NT_TIME',1)
731    if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'):
732      self.addDefine('HAVE_GET_USER_NAME',1)
733    elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'):
734      self.addDefine('HAVE_GET_USER_NAME',1)
735
736    if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'):
737      self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);')
738    if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'):
739      self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);')
740
741    self.types.check('int32_t', 'int')
742    if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'):
743      self.addTypedef('int', 'uid_t')
744      self.addTypedef('int', 'gid_t')
745    if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'):
746      self.framework.addDefine('R_OK', '04')
747      self.framework.addDefine('W_OK', '02')
748      self.framework.addDefine('X_OK', '01')
749    if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'):
750      self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)')
751      self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)')
752    if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'):
753      self.addDefine('HAVE_LARGE_INTEGER_U',1)
754
755    # Windows requires a Binary file creation flag when creating/opening binary files.  Is a better test in order?
756    if self.checkCompile('#include <Windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'):
757      self.addDefine('HAVE_O_BINARY',1)
758
759    if self.compilers.CC.find('win32fe') >= 0:
760      self.addDefine('PATH_SEPARATOR','\';\'')
761      self.addDefine('DIR_SEPARATOR','\'\\\\\'')
762      self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'')
763      self.addDefine('CANNOT_START_DEBUGGER',1)
764    else:
765      self.addDefine('PATH_SEPARATOR','\':\'')
766      self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'')
767      self.addDefine('DIR_SEPARATOR','\'/\'')
768
769    return
770
771#-----------------------------------------------------------------------------------------------------
772  def configureDefaultArch(self):
773    conffile = os.path.join('conf', 'petscvariables')
774    if self.framework.argDB['with-default-arch']:
775      fd = file(conffile, 'w')
776      fd.write('PETSC_ARCH='+self.arch.arch+'\n')
777      fd.write('PETSC_DIR='+self.petscdir.dir+'\n')
778      fd.write('include '+os.path.join(self.petscdir.dir,self.arch.arch,'conf','petscvariables')+'\n')
779      fd.close()
780      self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile)
781    elif os.path.isfile(conffile):
782      try:
783        os.unlink(conffile)
784      except:
785        raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?')
786    return
787
788#-----------------------------------------------------------------------------------------------------
789  def configureScript(self):
790    '''Output a script in the conf directory which will reproduce the configuration'''
791    import nargs
792    import sys
793    scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py')
794    args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs])
795    if 'configModules' in args:
796      if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure':
797        del args['configModules']
798    if 'optionsModule' in args:
799      if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions':
800        del args['optionsModule']
801    if not 'PETSC_ARCH' in args:
802      args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch)
803    f = file(scriptName, 'w')
804    f.write('#!'+sys.executable+'\n')
805    f.write('if __name__ == \'__main__\':\n')
806    f.write('  import sys\n')
807    f.write('  import os\n')
808    f.write('  sys.path.insert(0, os.path.abspath(\'config\'))\n')
809    f.write('  import configure\n')
810    # pretty print repr(args.values())
811    f.write('  configure_options = [\n')
812    for itm in sorted(args.values()):
813      f.write('    \''+str(itm)+'\',\n')
814    f.write('  ]\n')
815    f.write('  configure.petsc_configure(configure_options)\n')
816    f.close()
817    try:
818      os.chmod(scriptName, 0775)
819    except OSError, e:
820      self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e))
821    self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration')
822    return
823
824  def configureInstall(self):
825    '''Setup the directories for installation'''
826    if self.framework.argDB['prefix']:
827      self.installdir = self.framework.argDB['prefix']
828      self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\
829                                              '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\
830                                              '-@echo "========================================="'])
831    else:
832      self.installdir = os.path.join(self.petscdir.dir,self.arch.arch)
833      self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\
834                                              '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\
835                                              '-@echo "========================================="'])
836      return
837
838  def configureGCOV(self):
839    if self.framework.argDB['with-gcov']:
840      self.addDefine('USE_GCOV','1')
841    return
842
843  def configureFortranFlush(self):
844    if hasattr(self.compilers, 'FC'):
845      for baseName in ['flush','flush_']:
846        if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1):
847          self.addDefine('HAVE_'+baseName.upper(), 1)
848          return
849
850  def postProcessPackages(self):
851    postPackages=[]
852    for i in self.framework.packages:
853      if hasattr(i,'postProcess'): postPackages.append(i)
854    if postPackages:
855      # ctetgen needs petsc conf files. so attempt to create them early
856      self.framework.dumpConfFiles()
857      for i in postPackages: i.postProcess()
858    return
859
860  def configure(self):
861    if not os.path.samefile(self.petscdir.dir, os.getcwd()):
862      raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n  Configure invoked in: '+os.path.realpath(os.getcwd()))
863    if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir):
864      raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!')
865    if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],os.path.join(self.petscdir.dir,self.arch.arch)):
866      raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!')
867    self.framework.header          = os.path.join(self.arch.arch,'include','petscconf.h')
868    self.framework.cHeader         = os.path.join(self.arch.arch,'include','petscfix.h')
869    self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables')
870    self.framework.makeRuleHeader  = os.path.join(self.arch.arch,'conf','petscrules')
871    if self.libraries.math is None:
872      raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.')
873    if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'):
874      raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.')
875    self.executeTest(self.configureInline)
876    self.executeTest(self.configurePrefetch)
877    self.executeTest(self.configureUnused)
878    self.executeTest(self.configureExpect);
879    self.executeTest(self.configureFunctionName);
880    self.executeTest(self.configureIntptrt);
881    self.executeTest(self.configureSolaris)
882    self.executeTest(self.configureLinux)
883    self.executeTest(self.configureWin32)
884    self.executeTest(self.configureDefaultArch)
885    self.executeTest(self.configureScript)
886    self.executeTest(self.configureInstall)
887    self.executeTest(self.configureGCOV)
888    self.executeTest(self.configureFortranFlush)
889    self.executeTest(self.configureFeatureTestMacros)
890    self.executeTest(self.configureAtoll)
891    # dummy rules, always needed except for remote builds
892    self.addMakeRule('remote','')
893    self.addMakeRule('remoteclean','')
894
895    self.Dump()
896    self.dumpConfigInfo()
897    self.dumpMachineInfo()
898    self.postProcessPackages()
899    self.dumpCMakeConfig()
900    self.dumpCMakeLists()
901    self.cmakeBoot()
902    self.DumpPkgconfig()
903    self.framework.log.write('================================================================================\n')
904    self.logClear()
905    return
906