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