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