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 configureUnused(self): 529 '''Sees if __attribute((unused)) is supported''' 530 if self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 531 self.addDefine('UNUSED', ' ') 532 return 533 self.pushLanguage(self.languages.clanguage) 534 if self.checkLink('__attribute((unused)) static int myfunc(void){ return 1;}', 'int i = myfunc();\n'): 535 self.addDefine('UNUSED', '__attribute((unused))') 536 else: 537 self.addDefine('UNUSED', ' ') 538 self.popLanguage() 539 540 def configureExpect(self): 541 '''Sees if the __builtin_expect directive is supported''' 542 self.pushLanguage(self.languages.clanguage) 543 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 544 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 545 self.popLanguage() 546 547 def configureFunctionName(self): 548 '''Sees if the compiler supports __func__ or a variant. Falls back 549 on __FUNCT__ which PETSc source defines, but most users do not, thus 550 stack traces through user code are better when the compiler's 551 variant is used.''' 552 def getFunctionName(lang): 553 name = '__FUNCT__' 554 self.pushLanguage(lang) 555 if self.checkLink('', "if (__func__[0] != 'm') return 1;"): 556 name = '__func__' 557 elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"): 558 name = '__FUNCTION__' 559 self.popLanguage() 560 return name 561 langs = [] 562 563 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 564 if hasattr(self.compilers, 'CXX'): 565 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 566 else: 567 self.addDefine('FUNCTION_NAME_CXX', '__FUNCT__') 568 569 def configureIntptrt(self): 570 '''Determine what to use for uintptr_t''' 571 def staticAssertSizeMatchesVoidStar(inc,typename): 572 # The declaration is an error if either array size is negative. 573 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 574 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 575 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 576 self.pushLanguage(self.languages.clanguage) 577 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 578 self.addDefine('UINTPTR_T', 'uintptr_t') 579 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 580 self.addDefine('UINTPTR_T', 'unsigned long long') 581 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 582 self.addDefine('UINTPTR_T', 'size_t') 583 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 584 self.addDefine('UINTPTR_T', 'unsigned long') 585 elif staticAssertSizeMatchesVoidStar('','unsigned'): 586 self.addDefine('UINTPTR_T', 'unsigned') 587 else: 588 raise RuntimeError('Could not find any unsigned integer type matching void*') 589 self.popLanguage() 590 591 def configureInline(self): 592 '''Get a generic inline keyword, depending on the language''' 593 if self.languages.clanguage == 'C': 594 self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword) 595 self.addDefine('RESTRICT', self.compilers.cRestrict) 596 elif self.languages.clanguage == 'Cxx': 597 self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword) 598 self.addDefine('RESTRICT', self.compilers.cxxRestrict) 599 600 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 601 self.addDefine('RTLD_DEFAULT','1') 602 return 603 604 def configureSolaris(self): 605 '''Solaris specific stuff''' 606 if os.path.isdir(os.path.join('/usr','ucblib')): 607 try: 608 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 609 except AttributeError: 610 flag = None 611 if flag is None: 612 self.compilers.LIBS += ' -L/usr/ucblib' 613 else: 614 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 615 return 616 617 def configureLinux(self): 618 '''Linux specific stuff''' 619 # TODO: Test for this by mallocing an odd number of floats and checking the address 620 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 621 return 622 623 def configureWin32(self): 624 '''Win32 non-cygwin specific stuff''' 625 kernel32=0 626 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 627 self.addDefine('HAVE_WINDOWS_H',1) 628 self.addDefine('HAVE_GETCOMPUTERNAME',1) 629 kernel32=1 630 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 631 self.addDefine('HAVE_WINDOWS_H',1) 632 self.addDefine('HAVE_GETCOMPUTERNAME',1) 633 kernel32=1 634 if kernel32: 635 if self.framework.argDB['with-windows-graphics']: 636 self.addDefine('USE_WINDOWS_GRAPHICS',1) 637 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 638 self.addDefine('HAVE_LOADLIBRARY',1) 639 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 640 self.addDefine('HAVE_GETPROCADDRESS',1) 641 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 642 self.addDefine('HAVE_FREELIBRARY',1) 643 if self.checkLink('#include <Windows.h>','GetLastError()'): 644 self.addDefine('HAVE_GETLASTERROR',1) 645 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 646 self.addDefine('HAVE_SETLASTERROR',1) 647 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 648 self.addDefine('USE_NT_TIME',1) 649 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 650 self.addDefine('HAVE_GET_USER_NAME',1) 651 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 652 self.addDefine('HAVE_GET_USER_NAME',1) 653 654 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 655 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 656 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 657 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 658 659 self.types.check('int32_t', 'int') 660 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 661 self.addTypedef('int', 'uid_t') 662 self.addTypedef('int', 'gid_t') 663 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 664 self.framework.addDefine('R_OK', '04') 665 self.framework.addDefine('W_OK', '02') 666 self.framework.addDefine('X_OK', '01') 667 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 668 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 669 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 670 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 671 self.addDefine('HAVE_LARGE_INTEGER_U',1) 672 673 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 674 if self.checkCompile('#include <Windows.h>\n', 'int flags = O_BINARY;'): 675 self.addDefine('HAVE_O_BINARY',1) 676 677 if self.compilers.CC.find('win32fe') >= 0: 678 self.addDefine('PATH_SEPARATOR','\';\'') 679 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 680 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 681 self.addDefine('CANNOT_START_DEBUGGER',1) 682 else: 683 self.addDefine('PATH_SEPARATOR','\':\'') 684 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 685 self.addDefine('DIR_SEPARATOR','\'/\'') 686 687 return 688 689#----------------------------------------------------------------------------------------------------- 690 def configureDefaultArch(self): 691 conffile = os.path.join('conf', 'petscvariables') 692 if self.framework.argDB['with-default-arch']: 693 fd = file(conffile, 'w') 694 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 695 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 696 fd.write('include ${PETSC_DIR}/${PETSC_ARCH}/conf/petscvariables\n') 697 fd.close() 698 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 699 elif os.path.isfile(conffile): 700 try: 701 os.unlink(conffile) 702 except: 703 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 704 return 705 706#----------------------------------------------------------------------------------------------------- 707 def configureScript(self): 708 '''Output a script in the conf directory which will reproduce the configuration''' 709 import nargs 710 import sys 711 scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py') 712 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 713 if 'configModules' in args: 714 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 715 del args['configModules'] 716 if 'optionsModule' in args: 717 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions': 718 del args['optionsModule'] 719 if not 'PETSC_ARCH' in args: 720 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 721 f = file(scriptName, 'w') 722 f.write('#!'+sys.executable+'\n') 723 f.write('if __name__ == \'__main__\':\n') 724 f.write(' import sys\n') 725 f.write(' import os\n') 726 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 727 f.write(' import configure\n') 728 # pretty print repr(args.values()) 729 f.write(' configure_options = [\n') 730 for itm in sorted(args.values()): 731 f.write(' \''+str(itm)+'\',\n') 732 f.write(' ]\n') 733 f.write(' configure.petsc_configure(configure_options)\n') 734 f.close() 735 try: 736 os.chmod(scriptName, 0775) 737 except OSError, e: 738 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 739 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 740 return 741 742 def configureInstall(self): 743 '''Setup the directories for installation''' 744 if self.framework.argDB['prefix']: 745 self.installdir = self.framework.argDB['prefix'] 746 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 747 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 748 '-@echo "========================================="']) 749 else: 750 self.installdir = os.path.join(self.petscdir.dir,self.arch.arch) 751 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 752 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 753 '-@echo "========================================="']) 754 return 755 756 def configureGCOV(self): 757 if self.framework.argDB['with-gcov']: 758 self.addDefine('USE_GCOV','1') 759 return 760 761 def configureFortranFlush(self): 762 if hasattr(self.compilers, 'FC'): 763 for baseName in ['flush','flush_']: 764 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 765 self.addDefine('HAVE_'+baseName.upper(), 1) 766 return 767 768 769 def configure(self): 770 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 771 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 772 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 773 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 774 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)): 775 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 776 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 777 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 778 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables') 779 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'conf','petscrules') 780 if self.libraries.math is None: 781 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 782 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 783 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 784 self.executeTest(self.configureInline) 785 self.executeTest(self.configurePrefetch) 786 self.executeTest(self.configureUnused) 787 self.executeTest(self.configureExpect); 788 self.executeTest(self.configureFunctionName); 789 self.executeTest(self.configureIntptrt); 790 self.executeTest(self.configureSolaris) 791 self.executeTest(self.configureLinux) 792 self.executeTest(self.configureWin32) 793 self.executeTest(self.configureDefaultArch) 794 self.executeTest(self.configureScript) 795 self.executeTest(self.configureInstall) 796 self.executeTest(self.configureGCOV) 797 self.executeTest(self.configureFortranFlush) 798 # dummy rules, always needed except for remote builds 799 self.addMakeRule('remote','') 800 self.addMakeRule('remoteclean','') 801 802 self.Dump() 803 self.dumpConfigInfo() 804 self.dumpMachineInfo() 805 self.dumpCMakeConfig() 806 self.dumpCMakeLists() 807 self.cmakeBoot() 808 self.framework.log.write('================================================================================\n') 809 self.logClear() 810 return 811