xref: /petsc/config/PETSc/Configure.py (revision b6e6beb40ac0a73ccc19b70153df96d5058dce43)
1import config.base
2
3import os
4import sys
5import re
6import pickle
7
8class Configure(config.base.Configure):
9  def __init__(self, framework):
10    config.base.Configure.__init__(self, framework)
11    self.headerPrefix = 'PETSC'
12    self.substPrefix  = 'PETSC'
13    self.installed    = 0 # 1 indicates that Configure itself has already compiled and installed PETSc
14    self.found        = 1
15    return
16
17  def __str2__(self):
18    desc = ['  Using GNU make: ' + self.make.make]
19    if self.defines.get('USE_COVERAGE'):
20      desc.extend([
21        '  Code coverage: yes',
22        '  Using code coverage executable: {}'.format(self.getMakeMacro('PETSC_COVERAGE_EXEC'))
23      ])
24    if not self.installed:
25      desc.append('xxx=========================================================================xxx')
26      desc.append(' Configure stage complete. Now build PETSc libraries with:')
27      desc.append('   %s PETSC_DIR=%s PETSC_ARCH=%s all' % (self.make.make_user, self.petscdir.dir, self.arch.arch))
28      desc.append('xxx=========================================================================xxx')
29    else:
30      desc.append('xxx=========================================================================xxx')
31      desc.append(' Installation complete. You do not need to run make to compile or install the software')
32      desc.append('xxx=========================================================================xxx')
33    desc.append('')
34    return '\n'.join(desc)
35
36  def setupHelp(self, help):
37    import nargs
38    help.addArgument('PETSc',  '-prefix=<dir>',                              nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)'))
39    help.addArgument('PETSc',  '-with-prefetch=<bool>',                      nargs.ArgBool(None, 1,'Enable checking for prefetch instructions'))
40    help.addArgument('Windows','-with-windows-graphics=<bool>',              nargs.ArgBool(None, 1,'Enable check for Windows Graphics'))
41    help.addArgument('PETSc', '-with-default-arch=<bool>',                   nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH'))
42    help.addArgument('PETSc','-with-single-library=<bool>',                  nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library'))
43    help.addArgument('PETSc','-with-fortran-bindings=<bool>',                nargs.ArgBool(None, 1,'Build PETSc fortran bindings in the library and corresponding module files'))
44    help.addArgument('PETSc', '-with-ios=<bool>',                            nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library'))
45    help.addArgument('PETSc', '-with-display=<x11display>',                  nargs.Arg(None, '', 'Specifiy DISPLAY env variable for use with matlab test)'))
46    help.addArgument('PETSc', '-with-package-scripts=<pyscripts>',           nargs.ArgFileList(None,None,'Specify configure package scripts for user provided packages'))
47    help.addArgument('PETSc', '-with-coverage=<bool>',                       nargs.ArgFuzzyBool(None, value=0, help='Enable or disable code-coverage collection'))
48    help.addArgument('PETSc', '-with-coverage-exec=<executable>',            nargs.ArgExecutable(None, value='default-auto', mustExist=0, help='Name of executable to use for post-processing coverage data, e.g. \'gcov\' or \'llvm-cov\'. Pass \'auto\' to let configure infer from compiler'))
49    help.addArgument('PETSc', '-with-tau-perfstubs=<bool>',                  nargs.ArgBool(None, 1,'Enable TAU profiler stubs'))
50    help.addArgument('PETSc', '-with-strict-petscerrorcode=<bool>',          nargs.ArgFuzzyBool(None, value=0, help='Enable strict PetscErrorCode mode, which enables additional compile-time checking for misuse of PetscErrorCode and error handling'))
51    return
52
53  def registerPythonFile(self,filename,directory):
54    ''' Add a python file to the framework and registers its headerprefix, ... externalpackagedir
55        directory is the directory where the file relative to the BuildSystem or config path in python notation with . '''
56    (utilityName, ext) = os.path.splitext(filename)
57    if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__':
58      if directory: directory = directory+'.'
59      utilityObj                             = self.framework.require(directory+utilityName, self)
60      utilityObj.headerPrefix                = self.headerPrefix
61      utilityObj.archProvider                = self.arch
62      utilityObj.languageProvider            = self.languages
63      utilityObj.installDirProvider          = self.installdir
64      utilityObj.externalPackagesDirProvider = self.externalpackagesdir
65      utilityObj.precisionProvider           = self.scalartypes
66      utilityObj.indexProvider               = self.indexTypes
67      setattr(self, utilityName.lower(), utilityObj)
68      return utilityObj
69    return None
70
71  def setupDependencies(self, framework):
72    config.base.Configure.setupDependencies(self, framework)
73    self.programs      = framework.require('config.programs',           self)
74    self.setCompilers  = framework.require('config.setCompilers',       self)
75    self.compilerFlags = framework.require('config.compilerFlags',      self)
76    self.compilers     = framework.require('config.compilers',          self)
77    self.arch          = framework.require('PETSc.options.arch',        self.setCompilers)
78    self.petscdir      = framework.require('PETSc.options.petscdir',    self.arch)
79    self.installdir    = framework.require('PETSc.options.installDir',  self)
80    self.dataFilesPath = framework.require('PETSc.options.dataFilesPath',self)
81    self.scalartypes   = framework.require('PETSc.options.scalarTypes', self)
82    self.indexTypes    = framework.require('PETSc.options.indexTypes',  self)
83    self.languages     = framework.require('PETSc.options.languages',   self.setCompilers)
84    self.indexTypes    = framework.require('PETSc.options.indexTypes',  self.compilers)
85    self.types         = framework.require('config.types',              self)
86    self.headers       = framework.require('config.headers',            self)
87    self.functions     = framework.require('config.functions',          self)
88    self.libraries     = framework.require('config.libraries',          self)
89    self.atomics       = framework.require('config.atomics',            self)
90    self.make          = framework.require('config.packages.make',      self)
91    self.blasLapack    = framework.require('config.packages.BlasLapack',self)
92    self.mpi           = framework.require('config.packages.MPI',       self)
93    self.fortran       = framework.require('config.compilersFortran',   self)
94    self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self)
95
96    for utility in sorted(os.listdir(os.path.join('config','PETSc','options'))):
97      self.registerPythonFile(utility,'PETSc.options')
98
99    for utility in sorted(os.listdir(os.path.join('config','BuildSystem','config','utilities'))):
100      self.registerPythonFile(utility,'config.utilities')
101
102    for package in sorted(os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages'))):
103      obj = self.registerPythonFile(package,'config.packages')
104      if obj:
105        obj.archProvider                = self.framework.requireModule(obj.archProvider, obj)
106        obj.languageProvider            = self.framework.requireModule(obj.languageProvider, obj)
107        obj.installDirProvider          = self.framework.requireModule(obj.installDirProvider, obj)
108        obj.externalPackagesDirProvider = self.framework.requireModule(obj.externalPackagesDirProvider, obj)
109        obj.precisionProvider           = self.framework.requireModule(obj.precisionProvider, obj)
110        obj.indexProvider               = self.framework.requireModule(obj.indexProvider, obj)
111
112    # Force blaslapack and opencl to depend on scalarType so precision is set before BlasLapack is built
113    framework.require('PETSc.options.scalarTypes', self.f2cblaslapack)
114    framework.require('PETSc.options.scalarTypes', self.fblaslapack)
115    framework.require('PETSc.options.scalarTypes', self.blaslapack)
116    framework.require('PETSc.options.scalarTypes', self.opencl)
117
118    self.programs.headerPrefix     = self.headerPrefix
119    self.setCompilers.headerPrefix = self.headerPrefix
120    self.compilers.headerPrefix    = self.headerPrefix
121    self.fortran.headerPrefix      = self.headerPrefix
122    self.types.headerPrefix        = self.headerPrefix
123    self.headers.headerPrefix      = self.headerPrefix
124    self.functions.headerPrefix    = self.headerPrefix
125    self.libraries.headerPrefix    = self.headerPrefix
126
127    # Register user provided package scripts
128    if 'with-package-scripts' in self.framework.argDB:
129      for script in self.framework.argDB['with-package-scripts']:
130        if os.path.splitext(script)[1] != '.py':
131          raise RuntimeError('Only python scripts compatible with configure package script format should be specified! Invalid option -with-package-scripts='+script)
132        self.framework.logPrint('User is registering a new package script: '+script)
133        dname,fname = os.path.split(script)
134        if dname: sys.path.append(dname)
135        self.registerPythonFile(fname,'')
136
137    # test for a variety of basic headers and functions
138    headersC = map(lambda name: name+'.h',['setjmp','dos','fcntl','float','io','malloc','pwd','strings',
139                                            'unistd','sys/sysinfo','machine/endian','sys/param','sys/procfs','sys/resource',
140                                            'sys/systeminfo','sys/times','sys/utsname',
141                                            'sys/socket','sys/wait','netinet/in','netdb','direct','time','Ws2tcpip','sys/types',
142                                            'WindowsX','float','ieeefp','stdint','inttypes','immintrin'])
143    functions = ['access','_access','clock','drand48','getcwd','_getcwd','getdomainname','gethostname',
144                 'getwd','posix_memalign','popen','PXFGETARG','rand','getpagesize',
145                 'readlink','realpath','usleep','sleep','_sleep',
146                 'uname','snprintf','_snprintf','lseek','_lseek','time','fork','stricmp',
147                 'strcasecmp','bzero','dlopen','dlsym','dlclose','dlerror',
148                 '_set_output_format','_mkdir','socket','gethostbyname','fpresetsticky',
149                 'fpsetsticky','__gcov_dump']
150    libraries = [(['fpe'],'handle_sigfpes')]
151    librariessock = [(['socket','nsl'],'socket')]
152    self.headers.headers.extend(headersC)
153    self.functions.functions.extend(functions)
154    self.libraries.libraries.extend(libraries)
155    if not hasattr(self,'socket'):
156      self.libraries.libraries.extend(librariessock)
157    return
158
159  def DumpPkgconfig(self, petsc_pc):
160    ''' Create a pkg-config file '''
161    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')):
162      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig'))
163    with open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig',petsc_pc),'w') as fd:
164      cflags_inc = ['-I${includedir}']
165      if self.framework.argDB['prefix']:
166        fd.write('prefix='+self.installdir.dir+'\n')
167      else:
168        fd.write('prefix='+os.path.join(self.petscdir.dir, self.arch.arch)+'\n')
169        cflags_inc.append('-I' + os.path.join(self.petscdir.dir, 'include'))
170      fd.write('exec_prefix=${prefix}\n')
171      fd.write('includedir=${prefix}/include\n')
172      fd.write('libdir=${prefix}/lib\n')
173
174      with self.setCompilers.Language('C'):
175        fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n')
176        fd.write('cflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n')
177        fd.write('cflags_dep='+self.compilers.dependenciesGenerationFlag.get('C','')+'\n')
178        fd.write('ldflag_rpath='+self.setCompilers.CSharedLinkerFlag+'\n')
179      if hasattr(self.compilers, 'CXX'):
180        with self.setCompilers.Language('C++'):
181          fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n')
182          fd.write('cxxflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n')
183      if hasattr(self.compilers, 'FC'):
184        with self.setCompilers.Language('FC'):
185          fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n')
186          fd.write('fflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n')
187      if hasattr(self.compilers, 'CUDAC'):
188        with self.setCompilers.Language('CUDA'):
189          fd.write('cudacompiler='+self.setCompilers.getCompiler()+'\n')
190          fd.write('cudaflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n')
191          p = self.framework.require('config.packages.cuda')
192          fd.write('cudalib='+self.libraries.toStringNoDupes(p.lib)+'\n')
193          fd.write('cudainclude='+self.headers.toStringNoDupes(p.include)+'\n')
194          if hasattr(self.setCompilers,'CUDA_CXX'):
195            fd.write('cuda_cxx='+self.setCompilers.CUDA_CXX+'\n')
196            fd.write('cuda_cxxflags='+self.setCompilers.CUDA_CXXFLAGS+'\n')
197
198      fd.write('\n')
199      fd.write('Name: PETSc\n')
200      fd.write('Description: Library to solve ODEs and algebraic equations\n')
201      fd.write('Version: %s\n' % self.petscdir.version)
202      fd.write('Cflags: ' + ' '.join([self.setCompilers.CPPFLAGS] + cflags_inc) + '\n')
203      fd.write('Libs: '+self.libraries.toStringNoDupes(['-L${libdir}', self.petsclib], with_rpath=False)+'\n')
204      # Remove RPATH flags from library list.  User can add them using
205      # pkg-config --variable=ldflag_rpath and pkg-config --libs-only-L
206      fd.write('Libs.private: '+self.libraries.toStringNoDupes([f for f in self.packagelibs+self.complibs if not f.startswith(self.setCompilers.CSharedLinkerFlag)], with_rpath=False)+'\n')
207    return
208
209  def DumpModule(self):
210    ''' Create a module file '''
211    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')):
212      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules'))
213    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')):
214      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc'))
215    if self.framework.argDB['prefix']:
216      installdir  = self.installdir.dir
217      installarch = ''
218      installpath = os.path.join(installdir,'bin')
219    else:
220      installdir  = self.petscdir.dir
221      installarch = self.arch.arch
222      installpath = os.path.join(installdir,installarch,'bin')+':'+os.path.join(installdir,'bin')
223    fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc',self.petscdir.version),'w')
224    fd.write('''\
225#%%Module
226
227proc ModulesHelp { } {
228    puts stderr "This module sets the path and environment variables for petsc-%s"
229    puts stderr "     see https://petsc.org/ for more information      "
230    puts stderr ""
231}
232module-whatis "PETSc - Portable, Extensible Toolkit for Scientific Computation"
233
234set petsc_dir   "%s"
235set petsc_arch  "%s"
236
237setenv PETSC_ARCH "$petsc_arch"
238setenv PETSC_DIR "$petsc_dir"
239prepend-path PATH "%s"
240''' % (self.petscdir.version, installdir, installarch, installpath))
241    fd.close()
242    return
243
244  def Dump(self):
245    ''' Actually put the values into the configuration files '''
246    # eventually everything between -- should be gone
247    if self.mpi.usingMPIUni:
248      #
249      # Remove any MPI/MPICH include files that may have been put here by previous runs of ./configure
250      self.executeShellCommand('rm -rf  '+os.path.join(self.petscdir.dir,self.arch.arch,'include','mpi*')+' '+os.path.join(self.petscdir.dir,self.arch.arch,'include','opa*'), log = self.log)
251
252    self.logPrintDivider()
253    # Test for compiler-specific macros that need to be defined.
254    if self.setCompilers.isCrayVector('CC', self.log):
255      self.addDefine('HAVE_CRAY_VECTOR','1')
256
257    if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'):
258      self.addDefine('USE_SOCKET_VIEWER','1')
259      if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'):
260        self.addDefine('HAVE_SO_REUSEADDR','1')
261
262    self.logPrintDivider()
263    self.setCompilers.pushLanguage('C')
264    compiler = self.setCompilers.getCompiler()
265    if [s for s in ['mpicc','mpiicc'] if os.path.basename(compiler).find(s)>=0]:
266      try:
267        output   = self.executeShellCommand(compiler + ' -show', log = self.log)[0]
268        compiler = output.split(' ')[0]
269        self.addDefine('MPICC_SHOW','"'+output.strip().replace('\n','\\\\n').replace('"','')+'"')
270      except:
271        self.addDefine('MPICC_SHOW','"Unavailable"')
272    else:
273      self.addDefine('MPICC_SHOW','"Unavailable"')
274    self.setCompilers.popLanguage()
275#-----------------------------------------------------------------------------------------------------
276
277    # Sometimes we need C compiler, even if built with C++
278    self.setCompilers.pushLanguage('C')
279    # do not use getCompilerFlags() because that automatically includes the CPPFLAGS so one ends up with duplication flags in makefile usage
280    self.addMakeMacro('CC_FLAGS',self.setCompilers.CFLAGS)
281    self.setCompilers.popLanguage()
282
283    # And sometimes we need a C++ compiler even when PETSc is built with C
284    if hasattr(self.compilers, 'CXX'):
285      self.setCompilers.pushLanguage('Cxx')
286      self.addDefine('HAVE_CXX','1')
287      self.addMakeMacro('CXXPP_FLAGS',self.setCompilers.CXXPPFLAGS)
288      # do not use getCompilerFlags() because that automatically includes the CXXPPFLAGS so one ends up with duplication flags in makefile usage
289      self.addMakeMacro('CXX_FLAGS',self.setCompilers.CXXFLAGS+' '+self.setCompilers.CXX_CXXFLAGS)
290      cxx_linker = self.setCompilers.getLinker()
291      self.addMakeMacro('CXX_LINKER',cxx_linker)
292      self.addMakeMacro('CXX_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
293      self.setCompilers.popLanguage()
294
295    # C preprocessor values
296    self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS)
297
298    # compiler values
299    self.setCompilers.pushLanguage(self.languages.clanguage)
300    self.addMakeMacro('PCC',self.setCompilers.getCompiler())
301    # do not use getCompilerFlags() because that automatically includes the preprocessor flags so one ends up with duplication flags in makefile usage
302    if self.languages.clanguage == 'C':
303      self.addMakeMacro('PCC_FLAGS','$(CC_FLAGS)')
304    else:
305      self.addMakeMacro('PCC_FLAGS','$(CXX_FLAGS)')
306    self.setCompilers.popLanguage()
307    # .o or .obj
308    self.addMakeMacro('CC_SUFFIX','o')
309
310    # executable linker values
311    self.setCompilers.pushLanguage(self.languages.clanguage)
312    pcc_linker = self.setCompilers.getLinker()
313    self.addMakeMacro('PCC_LINKER',pcc_linker)
314    self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
315    self.setCompilers.popLanguage()
316    # '' for Unix, .exe for Windows
317    self.addMakeMacro('CC_LINKER_SUFFIX','')
318
319    if hasattr(self.compilers, 'FC'):
320      if self.framework.argDB['with-fortran-bindings']:
321        if not self.fortran.fortranIsF90:
322          raise RuntimeError('Error! Fortran compiler "'+self.compilers.FC+'" does not support F90! PETSc fortran bindings require a F90 compiler')
323        self.addDefine('HAVE_FORTRAN','1')
324      self.setCompilers.pushLanguage('FC')
325      # need FPPFLAGS in config/setCompilers
326      self.addMakeMacro('FPP_FLAGS',self.setCompilers.FPPFLAGS)
327
328      # compiler values
329      self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags())
330      self.setCompilers.popLanguage()
331      # .o or .obj
332      self.addMakeMacro('FC_SUFFIX','o')
333
334      # executable linker values
335      self.setCompilers.pushLanguage('FC')
336      self.addMakeMacro('FC_LINKER',self.setCompilers.getLinker())
337      self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
338      # apple requires this shared library linker flag on SOME versions of the os
339      if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1:
340        self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ')
341      self.setCompilers.popLanguage()
342
343      # F90 Modules
344      if self.setCompilers.fortranModuleIncludeFlag:
345        self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag)
346      else: # for non-f90 compilers like g77
347        self.addMakeMacro('FC_MODULE_FLAG', '-I')
348      if self.setCompilers.fortranModuleIncludeFlag:
349        self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag)
350    else:
351      self.addMakeMacro('FC','')
352
353    if hasattr(self.compilers, 'CUDAC'):
354      self.setCompilers.pushLanguage('CUDA')
355      self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags())
356      self.addMakeMacro('CUDAPP_FLAGS',self.setCompilers.CUDAPPFLAGS)
357      self.setCompilers.popLanguage()
358
359    if hasattr(self.compilers, 'HIPC'):
360      self.setCompilers.pushLanguage('HIP')
361      self.addMakeMacro('HIPC_FLAGS',self.setCompilers.getCompilerFlags())
362      self.addMakeMacro('HIPPP_FLAGS',self.setCompilers.HIPPPFLAGS)
363      self.setCompilers.popLanguage()
364
365    if hasattr(self.compilers, 'SYCLC'):
366      self.setCompilers.pushLanguage('SYCL')
367      self.addMakeMacro('SYCLC_FLAGS',self.setCompilers.getCompilerFlags())
368      self.addMakeMacro('SYCLPP_FLAGS',self.setCompilers.SYCLPPFLAGS)
369      self.setCompilers.popLanguage()
370
371    # shared library linker values
372    self.setCompilers.pushLanguage(self.languages.clanguage)
373    # need to fix BuildSystem to collect these separately
374    self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker())
375    self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}')
376    self.setCompilers.popLanguage()
377    # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture
378    # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX
379    if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX:
380      self.addMakeMacro('SL_LINKER_SUFFIX', '')
381      self.addDefine('SLSUFFIX','""')
382    else:
383      self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt)
384      self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"')
385
386    self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}')
387
388#-----------------------------------------------------------------------------------------------------
389
390    # CONLY or CPP. We should change the PETSc makefiles to do this better
391    if self.languages.clanguage == 'C': lang = 'CONLY'
392    else: lang = 'CXXONLY'
393    self.addMakeMacro('PETSC_LANGUAGE',lang)
394
395    # real or complex
396    self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype)
397    # double or float
398    self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision)
399
400    if self.framework.argDB['with-batch']:
401      self.addMakeMacro('PETSC_WITH_BATCH','1')
402
403#-----------------------------------------------------------------------------------------------------
404    # print include and lib for makefiles
405    self.logPrintDivider()
406    self.framework.packages.reverse()
407    petscincludes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')]
408    petscincludes_install = [os.path.join(self.installdir.dir, 'include')] if self.framework.argDB['prefix'] else petscincludes
409    includes = []
410    self.packagelibs = []
411    for i in self.framework.packages:
412      if not i.required:
413        if i.devicePackage:
414          self.addDefine('HAVE_DEVICE',1)
415        self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1)  # ONLY list package if it is used directly by PETSc (and not only by another package)
416      if not isinstance(i.lib, list):
417        i.lib = [i.lib]
418      if i.linkedbypetsc: self.packagelibs.extend(i.lib)
419      self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib))
420      if hasattr(i,'include'):
421        if not isinstance(i.include,list):
422          i.include = [i.include]
423        includes.extend(i.include)
424        self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include))
425    if self.framework.argDB['with-single-library']:
426      self.petsclib = '-lpetsc'
427    else:
428      self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys'
429    self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split()
430    self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs)
431    self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs)
432
433    self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC)
434    allincludes = petscincludes + includes
435    allincludes_install = petscincludes_install + includes
436    self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(allincludes)
437    self.PETSC_CC_INCLUDES_INSTALL = self.headers.toStringNoDupes(allincludes_install)
438    self.addMakeMacro('PETSC_CC_INCLUDES',self.PETSC_CC_INCLUDES)
439    self.addMakeMacro('PETSC_CC_INCLUDES_INSTALL', self.PETSC_CC_INCLUDES_INSTALL)
440    if hasattr(self.compilers, 'FC'):
441      def modinc(includes):
442        return includes if self.fortran.fortranIsF90 else []
443      self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes)))
444      self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install)))
445
446    self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"')
447
448    if self.framework.argDB['with-single-library']:
449      # overrides the values set in conf/variables
450      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}')
451      self.addMakeMacro('SHLIBS','libpetsc')
452      self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc')
453      self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc')
454      self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc')
455      self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc')
456      self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB)
457      self.addDefine('USE_SINGLE_LIBRARY', '1')
458      if self.sharedlibraries.useShared:
459        self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
460        self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
461        self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
462        self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
463        self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
464        self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
465        self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
466        self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
467        self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
468        self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
469        self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}')
470      else:
471        self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}')
472        self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
473        self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}')
474        self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}')
475        self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}')
476        self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}')
477        self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}')
478        self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}')
479        self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
480        self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
481        self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}')
482
483    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')):
484      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib'))
485
486# add a makefile endtry for display
487    if self.framework.argDB['with-display']:
488      self.addMakeMacro('DISPLAY',self.framework.argDB['with-display'])
489
490    # add a makefile entry for configure options
491    self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"'))
492
493    if self.framework.argDB['with-tau-perfstubs']:
494      self.addDefine('HAVE_TAU_PERFSTUBS',1)
495    return
496
497  def dumpConfigInfo(self):
498    import time
499    fd = open(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w')
500    fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"').replace('\\ ','\\\\ ')+'";\n')
501    fd.close()
502    return
503
504  def dumpMachineInfo(self):
505    import platform
506    import datetime
507    import time
508    import script
509    def escape(s):
510      return s.replace('"',r'\"').replace(r'\ ',r'\\ ') # novermin
511    fd = open(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w')
512    fd.write('static const char *petscmachineinfo = \"\\n\"\n')
513    fd.write('\"-----------------------------------------\\n\"\n')
514    buildhost = platform.node()
515    if os.environ.get('SOURCE_DATE_EPOCH'):
516      buildhost = "reproducible"
517    buildtime = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time())))
518    fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (buildtime, buildhost))
519    fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform()))
520    fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir)))
521    fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch)))
522    fd.write('\"-----------------------------------------\\n\";\n')
523    fd.write('static const char *petsccompilerinfo = \"\\n\"\n')
524    self.setCompilers.pushLanguage(self.languages.clanguage)
525    fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags())))
526    self.setCompilers.popLanguage()
527    if hasattr(self.compilers, 'FC'):
528      self.setCompilers.pushLanguage('FC')
529      fd.write('\"Using Fortran compiler: %s %s  %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS)))
530      self.setCompilers.popLanguage()
531    fd.write('\"-----------------------------------------\\n\";\n')
532    fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n')
533    fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES_INSTALL.replace('${PETSC_DIR}', self.installdir.petscDir))))
534    fd.write('\"-----------------------------------------\\n\";\n')
535    fd.write('static const char *petsclinkerinfo = \"\\n\"\n')
536    self.setCompilers.pushLanguage(self.languages.clanguage)
537    fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker())))
538    self.setCompilers.popLanguage()
539    if hasattr(self.compilers, 'FC'):
540      self.setCompilers.pushLanguage('FC')
541      fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker())))
542      self.setCompilers.popLanguage()
543    fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (escape(self.setCompilers.CSharedLinkerFlag), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(self.petsclib), escape(self.PETSC_EXTERNAL_LIB_BASIC)))
544    fd.write('\"-----------------------------------------\\n\";\n')
545    fd.close()
546    return
547
548  def configurePrefetch(self):
549    '''Sees if there are any prefetch functions supported'''
550    if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']:
551      self.addDefine('Prefetch(a,b,c)', ' ')
552      return
553    self.pushLanguage(self.languages.clanguage)
554    if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'):
555      # The Intel Intrinsics manual [1] specifies the prototype
556      #
557      #   void _mm_prefetch(char const *a, int sel);
558      #
559      # but other vendors seem to insist on using subtly different
560      # prototypes, including void* for the pointer, and an enum for
561      # sel.  These are both reasonable changes, but negatively impact
562      # portability.
563      #
564      # [1] https://software.intel.com/file/6373
565      self.addDefine('HAVE_XMMINTRIN_H', 1)
566      self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))')
567      self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA')
568      self.addDefine('PREFETCH_HINT_T0',  '_MM_HINT_T0')
569      self.addDefine('PREFETCH_HINT_T1',  '_MM_HINT_T1')
570      self.addDefine('PREFETCH_HINT_T2',  '_MM_HINT_T2')
571    elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'):
572      self.addDefine('HAVE_XMMINTRIN_H', 1)
573      self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))')
574      self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA')
575      self.addDefine('PREFETCH_HINT_T0',  '_MM_HINT_T0')
576      self.addDefine('PREFETCH_HINT_T1',  '_MM_HINT_T1')
577      self.addDefine('PREFETCH_HINT_T2',  '_MM_HINT_T2')
578    elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'):
579      # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality)
580      #
581      #   The value of rw is a compile-time constant one or zero; one
582      #   means that the prefetch is preparing for a write to the memory
583      #   address and zero, the default, means that the prefetch is
584      #   preparing for a read. The value locality must be a compile-time
585      #   constant integer between zero and three. A value of zero means
586      #   that the data has no temporal locality, so it need not be left
587      #   in the cache after the access. A value of three means that the
588      #   data has a high degree of temporal locality and should be left
589      #   in all levels of cache possible. Values of one and two mean,
590      #   respectively, a low or moderate degree of temporal locality.
591      #
592      # Here we adopt Intel's x86/x86-64 naming scheme for the locality
593      # hints.  Using macros for these values in necessary since some
594      # compilers require an enum.
595      self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))')
596      self.addDefine('PREFETCH_HINT_NTA', '0')
597      self.addDefine('PREFETCH_HINT_T0',  '3')
598      self.addDefine('PREFETCH_HINT_T1',  '2')
599      self.addDefine('PREFETCH_HINT_T2',  '1')
600    else:
601      self.addDefine('Prefetch(a,b,c)', ' ')
602    self.popLanguage()
603
604  def delGenFiles(self):
605    '''Delete generated files'''
606    delfile = os.path.join(self.arch.arch,'lib','petsc','conf','files')
607    try:
608      os.unlink(delfile)
609    except: pass
610
611  def configureAtoll(self):
612    '''Checks if atoll exists'''
613    if self.checkLink('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25");\n(void)v') or self.checkLink ('#include <stdlib.h>','long v = atoll("25");\n(void)v'):
614       self.addDefine('HAVE_ATOLL', '1')
615
616  def configureUnused(self):
617    '''Sees if __attribute((unused)) is supported'''
618    if self.framework.argDB['with-ios']:
619      self.addDefine('UNUSED', ' ')
620      return
621    self.pushLanguage(self.languages.clanguage)
622    if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\n(void)j;\ntypedef void* atype;\n__attribute((unused))  atype a'):
623      self.addDefine('UNUSED', '__attribute((unused))')
624    else:
625      self.addDefine('UNUSED', ' ')
626    self.popLanguage()
627
628  def configureIsatty(self):
629    '''Check if the Unix C function isatty() works correctly
630       Actually just assumes it does not work correctly on batch systems'''
631    if not self.framework.argDB['with-batch']:
632      self.addDefine('USE_ISATTY',1)
633
634  def configureDeprecated(self):
635    '''Check if __attribute((deprecated)) is supported'''
636    def checkDeprecated(macro_base, src, is_intel):
637      '''
638      run through the various attribute deprecated combinations and define MACRO_BAS(why) to the result
639      it if it compiles.
640
641      If none of the combos work, defines MACRO_BASE(why) as empty
642      '''
643      full_macro_name = macro_base + '(why)'
644      for prefix in ('__attribute__', '__attribute','__declspec'):
645        if prefix == '__declspec':
646          # declspec does not have an extra set of brackets around the arguments
647          attr_bodies = ('deprecated(why)', 'deprecated')
648        else:
649          attr_bodies = ('(deprecated(why))', '(deprecated)')
650
651        for attr_body in attr_bodies:
652          attr_def = '{}({})'.format(prefix, attr_body)
653          test_src = '\n'.join((
654            '#define {} {}'.format(full_macro_name, attr_def),
655            src.format(macro_base + '("asdasdadsasd")')
656          ))
657          if self.checkCompile(test_src, ''):
658            self.logPrint('configureDeprecated: \'{}\' appears to work'.format(attr_def))
659            if is_intel and '(why)' in attr_body:
660              self.logPrint('configureDeprecated: Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc executable in the environment to determine the language compatibility that it should attempt to emulate. Some important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g. 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc found in the default user environment is older and does not support the argument.\n'.format(attr_def))
661              self.logPrint('*** WE WILL THEREFORE REJECT \'{}\' AND CONTINUE TESTING ***'.format(attr_def))
662              continue
663            self.addDefine(full_macro_name, attr_def)
664            return
665
666      self.addDefine(full_macro_name, ' ')
667      return
668
669    lang = self.languages.clanguage
670    with self.Language(lang):
671      is_intel = self.setCompilers.isIntel(self.getCompiler(lang=lang), self.log)
672      checkDeprecated('DEPRECATED_FUNCTION', '{} int myfunc(void) {{ return 1; }}', is_intel)
673      checkDeprecated('DEPRECATED_TYPEDEF', 'typedef int my_int {};', is_intel)
674      checkDeprecated('DEPRECATED_ENUM', 'enum E {{ oldval {}, newval }};', is_intel)
675      # I was unable to make a CPP macro that takes the old and new values as separate
676      # arguments and builds the message needed by _Pragma hence the deprecation message is
677      # handled as it is
678      if self.checkCompile('#define TEST _Pragma("GCC warning \"Testing _Pragma\"") value'):
679        self.addDefine('DEPRECATED_MACRO(why)', '_Pragma(why)')
680      else:
681        self.addDefine('DEPRECATED_MACRO(why)', ' ')
682
683  def configureAlign(self):
684    '''Check if __attribute(aligned) is supported'''
685    code = '''\
686struct mystruct {int myint;} __attribute((aligned(16)));
687char assert_aligned[(sizeof(struct mystruct)==16)*2-1];
688'''
689    self.pushLanguage(self.languages.clanguage)
690    if self.checkCompile(code):
691      self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned(size)))')
692      self.addDefine('HAVE_ATTRIBUTEALIGNED', 1)
693    else:
694      self.framework.logPrint('Incorrect attribute(aligned)')
695      self.addDefine('ATTRIBUTEALIGNED(size)', ' ')
696    self.popLanguage()
697    return
698
699  def configureExpect(self):
700    '''Sees if the __builtin_expect directive is supported'''
701    self.pushLanguage(self.languages.clanguage)
702    if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'):
703      self.addDefine('HAVE_BUILTIN_EXPECT', 1)
704    self.popLanguage()
705
706  def configureFunctionName(self):
707    '''Sees if the compiler supports __func__ or a variant.'''
708    def getFunctionName(lang):
709      name = '"unknown"'
710      self.pushLanguage(lang)
711      for fname in ['__func__','__FUNCTION__','__extension__ __func__']:
712        code = "if ("+fname+"[0] != 'm') return 1;"
713        if self.checkCompile('',code) and self.checkLink('',code):
714          name = fname
715          break
716      self.popLanguage()
717      return name
718    langs = []
719
720    self.addDefine('FUNCTION_NAME_C', getFunctionName('C'))
721    if hasattr(self.compilers, 'CXX'):
722      self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx'))
723
724  def configureIntptrt(self):
725    '''Determine what to use for uintptr_t and intptr_t'''
726    def staticAssertSizeMatchesVoidStar(inc,typename):
727      # The declaration is an error if either array size is negative.
728      # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case
729      return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n'
730                                     + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename))
731
732    def generate_uintptr_guesses():
733      for suff in ('max', '64', '32', '16'):
734        yield '#include <stdint.h>', 'uint{}_t'.format(suff), 'PRIx{}'.format(suff.upper())
735      yield '#include <stdlib.h>\n#include <string.h>', 'size_t', 'zx'
736      yield '', 'unsigned long long', 'llx'
737      yield '', 'unsigned long', 'lx'
738      yield '', 'unsigned', 'x'
739
740    def generate_intptr_guesses():
741      for suff in ('max', '64', '32', '16'):
742        yield '#include <stdint.h>', 'int{}_t'.format(suff), 'PRIx{}'.format(suff.upper())
743      yield '', 'long long', 'llx'
744      yield '', 'long', 'lx'
745      yield '', 'int', 'x'
746
747    def check(default_typename, generator):
748      macro_name = default_typename.upper()
749      with self.Language(self.languages.clanguage):
750        if self.checkCompile(
751            '#include <stdint.h>',
752            'int x; {type_name} i = ({type_name})&x; (void)i'.format(type_name=default_typename)
753        ):
754          typename     = default_typename
755          print_format = 'PRIxPTR'
756        else:
757          for include, typename, print_format in generator():
758            if staticAssertSizeMatchesVoidStar(include, typename):
759              break
760          else:
761            raise RuntimeError('Could not find any {} type matching void*'.format(macro_name))
762      self.addDefine(macro_name         , typename)
763      self.addDefine(macro_name + '_FMT', '\"#\" ' + print_format)
764      return
765
766    check('uintptr_t', generate_uintptr_guesses)
767    check('intptr_t', generate_intptr_guesses)
768    return
769
770  def configureRTLDDefault(self):
771    '''Check for dynamic library feature'''
772    if self.checkCompile('#include <dlfcn.h>\n void *ptr =  RTLD_DEFAULT;'):
773      self.addDefine('HAVE_RTLD_DEFAULT','1')
774    return
775
776  def configureSolaris(self):
777    '''Solaris specific stuff'''
778    if os.path.isdir(os.path.join('/usr','ucblib')):
779      try:
780        flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag')
781      except AttributeError:
782        flag = None
783      if flag is None:
784        self.compilers.LIBS += ' -L/usr/ucblib'
785      else:
786        self.compilers.LIBS += ' '+flag+'/usr/ucblib'
787    return
788
789  def configureDarwin(self):
790    '''Log brew configuration for Apple systems'''
791    try:
792      self.executeShellCommand(['brew', 'config'], log = self.log)
793      self.executeShellCommand(['brew', 'info', 'gcc'], log = self.log)
794    except:
795      pass
796    return
797
798  def configureLinux(self):
799    '''Linux specific stuff'''
800    # TODO: Test for this by mallocing an odd number of floats and checking the address
801    self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1)
802    return
803
804  def configureWin32(self):
805    '''Win32 non-cygwin specific stuff'''
806    kernel32=0
807    if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'):
808      self.addDefine('HAVE_WINDOWS_H',1)
809      self.addDefine('HAVE_GETCOMPUTERNAME',1)
810      kernel32=1
811    elif self.libraries.add('kernel32','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'):
812      self.addDefine('HAVE_WINDOWS_H',1)
813      self.addDefine('HAVE_GETCOMPUTERNAME',1)
814      kernel32=1
815    if kernel32:
816      if self.framework.argDB['with-windows-graphics']:
817        self.addDefine('USE_WINDOWS_GRAPHICS',1)
818      if self.checkLink('#include <windows.h>','LoadLibrary(0)'):
819        self.addDefine('HAVE_LOADLIBRARY',1)
820      if self.checkLink('#include <windows.h>','GetProcAddress(0,0)'):
821        self.addDefine('HAVE_GETPROCADDRESS',1)
822      if self.checkLink('#include <windows.h>','FreeLibrary(0)'):
823        self.addDefine('HAVE_FREELIBRARY',1)
824      if self.checkLink('#include <windows.h>','GetLastError()'):
825        self.addDefine('HAVE_GETLASTERROR',1)
826      if self.checkLink('#include <windows.h>','SetLastError(0)'):
827        self.addDefine('HAVE_SETLASTERROR',1)
828      if self.checkLink('#include <windows.h>\n','QueryPerformanceCounter(0);\n'):
829        self.addDefine('USE_MICROSOFT_TIME',1)
830    if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'):
831      self.addDefine('HAVE_GET_USER_NAME',1)
832    elif self.libraries.add('advapi32','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'):
833      self.addDefine('HAVE_GET_USER_NAME',1)
834
835    if not self.libraries.add('User32.lib','GetDC',prototype='#include <windows.h>',call='GetDC(0);'):
836      self.libraries.add('user32','GetDC',prototype='#include <windows.h>',call='GetDC(0);')
837    if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);'):
838      self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);')
839
840    self.types.check('int32_t', 'int')
841    if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n(void)u'):
842      self.addTypedef('int', 'uid_t')
843      self.addTypedef('int', 'gid_t')
844    if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n(void)a'):
845      self.framework.addDefine('R_OK', '04')
846      self.framework.addDefine('W_OK', '02')
847      self.framework.addDefine('X_OK', '01')
848    if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'):
849      self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)')
850      self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)')
851    if self.checkCompile('#include <windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'):
852      self.addDefine('HAVE_LARGE_INTEGER_U',1)
853
854    # Windows requires a Binary file creation flag when creating/opening binary files.  Is a better test in order?
855    if self.checkCompile('#include <windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'):
856      self.addDefine('HAVE_O_BINARY',1)
857
858    if self.compilers.CC.find('win32fe') >= 0:
859      self.addDefine('HAVE_WINDOWS_COMPILERS',1)
860      self.addDefine('DIR_SEPARATOR','\'\\\\\'')
861      self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'')
862      self.addDefine('CANNOT_START_DEBUGGER',1)
863      (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log)
864      self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"')
865      (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log)
866      self.addMakeMacro('wPETSC_DIR',petscdir)
867      if self.dataFilesPath.datafilespath:
868        (datafilespath,error,status) = self.executeShellCommand('cygpath -m '+self.dataFilesPath.datafilespath, log = self.log)
869        self.addMakeMacro('DATAFILESPATH',datafilespath)
870
871    else:
872      self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'')
873      self.addDefine('DIR_SEPARATOR','\'/\'')
874      self.addDefine('DIR','"'+self.installdir.petscDir+'"')
875      self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir)
876      if self.dataFilesPath.datafilespath:
877        self.addMakeMacro('DATAFILESPATH',self.dataFilesPath.datafilespath)
878    self.addDefine('ARCH','"'+self.installdir.petscArch+'"')
879    return
880
881  def configureCoverage(self, lang, extra_coverage_flags=None, extra_debug_flags=None):
882    """
883    Check that a compiler accepts code-coverage flags. If the compiler does accept code-coverage flags
884    try to set debugging flags equivalent to -Og.
885
886    Arguments:
887    - lang: the language to check the coverage flag for
888    - extra_coverage_flags: a list of extra flags to use when checking the coverage flags
889    - extra_debug_flags: a list of extra flags to try when setting debug flags
890
891    On success:
892    - defines PETSC_USE_COVERAGE to 1
893    """
894    def log_print(msg, *args, **kwargs):
895      self.logPrint('checkCoverage: '+str(msg), *args, **kwargs)
896      return
897
898    def quoted(string):
899      return string.join(("'", "'"))
900
901    def make_flag_list(default, extra):
902      ret = [default]
903      if extra is not None:
904        assert isinstance(extra, list)
905        ret.extend(extra)
906      return ret
907
908    log_print('Checking coverage flag for language {}'.format(lang))
909    if not self.argDB['with-coverage']:
910      log_print('coverage was disabled from command line or default')
911      return
912
913    compiler  = self.getCompiler(lang=lang)
914    is_gnuish = self.setCompilers.isGNU(compiler, self.log) or self.setCompilers.isClang(compiler, self.log)
915
916    # if not gnuish and we don't have a set of extra flags, bail
917    if not is_gnuish and extra_coverage_flags is None:
918      log_print('Don\'t know how to add coverage for compiler {}. Only know how to add coverage for gnu-like compilers (either gcc or clang). Skipping it!'.format(quoted(compiler)))
919      return
920
921    coverage_flags = make_flag_list('--coverage', extra_coverage_flags)
922    log_print('Checking set of coverage flags: {}'.format(coverage_flags))
923
924    found = 0
925    with self.Language(lang):
926      with self.setCompilers.Language(lang):
927        for flag in coverage_flags:
928          if self.setCompilers.checkCompilerFlag(flag) and self.checkLink():
929            # compilerOnly = False, the linker also needs to see the coverage flag
930            self.setCompilers.insertCompilerFlag(flag, False)
931            found = 1
932            break
933          log_print(
934            'Compiler {} did not accept coverage flag {}'.format(quoted(compiler), quoted(flag))
935          )
936
937    if not found:
938      log_print('Compiler {} did not accept ANY coverage flags: {}, bailing!'.format(quoted(compiler), coverage_flags))
939      return
940
941    if not self.functions.haveFunction('__gcov_dump'):
942      self.functions.checkClassify(['__gcov_dump'])
943
944    # now check if we can override the optimization level. It is only kosher to do so if
945    # the user did not explicitly set the optimization flags (via CFLAGS, CXXFLAGS,
946    # CXXOPTFLAGS, etc). If they have done so, we sternly warn them about their lapse in
947    # judgement
948    with self.Language(lang):
949      compiler_flags = self.getCompilerFlags()
950
951    user_set          = 0
952    allowed_opt_flags = re.compile(r'|'.join((r'-O[01g]', r'-g[1-9]*')))
953    for flagsname in [self.getCompilerFlagsName(lang), self.compilerFlags.getOptionalFlagsName(lang)]:
954      if flagsname in self.argDB:
955        opt_flags = [
956          f for f in self.compilerFlags.findOptFlags(compiler_flags) if not allowed_opt_flags.match(f)
957        ]
958        if opt_flags:
959          self.logPrintWarning('Coverage requested, but optimization flag(s) {} found in {}. Coverage collection will work, but may be less accurate. Suggest removing the flag and/or using -Og (or equivalent) instead'.format(', '.join(map(quoted, opt_flags)), quoted(flagsname)))
960          user_set = 1
961          break
962
963    if not user_set:
964      debug_flags = make_flag_list('-Og', extra_debug_flags)
965      with self.setCompilers.Language(lang):
966        for flag in debug_flags:
967          try:
968            self.setCompilers.addCompilerFlag(flag)
969          except RuntimeError:
970            continue
971          break
972
973    self.addDefine('USE_COVERAGE', 1)
974    return
975
976  def configureCoverageExecutable(self):
977    """
978    Check that a code-coverage collecting tool exists and is on PATH.
979
980    On success:
981    - Adds PETSC_COVERAGE_EXEC make macro containing the full path to the coverage tool executable.
982
983    Raises RuntimeError if:
984    - User explicitly requests auto-detection of the coverage tool from command line, and this
985      routine fails to guess the suitable tool name.
986    - The routine fails to find the tool, and --with-coverage is true
987    """
988    def log_print(msg, *args, **kwargs):
989      self.logPrint('checkCoverage: '+str(msg), *args, **kwargs)
990      return
991
992    def quoted(string):
993      return string.join(("'", "'"))
994
995    required         = bool(self.argDB['with-coverage'])
996    arg_opt          = self.argDB['with-coverage-exec']
997    use_default_path = True
998    search_path      = ''
999
1000    log_print('{} to find an executable'.format('REQUIRED' if required else 'NOT required'))
1001    if arg_opt in {'auto', 'default-auto', '1'}:
1002      # detect it based on the C language compiler, hopefully this does not clash!
1003      compiler = self.getCompiler(lang=self.setCompilers.languages.clanguage)
1004      log_print('User did not explicitly set coverage exec (got {}), trying to auto-detect based on compiler {}'.format(quoted(arg_opt), quoted(compiler)))
1005      if self.setCompilers.isGNU(compiler, self.log):
1006        exec_names = ['gcov']
1007      elif self.setCompilers.isClang(compiler, self.log):
1008        exec_names = ['llvm-cov']
1009        if self.setCompilers.isDarwin(self.log):
1010          # macOS masquerades llvm-cov as just 'gcov', so we add this to the list in case
1011          # bare llvm-cov does not work
1012          exec_names.append('gcov')
1013      elif arg_opt == 'default-auto' and not required:
1014        # default-auto implies the user did not set it via command line!
1015        log_print('Could not auto-detect coverage tool for {}, not a gnuish compiler. Bailing since user did not explicitly set exec on the commandline'.format(quoted(compiler)))
1016        return
1017      else:
1018        # implies 'auto' explicitly set by user, or we were required to find
1019        # something. either way we should error
1020        raise RuntimeError('Could not auto-detect coverage tool for {}, please set coverage tool name explicitly'.format(quoted(compiler)))
1021    else:
1022      log_print('User explicitly set coverage exec as {}'.format(quoted(arg_opt)))
1023      par_dir = os.path.dirname(arg_opt)
1024      if os.path.exists(par_dir):
1025        # arg_opt is path-like, we should only search the provided directory when we go
1026        # looking for the tool
1027        use_default_path = False
1028        search_path      = par_dir
1029      exec_names = [arg_opt]
1030
1031    make_macro_name = 'PETSC_COVERAGE_EXEC'
1032    log_print('Checking for coverage tool(s):\n{}'.format('\n'.join('- '+t for t in exec_names)))
1033    found_exec = self.getExecutables(
1034      exec_names,
1035      path=search_path, getFullPath=True, useDefaultPath=use_default_path, resultName=make_macro_name
1036    )
1037
1038    if found_exec is None:
1039      # didn't find the coverage tool
1040      if required:
1041        raise RuntimeError('Coverage tool(s) {} could not be found. Please provide explicit path to coverage tool'.format(exec_names))
1042      return
1043
1044    found_exec_name = os.path.basename(found_exec)
1045    if 'llvm-cov' in found_exec_name and 'gcov' not in found_exec_name:
1046      # llvm-cov needs to be called as 'llvm-cov gcov' to work
1047      self.addMakeMacro(make_macro_name, found_exec + ' gcov')
1048    return
1049
1050  def configureStrictPetscErrorCode(self):
1051    """
1052    Enables or disables strict PetscErrorCode checking.
1053
1054    If --with-strict-petscerrorcode = 1:
1055    - defines PETSC_USE_STRICT_PETSCERRORCODE to 1
1056
1057    Else:
1058    - deletes any prior PETSC_USE_STRICT_PETSCERRORCODE definitions (if they exist)
1059    """
1060    define_name = 'USE_STRICT_PETSCERRORCODE'
1061    if self.argDB['with-strict-petscerrorcode']:
1062      self.addDefine(define_name, 1)
1063    else:
1064      # in case it was somehow added previously
1065      self.delDefine(define_name)
1066    return
1067
1068#-----------------------------------------------------------------------------------------------------
1069  def configureCygwinBrokenPipe(self):
1070    '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make
1071    http://cygwin.com/ml/cygwin/2013-05/msg00340.html '''
1072    if config.setCompilers.Configure.isCygwin(self.log):
1073      import platform
1074      import re
1075      r=re.compile("([0-9]+).([0-9]+).([0-9]+)")
1076      m=r.match(platform.release())
1077      major=int(m.group(1))
1078      minor=int(m.group(2))
1079      subminor=int(m.group(3))
1080      if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)):
1081        self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1')
1082    return
1083
1084#-----------------------------------------------------------------------------------------------------
1085  def configureDefaultArch(self):
1086    conffile = os.path.join('lib','petsc','conf', 'petscvariables')
1087    if self.framework.argDB['with-default-arch']:
1088      fd = open(conffile, 'w')
1089      fd.write('PETSC_ARCH='+self.arch.arch+'\n')
1090      fd.write('PETSC_DIR='+self.petscdir.dir+'\n')
1091      fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n')
1092      fd.close()
1093      self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile)
1094    elif os.path.isfile(conffile):
1095      try:
1096        os.unlink(conffile)
1097      except:
1098        raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?')
1099    return
1100
1101#-----------------------------------------------------------------------------------------------------
1102  def configureScript(self):
1103    '''Output a script in the conf directory which will reproduce the configuration'''
1104    import nargs
1105    import sys
1106    scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py')
1107    args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs])
1108    if 'with-clean' in args:
1109      del args['with-clean']
1110    if 'force' in args:
1111      del args['force']
1112    if 'configModules' in args:
1113      if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure':
1114        del args['configModules']
1115    if 'optionsModule' in args:
1116      if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions':
1117        del args['optionsModule']
1118    if not 'PETSC_ARCH' in args:
1119      args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch)
1120    f = open(scriptName, 'w')
1121    f.write('#!'+sys.executable+'\n')
1122    f.write('if __name__ == \'__main__\':\n')
1123    f.write('  import sys\n')
1124    f.write('  import os\n')
1125    f.write('  sys.path.insert(0, os.path.abspath(\'config\'))\n')
1126    f.write('  import configure\n')
1127    # pretty print repr(args.values())
1128    f.write('  configure_options = [\n')
1129    for itm in sorted(args.values()):
1130      f.write('    \''+str(itm)+'\',\n')
1131    f.write('  ]\n')
1132    f.write('  configure.petsc_configure(configure_options)\n')
1133    f.close()
1134    try:
1135      os.chmod(scriptName, 0o775)
1136    except OSError as e:
1137      self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e))
1138    self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration')
1139    return
1140
1141  def configureInstall(self):
1142    '''Setup the directories for installation'''
1143    if self.framework.argDB['prefix']:
1144      self.addMakeRule('print_mesg_after_build','',
1145       ['-@echo "========================================="',
1146        '-@echo "Now to install the libraries do:"',
1147        '-@echo "%s${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"' % self.installdir.installSudo,
1148        '-@echo "========================================="'])
1149    else:
1150      self.addMakeRule('print_mesg_after_build','',
1151       ['-@echo "========================================="',
1152        '-@echo "Now to check if the libraries are working do:"',
1153        '-@echo "${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"',
1154        '-@echo "========================================="'])
1155      return
1156
1157  def postProcessPackages(self):
1158    postPackages=[]
1159    for i in self.framework.packages:
1160      if hasattr(i,'postProcess'): postPackages.append(i)
1161    if postPackages:
1162      # ctetgen needs petsc conf files. so attempt to create them early
1163      self.framework.dumpConfFiles()
1164      # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix
1165      for i in postPackages:
1166        if i.name.upper() in ['PFLOTRAN']:
1167          i.postProcess()
1168          postPackages.remove(i)
1169      for i in postPackages: i.postProcess()
1170      for i in postPackages:
1171        if i.installedpetsc:
1172          self.installed = 1
1173          break
1174    return
1175
1176  def configure(self):
1177    if 'package-prefix-hash' in self.argDB:
1178      # turn off prefix if it was only used to for installing external packages.
1179      self.framework.argDB['prefix'] = ''
1180      self.dir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch))
1181      self.installdir.dir = self.dir
1182      self.installdir.petscDir = self.petscdir.dir
1183      self.petscDir = self.petscdir.dir
1184      self.petscArch = self.arch.arch
1185      self.addMakeMacro('PREFIXDIR',self.dir)
1186      self.confDir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch))
1187
1188    if not os.path.samefile(self.petscdir.dir, os.getcwd()):
1189      raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n  Configure invoked in: '+os.path.realpath(os.getcwd()))
1190    if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir):
1191      raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!')
1192    if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1:
1193      raise RuntimeError('Your --prefix '+self.framework.argDB['prefix']+' has spaces in it; this is not allowed.\n Use a --prefix that does not have spaces in it')
1194    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)):
1195      raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!')
1196    self.framework.header          = os.path.join(self.arch.arch,'include','petscconf.h')
1197    self.framework.cHeader         = os.path.join(self.arch.arch,'include','petscfix.h')
1198    self.framework.poisonheader    = os.path.join(self.arch.arch,'include','petscconf_poison.h')
1199    self.framework.pkgheader       = os.path.join(self.arch.arch,'include','petscpkg_version.h')
1200    self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables')
1201    self.framework.makeRuleHeader  = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules')
1202    if self.libraries.math is None:
1203      raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.')
1204    if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'):
1205      raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.')
1206    self.executeTest(self.configureRTLDDefault)
1207    self.executeTest(self.configurePrefetch)
1208    self.executeTest(self.configureUnused)
1209    self.executeTest(self.configureDeprecated)
1210    self.executeTest(self.configureIsatty)
1211    self.executeTest(self.configureExpect)
1212    self.executeTest(self.configureAlign)
1213    self.executeTest(self.configureFunctionName)
1214    self.executeTest(self.configureIntptrt)
1215    self.executeTest(self.configureSolaris)
1216    self.executeTest(self.configureLinux)
1217    self.executeTest(self.configureDarwin)
1218    self.executeTest(self.configureWin32)
1219    self.executeTest(self.configureCygwinBrokenPipe)
1220    self.executeTest(self.configureDefaultArch)
1221    self.executeTest(self.configureScript)
1222    self.executeTest(self.configureInstall)
1223    self.executeTest(self.configureAtoll)
1224    for LANG in ['C', 'Cxx', 'CUDA', 'HIP', 'SYCL', 'FC']:
1225      compilerName = LANG.upper() if LANG in {'Cxx', 'FC'} else LANG+'C'
1226      if hasattr(self.setCompilers, compilerName):
1227        kwargs = {}
1228        if LANG in {'CUDA'}:
1229          # nvcc preprocesses the base file into a bunch of intermediate files, which are
1230          # then compiled by the host compiler. Why is this a problem?  Because the
1231          # generated coverage data is based on these preprocessed source files! So gcov
1232          # tries to read it later, but since its in the tmp directory it cannot. Thus we
1233          # need to keep them around (in a place we know about).
1234          nvcc_tmp_dir = os.path.join(self.petscdir.dir, self.arch.arch, 'nvcc_tmp')
1235          try:
1236            os.mkdir(nvcc_tmp_dir)
1237          except FileExistsError:
1238            pass
1239          kwargs['extra_coverage_flags'] = [
1240            '-Xcompiler --coverage -Xcompiler -fPIC --keep --keep-dir={}'.format(nvcc_tmp_dir)
1241          ]
1242          if self.kokkos.found:
1243            # yet again the kokkos nvcc_wrapper goes out of its way to be as useless as
1244            # possible. Its default arch (sm_35) is actually too low to compile kokkos,
1245            # for whatever reason this works if you dont use the --keep and --keep-dir
1246            # flags above.
1247            kwargs['extra_coverage_flags'].append('-arch=native')
1248          kwargs['extra_debug_flags'] = ['-Xcompiler -Og']
1249        self.executeTest(self.configureCoverage, args=[LANG], kargs=kwargs)
1250    self.executeTest(self.configureCoverageExecutable)
1251    self.executeTest(self.configureStrictPetscErrorCode)
1252
1253    self.Dump()
1254    self.dumpConfigInfo()
1255    self.dumpMachineInfo()
1256    self.delGenFiles()
1257    # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install
1258    self.framework.storeSubstitutions(self.framework.argDB)
1259    self.framework.argDB['configureCache'] = pickle.dumps(self.framework)
1260    self.framework.argDB.save(force = True)
1261    self.DumpPkgconfig('PETSc.pc')
1262    self.DumpPkgconfig('petsc.pc')
1263    self.DumpModule()
1264    self.postProcessPackages()
1265    self.framework.log.write('================================================================================\n')
1266    self.logClear()
1267    return
1268