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)) 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 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)) 326 fd.write('\"-----------------------------------------\\n\";\n') 327 fd.close() 328 return 329 330 def dumpCMakeConfig(self): 331 ''' 332 Writes configuration-specific values to ${PETSC_ARCH}/conf/PETScConfig.cmake. 333 This file is private to PETSc and should not be included by third parties 334 (a suitable file can be produced later by CMake, but this is not it). 335 ''' 336 def cmakeset(fd,key,val=True): 337 if val == True: val = 'YES' 338 if val == False: val = 'NO' 339 fd.write('set (' + key + ' ' + val + ')\n') 340 def ensurelist(a): 341 if isinstance(a,list): 342 return a 343 else: 344 return [a] 345 def libpath(lib): 346 'Returns a search path if that is what this item provides, else "" which will be cleaned out later' 347 if not isinstance(lib,str): return '' 348 if lib.startswith('-L'): return lib[2:] 349 if lib.startswith('-R'): return lib[2:] 350 if lib.startswith('-Wl,-rpath,'): 351 # This case occurs when an external package needs a specific system library that is normally provided by the compiler. 352 # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the 353 # corresponding library. 354 return lib[len('-Wl,-rpath,'):] 355 if lib.startswith('-'): return '' 356 return os.path.dirname(lib) 357 def cleanlib(lib): 358 'Returns a library name if that is what this item provides, else "" which will be cleaned out later' 359 if not isinstance(lib,str): return '' 360 if lib.startswith('-l'): return lib[2:] 361 if lib.startswith('-Wl') or lib.startswith('-L'): return '' 362 lib = os.path.splitext(os.path.basename(lib))[0] 363 if lib.startswith('lib'): return lib[3:] 364 return lib 365 def nub(lst): 366 'Return a list containing the first occurrence of each unique element' 367 unique = [] 368 for elem in lst: 369 if elem not in unique and elem != '': 370 unique.append(elem) 371 return unique 372 try: reversed # reversed was added in Python-2.4 373 except NameError: 374 def reversed(lst): return lst[::-1] 375 def nublast(lst): 376 'Return a list containing the last occurrence of each unique entry in a list' 377 return reversed(nub(reversed(lst))) 378 def cmakeexpand(varname): 379 return r'"${' + varname + r'}"' 380 def uniqextend(lst,new): 381 for x in ensurelist(new): 382 if x not in lst: 383 lst.append(x) 384 def notstandardinclude(path): 385 return path not in '/usr/include /usr/local/include'.split() 386 def writeMacroDefinitions(fd): 387 if self.mpi.usingMPIUni: 388 cmakeset(fd,'PETSC_HAVE_MPIUNI') 389 for pkg in self.framework.packages: 390 if pkg.useddirectly: 391 cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE) 392 for name,val in self.functions.defines.items(): 393 cmakeset(fd,'PETSC_'+name,val) 394 for dct in [self.defines, self.libraryoptions.defines]: 395 for k,v in dct.items(): 396 if k.startswith('USE_'): 397 cmakeset(fd,'PETSC_' + k, v) 398 cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex') 399 cmakeset(fd,'PETSC_USE_REAL_' + self.scalartypes.precision.upper()) 400 cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage) 401 if hasattr(self.compilers, 'FC'): 402 cmakeset(fd,'PETSC_HAVE_FORTRAN') 403 if self.compilers.fortranIsF90: 404 cmakeset(fd,'PETSC_USING_F90') 405 if self.sharedlibraries.useShared: 406 cmakeset(fd,'BUILD_SHARED_LIBS') 407 def writeBuildFlags(fd): 408 def extendby(lib): 409 libs = ensurelist(lib) 410 lib_paths.extend(map(libpath,libs)) 411 lib_libs.extend(map(cleanlib,libs)) 412 uniqextend(includes,pkg.include) 413 lib_paths = [] 414 lib_libs = [] 415 includes = [] 416 libvars = [] 417 for pkg in self.framework.packages: 418 extendby(pkg.lib) 419 extendby(self.libraries.math) 420 extendby(self.libraries.rt) 421 extendby(self.compilers.flibs) 422 extendby(self.compilers.cxxlibs) 423 extendby(self.compilers.LIBS.split()) 424 for libname in nublast(lib_libs): 425 libvar = 'PETSC_' + libname.upper() + '_LIB' 426 addpath = '' 427 for lpath in nublast(lib_paths): 428 addpath += '"' + str(lpath) + '" ' 429 fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n') 430 libvars.append(libvar) 431 fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n') 432 fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n') 433 fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',filter(notstandardinclude,includes))) + ')\n') 434 fd = open(os.path.join(self.arch.arch,'conf','PETScConfig.cmake'), 'w') 435 writeMacroDefinitions(fd) 436 writeBuildFlags(fd) 437 fd.close() 438 return 439 440 def dumpCMakeLists(self): 441 import sys 442 if sys.version_info >= (2,5): 443 import cmakegen 444 try: 445 cmakegen.main(self.petscdir.dir) 446 except (OSError), e: 447 self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e)) 448 else: 449 self.framework.logPrint('Skipping cmakegen due to old python version: ' +str(sys.version_info) ) 450 451 def cmakeBoot(self): 452 import sys 453 self.cmakeboot_success = False 454 if sys.version_info >= (2,5) and hasattr(self.cmake,'cmake'): 455 try: 456 import cmakeboot 457 self.cmakeboot_success = cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,log=self.framework.log) 458 except (OSError), e: 459 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 460 except (ImportError, KeyError), e: 461 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 462 if self.cmakeboot_success and not hasattr(self.compilers, 'CUDAC'): # Our CMake build does not support CUDA at this time 463 self.addMakeMacro('PETSC_BUILD_USING_CMAKE',1) 464 else: 465 self.framework.logPrint('Skipping cmakeboot due to old python version: ' +str(sys.version_info) ) 466 return 467 468 def configurePrefetch(self): 469 '''Sees if there are any prefetch functions supported''' 470 if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 471 self.addDefine('Prefetch(a,b,c)', ' ') 472 return 473 self.pushLanguage(self.languages.clanguage) 474 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 475 # The Intel Intrinsics manual [1] specifies the prototype 476 # 477 # void _mm_prefetch(char const *a, int sel); 478 # 479 # but other vendors seem to insist on using subtly different 480 # prototypes, including void* for the pointer, and an enum for 481 # sel. These are both reasonable changes, but negatively impact 482 # portability. 483 # 484 # [1] http://software.intel.com/file/6373 485 self.addDefine('HAVE_XMMINTRIN_H', 1) 486 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(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('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 492 self.addDefine('HAVE_XMMINTRIN_H', 1) 493 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 494 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 495 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 496 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 497 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 498 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 499 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 500 # 501 # The value of rw is a compile-time constant one or zero; one 502 # means that the prefetch is preparing for a write to the memory 503 # address and zero, the default, means that the prefetch is 504 # preparing for a read. The value locality must be a compile-time 505 # constant integer between zero and three. A value of zero means 506 # that the data has no temporal locality, so it need not be left 507 # in the cache after the access. A value of three means that the 508 # data has a high degree of temporal locality and should be left 509 # in all levels of cache possible. Values of one and two mean, 510 # respectively, a low or moderate degree of temporal locality. 511 # 512 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 513 # hints. Using macros for these values in necessary since some 514 # compilers require an enum. 515 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 516 self.addDefine('PREFETCH_HINT_NTA', '0') 517 self.addDefine('PREFETCH_HINT_T0', '3') 518 self.addDefine('PREFETCH_HINT_T1', '2') 519 self.addDefine('PREFETCH_HINT_T2', '1') 520 else: 521 self.addDefine('Prefetch(a,b,c)', ' ') 522 self.popLanguage() 523 524 def configureUnused(self): 525 '''Sees if __attribute((unused)) is supported''' 526 if self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 527 self.addDefine('UNUSED', ' ') 528 return 529 self.pushLanguage(self.languages.clanguage) 530 if self.checkLink('__attribute((unused)) static int myfunc(void){ return 1;}', 'int i = myfunc();\n'): 531 self.addDefine('UNUSED', '__attribute((unused))') 532 else: 533 self.addDefine('UNUSED', ' ') 534 self.popLanguage() 535 536 def configureExpect(self): 537 '''Sees if the __builtin_expect directive is supported''' 538 self.pushLanguage(self.languages.clanguage) 539 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 540 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 541 self.popLanguage() 542 543 def configureFunctionName(self): 544 '''Sees if the compiler supports __func__ or a variant. Falls back 545 on __FUNCT__ which PETSc source defines, but most users do not, thus 546 stack traces through user code are better when the compiler's 547 variant is used.''' 548 def getFunctionName(lang): 549 name = '__FUNCT__' 550 self.pushLanguage(lang) 551 if self.checkLink('', "if (__func__[0] != 'm') return 1;"): 552 name = '__func__' 553 elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"): 554 name = '__FUNCTION__' 555 self.popLanguage() 556 return name 557 langs = [] 558 559 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 560 if hasattr(self.compilers, 'CXX'): 561 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 562 else: 563 self.addDefine('FUNCTION_NAME_CXX', '__FUNCT__') 564 565 def configureIntptrt(self): 566 '''Determine what to use for uintptr_t''' 567 def staticAssertSizeMatchesVoidStar(inc,typename): 568 # The declaration is an error if either array size is negative. 569 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 570 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 571 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 572 self.pushLanguage(self.languages.clanguage) 573 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 574 self.addDefine('UINTPTR_T', 'uintptr_t') 575 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 576 self.addDefine('UINTPTR_T', 'unsigned long long') 577 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 578 self.addDefine('UINTPTR_T', 'size_t') 579 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 580 self.addDefine('UINTPTR_T', 'unsigned long') 581 elif staticAssertSizeMatchesVoidStar('','unsigned'): 582 self.addDefine('UINTPTR_T', 'unsigned') 583 else: 584 raise RuntimeError('Could not find any unsigned integer type matching void*') 585 self.popLanguage() 586 587 def configureInline(self): 588 '''Get a generic inline keyword, depending on the language''' 589 if self.languages.clanguage == 'C': 590 self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword) 591 self.addDefine('RESTRICT', self.compilers.cRestrict) 592 elif self.languages.clanguage == 'Cxx': 593 self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword) 594 self.addDefine('RESTRICT', self.compilers.cxxRestrict) 595 596 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 597 self.addDefine('RTLD_DEFAULT','1') 598 return 599 600 def configureSolaris(self): 601 '''Solaris specific stuff''' 602 if os.path.isdir(os.path.join('/usr','ucblib')): 603 try: 604 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 605 except AttributeError: 606 flag = None 607 if flag is None: 608 self.compilers.LIBS += ' -L/usr/ucblib' 609 else: 610 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 611 return 612 613 def configureLinux(self): 614 '''Linux specific stuff''' 615 # TODO: Test for this by mallocing an odd number of floats and checking the address 616 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 617 return 618 619 def configureWin32(self): 620 '''Win32 non-cygwin specific stuff''' 621 kernel32=0 622 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 623 self.addDefine('HAVE_WINDOWS_H',1) 624 self.addDefine('HAVE_GETCOMPUTERNAME',1) 625 kernel32=1 626 elif self.libraries.add('kernel32','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 if kernel32: 631 if self.framework.argDB['with-windows-graphics']: 632 self.addDefine('USE_WINDOWS_GRAPHICS',1) 633 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 634 self.addDefine('HAVE_LOADLIBRARY',1) 635 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 636 self.addDefine('HAVE_GETPROCADDRESS',1) 637 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 638 self.addDefine('HAVE_FREELIBRARY',1) 639 if self.checkLink('#include <Windows.h>','GetLastError()'): 640 self.addDefine('HAVE_GETLASTERROR',1) 641 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 642 self.addDefine('HAVE_SETLASTERROR',1) 643 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 644 self.addDefine('USE_NT_TIME',1) 645 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 646 self.addDefine('HAVE_GET_USER_NAME',1) 647 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 648 self.addDefine('HAVE_GET_USER_NAME',1) 649 650 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 651 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 652 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 653 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 654 655 self.types.check('int32_t', 'int') 656 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 657 self.addTypedef('int', 'uid_t') 658 self.addTypedef('int', 'gid_t') 659 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 660 self.framework.addDefine('R_OK', '04') 661 self.framework.addDefine('W_OK', '02') 662 self.framework.addDefine('X_OK', '01') 663 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 664 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 665 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 666 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 667 self.addDefine('HAVE_LARGE_INTEGER_U',1) 668 669 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 670 if self.checkCompile('#include <Windows.h>\n', 'int flags = O_BINARY;'): 671 self.addDefine('HAVE_O_BINARY',1) 672 673 if self.compilers.CC.find('win32fe') >= 0: 674 self.addDefine('PATH_SEPARATOR','\';\'') 675 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 676 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 677 self.addDefine('CANNOT_START_DEBUGGER',1) 678 else: 679 self.addDefine('PATH_SEPARATOR','\':\'') 680 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 681 self.addDefine('DIR_SEPARATOR','\'/\'') 682 683 return 684 685#----------------------------------------------------------------------------------------------------- 686 def configureDefaultArch(self): 687 conffile = os.path.join('conf', 'petscvariables') 688 if self.framework.argDB['with-default-arch']: 689 fd = file(conffile, 'w') 690 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 691 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 692 fd.write('include ${PETSC_DIR}/${PETSC_ARCH}/conf/petscvariables\n') 693 fd.close() 694 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 695 elif os.path.isfile(conffile): 696 try: 697 os.unlink(conffile) 698 except: 699 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 700 return 701 702#----------------------------------------------------------------------------------------------------- 703 def configureScript(self): 704 '''Output a script in the conf directory which will reproduce the configuration''' 705 import nargs 706 import sys 707 scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py') 708 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 709 if 'configModules' in args: 710 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 711 del args['configModules'] 712 if 'optionsModule' in args: 713 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions': 714 del args['optionsModule'] 715 if not 'PETSC_ARCH' in args: 716 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 717 f = file(scriptName, 'w') 718 f.write('#!'+sys.executable+'\n') 719 f.write('if __name__ == \'__main__\':\n') 720 f.write(' import sys\n') 721 f.write(' import os\n') 722 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 723 f.write(' import configure\n') 724 # pretty print repr(args.values()) 725 f.write(' configure_options = [\n') 726 for itm in sorted(args.values()): 727 f.write(' \''+str(itm)+'\',\n') 728 f.write(' ]\n') 729 f.write(' configure.petsc_configure(configure_options)\n') 730 f.close() 731 try: 732 os.chmod(scriptName, 0775) 733 except OSError, e: 734 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 735 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 736 return 737 738 def configureInstall(self): 739 '''Setup the directories for installation''' 740 if self.framework.argDB['prefix']: 741 self.installdir = self.framework.argDB['prefix'] 742 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 743 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 744 '-@echo "========================================="']) 745 else: 746 self.installdir = os.path.join(self.petscdir.dir,self.arch.arch) 747 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 748 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 749 '-@echo "========================================="']) 750 return 751 752 def configureGCOV(self): 753 if self.framework.argDB['with-gcov']: 754 self.addDefine('USE_GCOV','1') 755 return 756 757 def configureFortranFlush(self): 758 if hasattr(self.compilers, 'FC'): 759 for baseName in ['flush','flush_']: 760 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 761 self.addDefine('HAVE_'+baseName.upper(), 1) 762 return 763 764 765 def configure(self): 766 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 767 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 768 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 769 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 770 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)): 771 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 772 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 773 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 774 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables') 775 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'conf','petscrules') 776 if self.libraries.math is None: 777 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 778 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 779 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 780 self.executeTest(self.configureInline) 781 self.executeTest(self.configurePrefetch) 782 self.executeTest(self.configureUnused) 783 self.executeTest(self.configureExpect); 784 self.executeTest(self.configureFunctionName); 785 self.executeTest(self.configureIntptrt); 786 self.executeTest(self.configureSolaris) 787 self.executeTest(self.configureLinux) 788 self.executeTest(self.configureWin32) 789 self.executeTest(self.configureDefaultArch) 790 self.executeTest(self.configureScript) 791 self.executeTest(self.configureInstall) 792 self.executeTest(self.configureGCOV) 793 self.executeTest(self.configureFortranFlush) 794 # dummy rules, always needed except for remote builds 795 self.addMakeRule('remote','') 796 self.addMakeRule('remoteclean','') 797 798 self.Dump() 799 self.dumpConfigInfo() 800 self.dumpMachineInfo() 801 self.dumpCMakeConfig() 802 self.dumpCMakeLists() 803 self.cmakeBoot() 804 self.framework.log.write('================================================================================\n') 805 self.logClear() 806 return 807