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