xref: /petsc/config/PETSc/Configure.py (revision 3649974ff2fe2c90f327f29aac9f68ec978ade9e)
1import config.base
2
3import os
4import re
5
6class Configure(config.base.Configure):
7  def __init__(self, framework):
8    config.base.Configure.__init__(self, framework)
9    self.headerPrefix = 'PETSC'
10    self.substPrefix  = 'PETSC'
11    self.defineAutoconfMacros()
12    return
13
14  def __str2__(self):
15    desc = []
16    desc.append('xxx=========================================================================xxx')
17    desc.append('   Configure stage complete. Now build PETSc libraries with:')
18    desc.append('   make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all')
19    desc.append('xxx=========================================================================xxx')
20    return '\n'.join(desc)+'\n'
21
22  def setupHelp(self, help):
23    import nargs
24    help.addArgument('PETSc',  '-prefix=<path>',                  nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)'))
25    help.addArgument('Windows','-with-windows-graphics=<bool>',   nargs.ArgBool(None, 1,'Enable check for Windows Graphics'))
26    help.addArgument('PETSc', '-with-default-arch=<bool>',        nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH'))
27    help.addArgument('PETSc','-with-single-library=<bool>',       nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library'))
28    help.addArgument('PETSc', '-with-iphone=<no,yes>',            nargs.ArgDownload(None, 0, 'Build an iPhone version of PETSc'))
29    return
30
31  def setupDependencies(self, framework):
32    config.base.Configure.setupDependencies(self, framework)
33    self.setCompilers  = framework.require('config.setCompilers',      self)
34    self.arch          = framework.require('PETSc.utilities.arch',     self.setCompilers)
35    self.petscdir      = framework.require('PETSc.utilities.petscdir', self.setCompilers)
36    self.languages     = framework.require('PETSc.utilities.languages',self.setCompilers)
37    self.debugging     = framework.require('PETSc.utilities.debugging',self.setCompilers)
38    self.make          = framework.require('PETSc.utilities.Make',     self)
39    self.CHUD          = framework.require('PETSc.utilities.CHUD',     self)
40    self.compilers     = framework.require('config.compilers',         self)
41    self.types         = framework.require('config.types',             self)
42    self.headers       = framework.require('config.headers',           self)
43    self.functions     = framework.require('config.functions',         self)
44    self.libraries     = framework.require('config.libraries',         self)
45    if os.path.isdir(os.path.join('config', 'PETSc')):
46      for d in ['utilities', 'packages']:
47        for utility in os.listdir(os.path.join('config', 'PETSc', d)):
48          (utilityName, ext) = os.path.splitext(utility)
49          if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__':
50            utilityObj                    = self.framework.require('PETSc.'+d+'.'+utilityName, self)
51            utilityObj.headerPrefix       = self.headerPrefix
52            utilityObj.archProvider       = self.arch
53            utilityObj.languageProvider   = self.languages
54            utilityObj.installDirProvider = self.petscdir
55            setattr(self, utilityName.lower(), utilityObj)
56    self.qd    = framework.require('PETSc.packages.qd', self)
57    self.qd.archProvider      = self.arch
58    self.qd.precisionProvider = self.scalartypes
59    self.qd.installDirProvider= self.petscdir
60
61    #force blaslapack to depend on scalarType so precision is set before BlasLapack is built
62    self.blaslapack    = framework.require('config.packages.BlasLapack', self)
63    framework.require('PETSc.utilities.scalarTypes', self.blaslapack)
64    self.blaslapack.archProvider      = self.arch
65    self.blaslapack.precisionProvider = self.scalartypes
66    self.blaslapack.installDirProvider= self.petscdir
67
68    self.mpi           = framework.require('config.packages.MPI',        self)
69    self.mpi.archProvider             = self.arch
70    self.mpi.languageProvider         = self.languages
71    self.mpi.installDirProvider       = self.petscdir
72    self.umfpack       = framework.require('config.packages.UMFPACK',    self)
73    self.umfpack.archProvider         = self.arch
74    self.umfpack.languageProvider     = self.languages
75    self.umfpack.installDirProvider   = self.petscdir
76    self.cholmod       = framework.require('config.packages.CHOLMOD',    self)
77    self.cholmod.archProvider         = self.arch
78    self.cholmod.languageProvider     = self.languages
79    self.cholmod.installDirProvider   = self.petscdir
80    self.boost         = framework.require('config.packages.boost',      self)
81    self.boost.archProvider           = self.arch
82    self.boost.languageProvider       = self.languages
83    self.boost.installDirProvider     = self.petscdir
84    self.Fiat          = framework.require('config.packages.Fiat',       self)
85    self.Fiat.archProvider            = self.arch
86    self.Fiat.languageProvider        = self.languages
87    self.Fiat.installDirProvider      = self.petscdir
88    self.ExodusII      = framework.require('config.packages.ExodusII',   self)
89    self.ExodusII.archProvider        = self.arch
90    self.ExodusII.languageProvider    = self.languages
91    self.ExodusII.installDirProvider  = self.petscdir
92
93    self.compilers.headerPrefix = self.headerPrefix
94    self.types.headerPrefix     = self.headerPrefix
95    self.headers.headerPrefix   = self.headerPrefix
96    self.functions.headerPrefix = self.headerPrefix
97    self.libraries.headerPrefix = self.headerPrefix
98    self.blaslapack.headerPrefix = self.headerPrefix
99    self.mpi.headerPrefix        = self.headerPrefix
100    headersC = map(lambda name: name+'.h', ['dos', 'endian', 'fcntl', 'float', 'io', 'limits', 'malloc', 'pwd', 'search', 'strings',
101                                            'unistd', 'machine/endian', 'sys/param', 'sys/procfs', 'sys/resource',
102                                            'sys/systeminfo', 'sys/times', 'sys/utsname','string', 'stdlib','memory',
103                                            'sys/socket','sys/wait','netinet/in','netdb','Direct','time','Ws2tcpip','sys/types',
104                                            'WindowsX', 'cxxabi','float','ieeefp','stdint','fenv'])
105    functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 'getpwuid',
106                 'gettimeofday', 'getwd', 'memalign', 'memmove', 'mkstemp', 'popen', 'PXFGETARG', 'rand', 'getpagesize',
107                 'readlink', 'realpath',  'sigaction', 'signal', 'sigset', 'nanosleep', 'usleep', 'sleep', '_sleep', 'socket',
108                 'times', 'gethostbyname', 'uname','snprintf','_snprintf','_fullpath','lseek','_lseek','time','fork','stricmp',
109                 'strcasecmp', 'bzero', 'dlopen', 'dlsym', 'dlclose', 'dlerror',
110                 '_intel_fast_memcpy','_intel_fast_memset']
111    libraries1 = [(['socket', 'nsl'], 'socket'), (['fpe'], 'handle_sigfpes')]
112    self.headers.headers.extend(headersC)
113    self.functions.functions.extend(functions)
114    self.libraries.libraries.extend(libraries1)
115    return
116
117  def defineAutoconfMacros(self):
118    self.hostMacro = 'dnl Version: 2.13\ndnl Variable: host_cpu\ndnl Variable: host_vendor\ndnl Variable: host_os\nAC_CANONICAL_HOST'
119    return
120
121  def Dump(self):
122    ''' Actually put the values into the configuration files '''
123    # eventually everything between -- should be gone
124#-----------------------------------------------------------------------------------------------------
125
126    # Sometimes we need C compiler, even if built with C++
127    self.setCompilers.pushLanguage('C')
128    self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags())
129    self.setCompilers.popLanguage()
130
131    # C preprocessor values
132    self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS+self.CHUD.CPPFLAGS)
133
134    # compiler values
135    self.setCompilers.pushLanguage(self.languages.clanguage)
136    self.addMakeMacro('PCC',self.setCompilers.getCompiler())
137    self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags())
138    self.setCompilers.popLanguage()
139    # .o or .obj
140    self.addMakeMacro('CC_SUFFIX','o')
141
142    # executable linker values
143    self.setCompilers.pushLanguage(self.languages.clanguage)
144    pcc_linker = self.setCompilers.getLinker()
145    self.addMakeMacro('PCC_LINKER',pcc_linker)
146    self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
147    self.setCompilers.popLanguage()
148    # '' for Unix, .exe for Windows
149    self.addMakeMacro('CC_LINKER_SUFFIX','')
150    self.addMakeMacro('PCC_LINKER_LIBS',self.libraries.toStringNoDupes(self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split(' '))+self.CHUD.LIBS)
151
152    if hasattr(self.compilers, 'FC'):
153      self.setCompilers.pushLanguage('FC')
154      # need FPPFLAGS in config/setCompilers
155      self.addDefine('HAVE_FORTRAN','1')
156      self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS)
157
158      # compiler values
159      self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags())
160      self.setCompilers.popLanguage()
161      # .o or .obj
162      self.addMakeMacro('FC_SUFFIX','o')
163
164      # executable linker values
165      self.setCompilers.pushLanguage('FC')
166      # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker
167      fc_linker = self.setCompilers.getLinker()
168      if config.setCompilers.Configure.isNAG(fc_linker):
169        self.addMakeMacro('FC_LINKER',pcc_linker)
170      else:
171        self.addMakeMacro('FC_LINKER',fc_linker)
172      self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags())
173      # apple requires this shared library linker flag on SOME versions of the os
174      if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1:
175        self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ')
176      self.setCompilers.popLanguage()
177
178      # F90 Modules
179      if self.setCompilers.fortranModuleIncludeFlag:
180        self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag)
181      else: # for non-f90 compilers like g77
182        self.addMakeMacro('FC_MODULE_FLAG', '-I')
183      if self.setCompilers.fortranModuleIncludeFlag:
184        self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag)
185    else:
186      self.addMakeMacro('FC','')
187
188    # shared library linker values
189    self.setCompilers.pushLanguage(self.languages.clanguage)
190    # need to fix BuildSystem to collect these separately
191    self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker())
192    self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}')
193    self.setCompilers.popLanguage()
194    # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture
195    # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX
196    if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX:
197      self.addMakeMacro('SL_LINKER_SUFFIX', '')
198      self.addDefine('SLSUFFIX','""')
199    else:
200      self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt)
201      self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"')
202
203    #SL_LINKER_LIBS is currently same as PCC_LINKER_LIBS - so simplify
204    self.addMakeMacro('SL_LINKER_LIBS','${PCC_LINKER_LIBS}')
205    #self.addMakeMacro('SL_LINKER_LIBS',self.libraries.toStringNoDupes(self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split(' ')))
206
207#-----------------------------------------------------------------------------------------------------
208
209    # CONLY or CPP. We should change the PETSc makefiles to do this better
210    if self.languages.clanguage == 'C': lang = 'CONLY'
211    else: lang = 'CXXONLY'
212    self.addMakeMacro('PETSC_LANGUAGE',lang)
213
214    # real or complex
215    self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype)
216    # double or float
217    self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision)
218
219    if self.framework.argDB['with-batch']:
220      self.addMakeMacro('PETSC_WITH_BATCH','1')
221
222    # Test for compiler-specific macros that need to be defined.
223    if self.setCompilers.isCray('CC'):
224      self.addDefine('HAVE_CRAYC','1')
225
226#-----------------------------------------------------------------------------------------------------
227    if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket'):
228      self.addDefine('USE_SOCKET_VIEWER','1')
229
230#-----------------------------------------------------------------------------------------------------
231    # print include and lib for external packages
232    self.framework.packages.reverse()
233    includes = []
234    libs = []
235    for i in self.framework.packages:
236      if i.useddirectly:
237        self.addDefine('HAVE_'+i.PACKAGE, 1)  # ONLY list package if it is used directly by PETSc (and not only by another package)
238      if not isinstance(i.lib, list):
239        i.lib = [i.lib]
240      libs.extend(i.lib)
241      self.addMakeMacro(i.PACKAGE+'_LIB', self.libraries.toStringNoDupes(i.lib))
242      if hasattr(i,'include'):
243        if not isinstance(i.include,list):
244          i.include = [i.include]
245        includes.extend(i.include)
246        self.addMakeMacro(i.PACKAGE+'_INCLUDE',self.headers.toStringNoDupes(i.include))
247    self.addMakeMacro('PACKAGES_LIBS',self.libraries.toStringNoDupes(libs+self.libraries.math))
248    self.PACKAGES_LIBS = self.libraries.toStringNoDupes(libs+self.libraries.math)
249    self.addMakeMacro('PACKAGES_INCLUDES',self.headers.toStringNoDupes(includes))
250    self.PACKAGES_INCLUDES = self.headers.toStringNoDupes(includes)
251    if hasattr(self.compilers, 'FC'):
252      if self.compilers.fortranIsF90:
253        self.addMakeMacro('PACKAGES_MODULES_INCLUDES',self.headers.toStringModulesNoDupes(includes))
254
255    self.addMakeMacro('DESTDIR',self.installdir)
256    self.addDefine('LIB_DIR','"'+os.path.join(self.installdir,'lib')+'"')
257
258    if self.framework.argDB['with-single-library']:
259      # overrides the values set in conf/variables
260      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}')
261      self.addMakeMacro('PETSC_SYS_LIB_BASIC','-lpetsc')
262      self.addMakeMacro('PETSC_VEC_LIB_BASIC','-lpetsc')
263      self.addMakeMacro('PETSC_MAT_LIB_BASIC','-lpetsc')
264      self.addMakeMacro('PETSC_DM_LIB_BASIC','-lpetsc')
265      self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc')
266      self.addMakeMacro('PETSC_SNES_LIB_BASIC','-lpetsc')
267      self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc')
268      self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc')
269      self.addMakeMacro('PETSC_CONTRIB_BASIC','-lpetsc')
270      self.addMakeMacro('SHLIBS','libpetsc')
271      self.addDefine('USE_SINGLE_LIBRARY', '1')
272
273    if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')):
274      os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib'))
275
276    # add a makefile entry for configure options
277    self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"'))
278    return
279
280  def dumpConfigInfo(self):
281    import time
282    fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w')
283    fd.write('static const char *petscconfigureruntime = "'+time.ctime(time.time())+'";\n')
284    fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n')
285    fd.close()
286    return
287
288  def dumpMachineInfo(self):
289    import platform
290    import time
291    import script
292    fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w')
293    fd.write('static const char *petscmachineinfo = \"\\n\"\n')
294    fd.write('\"-----------------------------------------\\n\"\n')
295    fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (time.ctime(time.time()), platform.node()))
296    fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform()))
297    fd.write('\"Using PETSc directory: %s\\n\"\n' % (self.petscdir.dir))
298    fd.write('\"Using PETSc arch: %s\\n\"\n' % (self.arch.arch))
299    fd.write('\"-----------------------------------------\\n\";\n')
300    fd.write('static const char *petsccompilerinfo = \"\\n\"\n')
301    self.setCompilers.pushLanguage(self.languages.clanguage)
302    fd.write('\"Using C compiler: %s %s ${COPTFLAGS} ${CFLAGS}\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags()))
303    self.setCompilers.popLanguage()
304    if hasattr(self.compilers, 'FC'):
305      self.setCompilers.pushLanguage('FC')
306      fd.write('\"Using Fortran compiler: %s %s ${FOPTFLAGS} ${FFLAGS} %s\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags(), self.setCompilers.CPPFLAGS))
307      self.setCompilers.popLanguage()
308    fd.write('\"-----------------------------------------\\n\";\n')
309    fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n')
310    fd.write('\"Using include paths: %s %s %s\\n\"\n' % ('-I'+os.path.join(self.petscdir.dir, self.arch.arch, 'include'), '-I'+os.path.join(self.petscdir.dir, 'include'), self.PACKAGES_INCLUDES))
311    fd.write('\"-----------------------------------------\\n\";\n')
312    fd.write('static const char *petsclinkerinfo = \"\\n\"\n')
313    self.setCompilers.pushLanguage(self.languages.clanguage)
314    fd.write('\"Using C linker: %s\\n\"\n' % (self.setCompilers.getLinker()))
315    self.setCompilers.popLanguage()
316    if hasattr(self.compilers, 'FC'):
317      self.setCompilers.pushLanguage('FC')
318      fd.write('\"Using Fortran linker: %s\\n\"\n' % (self.setCompilers.getLinker()))
319      self.setCompilers.popLanguage()
320    fd.write('\"Using libraries: %s%s -L%s %s %s %s\\n\"\n' % (self.setCompilers.CSharedLinkerFlag, os.path.join(self.petscdir.dir, self.arch.arch, 'lib'), os.path.join(self.petscdir.dir, self.arch.arch, 'lib'), '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys', self.PACKAGES_LIBS, self.libraries.toStringNoDupes(self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split(' '))+self.CHUD.LIBS))
321    fd.write('\"-----------------------------------------\\n\";\n')
322    fd.close()
323    return
324
325  def dumpCMakeConfig(self):
326    '''
327    Writes configuration-specific values to ${PETSC_ARCH}/conf/PETScConfig.cmake.
328    This file is private to PETSc and should not be included by third parties
329    (a suitable file can be produced later by CMake, but this is not it).
330    '''
331    def cmakeset(fd,key,val=True):
332      if val == True: val = 'YES'
333      if val == False: val = 'NO'
334      fd.write('set (' + key + ' ' + val + ')\n')
335    def ensurelist(a):
336      if isinstance(a,list):
337        return a
338      else:
339        return [a]
340    def libpath(lib):
341      'Returns a search path if that is what this item provides, else "" which will be cleaned out later'
342      if lib.startswith('-L'): return lib[2:]
343      if lib.startswith('-R'): return lib[2:]
344      if lib.startswith('-Wl,-rpath,'):
345        # This case occurs when an external package needs a specific system library that is normally provided by the compiler.
346        # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the
347        # corresponding library.
348        return lib[len('-Wl,-rpath,'):]
349      if lib.startswith('-'): return ''
350      return os.path.dirname(lib)
351    def cleanlib(lib):
352      'Returns a library name if that is what this item provides, else "" which will be cleaned out later'
353      if lib.startswith('-l'):  return lib[2:]
354      if lib.startswith('-Wl') or lib.startswith('-L'): return ''
355      lib = os.path.splitext(os.path.basename(lib))[0]
356      if lib.startswith('lib'): return lib[3:]
357      return lib
358    def nub(lst):
359      unique = []
360      for elem in lst:
361        if elem not in unique and elem != '':
362          unique.append(elem)
363      return unique
364    def cmakeexpand(varname):
365      return r'"${' + varname + r'}"'
366    def uniqextend(list,new):
367      for x in ensurelist(new):
368        if x not in list:
369          list.append(x)
370    def notstandardinclude(path):
371      return path not in '/usr/include /usr/local/include'.split()
372    def writeMacroDefinitions(fd):
373      if self.mpi.usingMPIUni:
374        cmakeset(fd,'PETSC_HAVE_MPIUNI')
375      for pkg in self.framework.packages:
376        if pkg.useddirectly:
377          cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE)
378      for name,val in self.functions.defines.items():
379        cmakeset(fd,'PETSC_'+name,val)
380      for dct in [self.defines, self.libraryoptions.defines]:
381        for k,v in dct.items():
382          if k.startswith('USE_'):
383            cmakeset(fd,'PETSC_' + k, v)
384      cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex')
385      cmakeset(fd,'PETSC_USE_SCALAR_' + self.scalartypes.precision.upper())
386      cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage)
387      if hasattr(self.compilers, 'FC'):
388        cmakeset(fd,'PETSC_HAVE_FORTRAN')
389        if self.compilers.fortranIsF90:
390          cmakeset(fd,'PETSC_USING_F90')
391      if self.sharedlibraries.useShared:
392        cmakeset(fd,'BUILD_SHARED_LIBS')
393    def writeBuildFlags(fd):
394      lib_paths = []
395      lib_libs  = []
396      includes  = []
397      libvars   = []
398      for pkg in self.framework.packages:
399        libs = ensurelist(pkg.lib)
400        lib_paths.extend(map(libpath,libs))
401        lib_libs.extend(map(cleanlib,libs))
402        uniqextend(includes,pkg.include)
403      for libname in nub(lib_libs):
404        libvar = 'PETSC_' + libname.upper() + '_LIB'
405        addpath = ''
406        for lpath in nub(lib_paths):
407          addpath += '"' + str(lpath) + '" '
408        fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n')
409        libvars.append(libvar)
410      fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n')
411      fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n')
412      fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',filter(notstandardinclude,includes))) + ')\n')
413    fd = open(os.path.join(self.arch.arch,'conf','PETScConfig.cmake'), 'w')
414    writeMacroDefinitions(fd)
415    writeBuildFlags(fd)
416    fd.close()
417    return
418
419  def configurePrefetch(self):
420    '''Sees if there are any prefetch functions supported'''
421    if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']:
422      self.addDefine('Prefetch(a,b,c)', ' ')
423      return
424    self.pushLanguage(self.languages.clanguage)
425    if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,(int)0);\n'):
426      self.addDefine('HAVE_XMMINTRIN_H', 1)
427      self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(int)(c))')
428    elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,(int)0);\n'):
429      self.addDefine('HAVE_XMMINTRIN_H', 1)
430      self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(int)(c))')
431    elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'):
432      self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))')
433    else:
434      self.addDefine('Prefetch(a,b,c)', ' ')
435    self.popLanguage()
436
437  def configureExpect(self):
438    '''Sees if the __builtin_expect directive is supported'''
439    self.pushLanguage(self.languages.clanguage)
440    if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'):
441      self.addDefine('HAVE_BUILTIN_EXPECT', 1)
442    self.popLanguage()
443
444  def configureIntptrt(self):
445    '''Determine what to use for uintptr_t'''
446    def staticAssertSizeMatchesVoidStar(inc,typename):
447      # The declaration is an error if either array size is negative.
448      # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case
449      return self.checkCompile(inc, '#define SZ (sizeof(void*)-sizeof(%s))\nint type_is_too_large[SZ],type_is_too_small[-SZ];'%typename)
450    self.pushLanguage(self.languages.clanguage)
451    if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'):
452      self.addDefine('UINTPTR_T', 'uintptr_t')
453    elif staticAssertSizeMatchesVoidStar('','unsigned long long'):
454      self.addDefine('UINTPTR_T', 'unsigned long long')
455    elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'):
456      self.addDefine('UINTPTR_T', 'size_t')
457    elif staticAssertSizeMatchesVoidStar('','unsigned'):
458      self.addDefine('UINTPTR_T', 'unsigned')
459    self.popLanguage()
460
461  def configureInline(self):
462    '''Get a generic inline keyword, depending on the language'''
463    if self.languages.clanguage == 'C':
464      self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword)
465      self.addDefine('RESTRICT', self.compilers.cRestrict)
466    elif self.languages.clanguage == 'Cxx':
467      self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword)
468      self.addDefine('RESTRICT', self.compilers.cxxRestrict)
469    return
470
471  def configureSolaris(self):
472    '''Solaris specific stuff'''
473    if self.arch.hostOsBase.startswith('solaris'):
474      if os.path.isdir(os.path.join('/usr','ucblib')):
475        try:
476          flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag')
477        except AttributeError:
478          flag = None
479        if flag is None:
480          self.compilers.LIBS += ' -L/usr/ucblib'
481        else:
482          self.compilers.LIBS += ' '+flag+'/usr/ucblib'
483    return
484
485  def configureLinux(self):
486    '''Linux specific stuff'''
487    if self.arch.hostOsBase == 'linux':
488      self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1)
489    return
490
491  def configureWin32(self):
492    '''Win32 non-cygwin specific stuff'''
493    kernel32=0
494    if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'):
495      self.addDefine('HAVE_WINDOWS_H',1)
496      self.addDefine('HAVE_GETCOMPUTERNAME',1)
497      kernel32=1
498    elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'):
499      self.addDefine('HAVE_WINDOWS_H',1)
500      self.addDefine('HAVE_GETCOMPUTERNAME',1)
501      kernel32=1
502    if kernel32:
503      if self.framework.argDB['with-windows-graphics']:
504        self.addDefine('USE_WINDOWS_GRAPHICS',1)
505      if self.checkLink('#include <Windows.h>','LoadLibrary(0)'):
506        self.addDefine('HAVE_LOADLIBRARY',1)
507      if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'):
508        self.addDefine('HAVE_GETPROCADDRESS',1)
509      if self.checkLink('#include <Windows.h>','FreeLibrary(0)'):
510        self.addDefine('HAVE_FREELIBRARY',1)
511      if self.checkLink('#include <Windows.h>','GetLastError()'):
512        self.addDefine('HAVE_GETLASTERROR',1)
513      if self.checkLink('#include <Windows.h>','SetLastError(0)'):
514        self.addDefine('HAVE_SETLASTERROR',1)
515      if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'):
516        self.addDefine('USE_NT_TIME',1)
517    if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'):
518      self.addDefine('HAVE_GET_USER_NAME',1)
519    elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'):
520      self.addDefine('HAVE_GET_USER_NAME',1)
521
522    if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'):
523      self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);')
524    if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'):
525      self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);')
526
527    self.types.check('int32_t', 'int')
528    if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'):
529      self.addTypedef('int', 'uid_t')
530      self.addTypedef('int', 'gid_t')
531    if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'):
532      self.framework.addDefine('R_OK', '04')
533      self.framework.addDefine('W_OK', '02')
534      self.framework.addDefine('X_OK', '01')
535    if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'):
536      self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)')
537      self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)')
538    if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'):
539      self.addDefine('HAVE_LARGE_INTEGER_U',1)
540
541    # Windows requires a Binary file creation flag when creating/opening binary files.  Is a better test in order?
542    if self.checkCompile('#include <Windows.h>\n',''):
543      self.addDefine('HAVE_O_BINARY',1)
544
545    if self.compilers.CC.find('win32fe') >= 0:
546      self.addDefine('PATH_SEPARATOR','\';\'')
547      self.addDefine('DIR_SEPARATOR','\'\\\\\'')
548      self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'')
549      self.addDefine('CANNOT_START_DEBUGGER',1)
550    else:
551      self.addDefine('PATH_SEPARATOR','\':\'')
552      self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'')
553      self.addDefine('DIR_SEPARATOR','\'/\'')
554    return
555
556#-----------------------------------------------------------------------------------------------------
557  def configureDefaultArch(self):
558    conffile = os.path.join('conf', 'petscvariables')
559    if self.framework.argDB['with-default-arch']:
560      fd = file(conffile, 'w')
561      fd.write('PETSC_ARCH='+self.arch.arch+'\n')
562      fd.write('PETSC_DIR='+self.petscdir.dir+'\n')
563      fd.write('include ${PETSC_DIR}/${PETSC_ARCH}/conf/petscvariables\n')
564      fd.close()
565      self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile)
566    elif os.path.isfile(conffile):
567      try:
568        os.unlink(conffile)
569      except:
570        raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?')
571    return
572
573#-----------------------------------------------------------------------------------------------------
574  def configureScript(self):
575    '''Output a script in the conf directory which will reproduce the configuration'''
576    import nargs
577    import sys
578    scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py')
579    args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs])
580    if 'configModules' in args:
581      if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure':
582        del args['configModules']
583    if 'optionsModule' in args:
584      if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions':
585        del args['optionsModule']
586    if not 'PETSC_ARCH' in args:
587      args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch)
588    f = file(scriptName, 'w')
589    f.write('#!'+sys.executable+'\n')
590    f.write('if __name__ == \'__main__\':\n')
591    f.write('  import sys\n')
592    f.write('  import os\n')
593    f.write('  sys.path.insert(0, os.path.abspath(\'config\'))\n')
594    f.write('  import configure\n')
595    # pretty print repr(args.values())
596    f.write('  configure_options = [\n')
597    for itm in args.values():
598      f.write('    \''+str(itm)+'\',\n')
599    f.write('  ]\n')
600    f.write('  configure.petsc_configure(configure_options)\n')
601    f.close()
602    try:
603      os.chmod(scriptName, 0775)
604    except OSError, e:
605      self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e))
606    self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration')
607    return
608
609  def configureInstall(self):
610    '''Setup the directories for installation'''
611    if self.framework.argDB['prefix']:
612      self.installdir = self.framework.argDB['prefix']
613      self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\
614                                              '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\
615                                              '-@echo "========================================="'])
616    else:
617      self.installdir = os.path.join(self.petscdir.dir,self.arch.arch)
618      self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\
619                                              '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\
620                                              '-@echo "========================================="'])
621      return
622
623  def configureGCOV(self):
624    if self.framework.argDB['with-gcov']:
625      self.addDefine('USE_GCOV','1')
626    return
627
628  def configureFortranFlush(self):
629    if hasattr(self.compilers, 'FC'):
630      for baseName in ['flush','flush_']:
631        if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1):
632          self.addDefine('HAVE_'+baseName.upper(), 1)
633          return
634
635
636  def configure(self):
637    if not os.path.samefile(self.petscdir.dir, os.getcwd()):
638      raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n  Configure invoked in: '+os.path.realpath(os.getcwd()))
639    if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir):
640      raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!')
641    self.framework.header          = self.arch.arch+'/include/petscconf.h'
642    self.framework.cHeader         = self.arch.arch+'/include/petscfix.h'
643    self.framework.makeMacroHeader = self.arch.arch+'/conf/petscvariables'
644    self.framework.makeRuleHeader  = self.arch.arch+'/conf/petscrules'
645    if self.libraries.math is None:
646      raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.')
647    if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'):
648      raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.')
649    self.executeTest(self.configureInline)
650    self.executeTest(self.configurePrefetch)
651    self.executeTest(self.configureExpect);
652    self.executeTest(self.configureIntptrt);
653    self.executeTest(self.configureSolaris)
654    self.executeTest(self.configureLinux)
655    self.executeTest(self.configureWin32)
656    self.executeTest(self.configureDefaultArch)
657    self.executeTest(self.configureScript)
658    self.executeTest(self.configureInstall)
659    self.executeTest(self.configureGCOV)
660    self.executeTest(self.configureFortranFlush)
661    # dummy rules, always needed except for remote builds
662    self.addMakeRule('remote','')
663    self.addMakeRule('remoteclean','')
664
665    self.Dump()
666    self.dumpConfigInfo()
667    self.dumpMachineInfo()
668    self.dumpCMakeConfig()
669    self.framework.log.write('================================================================================\n')
670    self.logClear()
671    return
672