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