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