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